summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GeoIP-1.4.0/AUTHORS1
-rw-r--r--src/GeoIP-1.4.0/COPYING504
-rw-r--r--src/GeoIP-1.4.0/ChangeLog374
-rw-r--r--src/GeoIP-1.4.0/GeoIP-LICENSE.txt74
-rw-r--r--src/GeoIP-1.4.0/INSTALL182
-rw-r--r--src/GeoIP-1.4.0/Makefile.am10
-rw-r--r--src/GeoIP-1.4.0/NEWS0
-rw-r--r--src/GeoIP-1.4.0/README132
-rw-r--r--src/GeoIP-1.4.0/TODO54
-rw-r--r--src/GeoIP-1.4.0/data/GeoIP-LICENSE.txt76
-rw-r--r--src/GeoIP-1.4.0/data/GeoIP.datbin0 -> 1145452 bytes
-rw-r--r--src/GeoIP-1.4.0/data/Makefile.am7
-rw-r--r--src/GeoIP-1.4.0/data/README2
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/GeoIP.c994
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/GeoIP.h183
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/GeoIPCity.c244
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/GeoIPCity.h63
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/GeoIPUpdate.c850
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/GeoIPUpdate.h63
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/GeoIP_internal.h11
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/Makefile.am17
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/global.h32
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/md5.c332
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/md5.h40
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/regionName.c13311
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/timeZone.c551
-rw-r--r--src/GeoIP-1.4.0/libGeoIP/types.h140
-rw-r--r--src/Makefile.am96
-rw-r--r--src/arkollon/Makefile.am40
-rw-r--r--src/arkollon/data.cpp44
-rw-r--r--src/arkollon/data.h3065
-rw-r--r--src/arkollon/headerlistitem.cpp126
-rw-r--r--src/arkollon/headerlistitem.h39
-rw-r--r--src/arkollon/logdialog.ui91
-rw-r--r--src/arkollon/rcparser.cpp146
-rw-r--r--src/arkollon/rcparser.h50
-rw-r--r--src/arkollon/torkarkollon.118
-rw-r--r--src/arkollon/torkarkollon.cpp74
-rw-r--r--src/arkollon/uninstallwizard.cpp322
-rw-r--r--src/arkollon/uninstallwizard.h87
-rw-r--r--src/arkollon/wizard.cpp950
-rw-r--r--src/arkollon/wizard.h183
-rw-r--r--src/arkollon/wizardbase.ui921
-rw-r--r--src/arkollon/wizardbase.ui.h58
-rw-r--r--src/chart.cpp123
-rw-r--r--src/chart.h52
-rw-r--r--src/configdialog.cpp515
-rw-r--r--src/configdialog.h70
-rw-r--r--src/constants.h54
-rw-r--r--src/crashhandler.cpp293
-rw-r--r--src/crashhandler.h34
-rw-r--r--src/crypto.cpp816
-rw-r--r--src/crypto.h183
-rw-r--r--src/dcoptork.h49
-rw-r--r--src/dndlistview.cpp346
-rw-r--r--src/dndlistview.h84
-rw-r--r--src/eventsrc11
-rw-r--r--src/firewallsproxies.ui666
-rw-r--r--src/firewallsproxies.ui.h229
-rw-r--r--src/functions.cpp202
-rw-r--r--src/functions.h268
-rw-r--r--src/hiddensrvs.ui241
-rw-r--r--src/hiddensrvs.ui.h207
-rw-r--r--src/hidsrvwizard.ui484
-rw-r--r--src/hidsrvwizard.ui.h163
-rw-r--r--src/hitwidget.cpp208
-rw-r--r--src/hitwidget.h71
-rw-r--r--src/hitwidget_layout.ui343
-rw-r--r--src/hitwidget_layout.ui.h1
-rw-r--r--src/icons/FLAGS_LICENCE3
-rw-r--r--src/icons/Makefile.am5
-rwxr-xr-xsrc/icons/cr16-action-likeback_bug_tork.pngbin0 -> 703 bytes
-rw-r--r--src/icons/cr16-action-likeback_configure_tork.pngbin0 -> 192 bytes
-rw-r--r--src/icons/cr16-action-likeback_dislike_tork.pngbin0 -> 844 bytes
-rwxr-xr-xsrc/icons/cr16-action-likeback_feature_tork.pngbin0 -> 829 bytes
-rw-r--r--src/icons/cr16-action-likeback_like_tork.pngbin0 -> 894 bytes
-rw-r--r--src/icons/hi16-action-tork_torsmall.pngbin0 -> 494 bytes
-rw-r--r--src/icons/hi16-app-tork_19.pngbin0 -> 850 bytes
-rw-r--r--src/icons/hi16-app-tork_33.pngbin0 -> 899 bytes
-rw-r--r--src/icons/hi16-app-tork_FAILED.pngbin0 -> 2052 bytes
-rw-r--r--src/icons/hi16-app-tork_ad.pngbin0 -> 1503 bytes
-rw-r--r--src/icons/hi16-app-tork_ae.pngbin0 -> 1278 bytes
-rw-r--r--src/icons/hi16-app-tork_af.pngbin0 -> 1444 bytes
-rw-r--r--src/icons/hi16-app-tork_ag.pngbin0 -> 1651 bytes
-rw-r--r--src/icons/hi16-app-tork_ai.pngbin0 -> 1675 bytes
-rw-r--r--src/icons/hi16-app-tork_aim_protocol.pngbin0 -> 1267 bytes
-rw-r--r--src/icons/hi16-app-tork_al.pngbin0 -> 1577 bytes
-rw-r--r--src/icons/hi16-app-tork_am.pngbin0 -> 1461 bytes
-rw-r--r--src/icons/hi16-app-tork_an.pngbin0 -> 1540 bytes
-rw-r--r--src/icons/hi16-app-tork_ao.pngbin0 -> 1603 bytes
-rw-r--r--src/icons/hi16-app-tork_aq.pngbin0 -> 1606 bytes
-rw-r--r--src/icons/hi16-app-tork_ar.pngbin0 -> 1532 bytes
-rw-r--r--src/icons/hi16-app-tork_as.pngbin0 -> 1603 bytes
-rw-r--r--src/icons/hi16-app-tork_at.pngbin0 -> 1307 bytes
-rw-r--r--src/icons/hi16-app-tork_au.pngbin0 -> 1582 bytes
-rw-r--r--src/icons/hi16-app-tork_aw.pngbin0 -> 1522 bytes
-rw-r--r--src/icons/hi16-app-tork_ax.pngbin0 -> 1606 bytes
-rw-r--r--src/icons/hi16-app-tork_az.pngbin0 -> 1616 bytes
-rw-r--r--src/icons/hi16-app-tork_ba.pngbin0 -> 1520 bytes
-rw-r--r--src/icons/hi16-app-tork_bb.pngbin0 -> 1593 bytes
-rw-r--r--src/icons/hi16-app-tork_bd.pngbin0 -> 1624 bytes
-rw-r--r--src/icons/hi16-app-tork_be.pngbin0 -> 1276 bytes
-rw-r--r--src/icons/hi16-app-tork_bf.pngbin0 -> 1300 bytes
-rw-r--r--src/icons/hi16-app-tork_bg.pngbin0 -> 1278 bytes
-rw-r--r--src/icons/hi16-app-tork_bh.pngbin0 -> 1436 bytes
-rw-r--r--src/icons/hi16-app-tork_bi.pngbin0 -> 1659 bytes
-rw-r--r--src/icons/hi16-app-tork_bj.pngbin0 -> 1394 bytes
-rw-r--r--src/icons/hi16-app-tork_bm.pngbin0 -> 1482 bytes
-rw-r--r--src/icons/hi16-app-tork_bn.pngbin0 -> 1624 bytes
-rw-r--r--src/icons/hi16-app-tork_bo.pngbin0 -> 1423 bytes
-rw-r--r--src/icons/hi16-app-tork_br.pngbin0 -> 1547 bytes
-rw-r--r--src/icons/hi16-app-tork_bs.pngbin0 -> 1428 bytes
-rw-r--r--src/icons/hi16-app-tork_bt.pngbin0 -> 1668 bytes
-rw-r--r--src/icons/hi16-app-tork_bv.pngbin0 -> 1632 bytes
-rw-r--r--src/icons/hi16-app-tork_bw.pngbin0 -> 1472 bytes
-rw-r--r--src/icons/hi16-app-tork_by.pngbin0 -> 1298 bytes
-rw-r--r--src/icons/hi16-app-tork_bz.pngbin0 -> 1584 bytes
-rw-r--r--src/icons/hi16-app-tork_ca.pngbin0 -> 1562 bytes
-rw-r--r--src/icons/hi16-app-tork_cc.pngbin0 -> 1616 bytes
-rw-r--r--src/icons/hi16-app-tork_cd.pngbin0 -> 1620 bytes
-rw-r--r--src/icons/hi16-app-tork_cf.pngbin0 -> 1530 bytes
-rw-r--r--src/icons/hi16-app-tork_cg.pngbin0 -> 1398 bytes
-rw-r--r--src/icons/hi16-app-tork_ch.pngbin0 -> 1295 bytes
-rw-r--r--src/icons/hi16-app-tork_ci.pngbin0 -> 1499 bytes
-rw-r--r--src/icons/hi16-app-tork_ck.pngbin0 -> 1506 bytes
-rw-r--r--src/icons/hi16-app-tork_cl.pngbin0 -> 1390 bytes
-rw-r--r--src/icons/hi16-app-tork_cm.pngbin0 -> 1373 bytes
-rw-r--r--src/icons/hi16-app-tork_cn.pngbin0 -> 1243 bytes
-rw-r--r--src/icons/hi16-app-tork_co.pngbin0 -> 1234 bytes
-rw-r--r--src/icons/hi16-app-tork_cr.pngbin0 -> 1455 bytes
-rw-r--r--src/icons/hi16-app-tork_cs.pngbin0 -> 1372 bytes
-rw-r--r--src/icons/hi16-app-tork_cu.pngbin0 -> 1591 bytes
-rw-r--r--src/icons/hi16-app-tork_cv.pngbin0 -> 1537 bytes
-rw-r--r--src/icons/hi16-app-tork_cx.pngbin0 -> 1535 bytes
-rw-r--r--src/icons/hi16-app-tork_cy.pngbin0 -> 1593 bytes
-rw-r--r--src/icons/hi16-app-tork_cz.pngbin0 -> 1463 bytes
-rw-r--r--src/icons/hi16-app-tork_de.pngbin0 -> 1293 bytes
-rw-r--r--src/icons/hi16-app-tork_dj.pngbin0 -> 1463 bytes
-rw-r--r--src/icons/hi16-app-tork_dk.pngbin0 -> 1422 bytes
-rw-r--r--src/icons/hi16-app-tork_dm.pngbin0 -> 1592 bytes
-rw-r--r--src/icons/hi16-app-tork_do.pngbin0 -> 1581 bytes
-rw-r--r--src/icons/hi16-app-tork_dz.pngbin0 -> 1665 bytes
-rw-r--r--src/icons/hi16-app-tork_ec.pngbin0 -> 1444 bytes
-rw-r--r--src/icons/hi16-app-tork_ee.pngbin0 -> 1246 bytes
-rw-r--r--src/icons/hi16-app-tork_eg.pngbin0 -> 1344 bytes
-rw-r--r--src/icons/hi16-app-tork_eh.pngbin0 -> 1486 bytes
-rw-r--r--src/icons/hi16-app-tork_er.pngbin0 -> 1499 bytes
-rw-r--r--src/icons/hi16-app-tork_es.pngbin0 -> 1420 bytes
-rw-r--r--src/icons/hi16-app-tork_et.pngbin0 -> 1632 bytes
-rw-r--r--src/icons/hi16-app-tork_eu.pngbin0 -> 1133 bytes
-rw-r--r--src/icons/hi16-app-tork_fi.pngbin0 -> 1558 bytes
-rw-r--r--src/icons/hi16-app-tork_fj.pngbin0 -> 1667 bytes
-rw-r--r--src/icons/hi16-app-tork_fk.pngbin0 -> 1597 bytes
-rw-r--r--src/icons/hi16-app-tork_fm.pngbin0 -> 1584 bytes
-rw-r--r--src/icons/hi16-app-tork_fo.pngbin0 -> 1637 bytes
-rw-r--r--src/icons/hi16-app-tork_fr.pngbin0 -> 1491 bytes
-rw-r--r--src/icons/hi16-app-tork_ga.pngbin0 -> 1335 bytes
-rw-r--r--src/icons/hi16-app-tork_gadu_protocol.pngbin0 -> 1514 bytes
-rw-r--r--src/icons/hi16-app-tork_gb.pngbin0 -> 1748 bytes
-rw-r--r--src/icons/hi16-app-tork_gd.pngbin0 -> 1481 bytes
-rw-r--r--src/icons/hi16-app-tork_ge.pngbin0 -> 1527 bytes
-rw-r--r--src/icons/hi16-app-tork_gf.pngbin0 -> 1491 bytes
-rw-r--r--src/icons/hi16-app-tork_gg.pngbin0 -> 1523 bytes
-rw-r--r--src/icons/hi16-app-tork_gh.pngbin0 -> 1328 bytes
-rw-r--r--src/icons/hi16-app-tork_gi.pngbin0 -> 1535 bytes
-rw-r--r--src/icons/hi16-app-tork_gl.pngbin0 -> 1566 bytes
-rw-r--r--src/icons/hi16-app-tork_gm.pngbin0 -> 1438 bytes
-rw-r--r--src/icons/hi16-app-tork_gn.pngbin0 -> 1594 bytes
-rw-r--r--src/icons/hi16-app-tork_gp.pngbin0 -> 1491 bytes
-rw-r--r--src/icons/hi16-app-tork_gq.pngbin0 -> 1494 bytes
-rw-r--r--src/icons/hi16-app-tork_gr.pngbin0 -> 1563 bytes
-rw-r--r--src/icons/hi16-app-tork_groupwise_protocol.pngbin0 -> 828 bytes
-rw-r--r--src/icons/hi16-app-tork_gs.pngbin0 -> 1585 bytes
-rw-r--r--src/icons/hi16-app-tork_gt.pngbin0 -> 1648 bytes
-rw-r--r--src/icons/hi16-app-tork_gu.pngbin0 -> 1607 bytes
-rw-r--r--src/icons/hi16-app-tork_gw.pngbin0 -> 1284 bytes
-rw-r--r--src/icons/hi16-app-tork_gy.pngbin0 -> 1653 bytes
-rw-r--r--src/icons/hi16-app-tork_hk.pngbin0 -> 1375 bytes
-rw-r--r--src/icons/hi16-app-tork_hm.pngbin0 -> 1499 bytes
-rw-r--r--src/icons/hi16-app-tork_hn.pngbin0 -> 1568 bytes
-rw-r--r--src/icons/hi16-app-tork_hr.pngbin0 -> 1607 bytes
-rw-r--r--src/icons/hi16-app-tork_ht.pngbin0 -> 1537 bytes
-rw-r--r--src/icons/hi16-app-tork_hu.pngbin0 -> 1357 bytes
-rw-r--r--src/icons/hi16-app-tork_icq_protocol.pngbin0 -> 1841 bytes
-rw-r--r--src/icons/hi16-app-tork_id.pngbin0 -> 1333 bytes
-rw-r--r--src/icons/hi16-app-tork_ie.pngbin0 -> 1486 bytes
-rw-r--r--src/icons/hi16-app-tork_il.pngbin0 -> 1594 bytes
-rw-r--r--src/icons/hi16-app-tork_in.pngbin0 -> 1545 bytes
-rw-r--r--src/icons/hi16-app-tork_io.pngbin0 -> 1732 bytes
-rw-r--r--src/icons/hi16-app-tork_iq.pngbin0 -> 1397 bytes
-rw-r--r--src/icons/hi16-app-tork_ir.pngbin0 -> 1545 bytes
-rw-r--r--src/icons/hi16-app-tork_irc_protocol.pngbin0 -> 1432 bytes
-rw-r--r--src/icons/hi16-app-tork_is.pngbin0 -> 1633 bytes
-rw-r--r--src/icons/hi16-app-tork_it.pngbin0 -> 1354 bytes
-rw-r--r--src/icons/hi16-app-tork_jabber_protocol.pngbin0 -> 1466 bytes
-rw-r--r--src/icons/hi16-app-tork_je.pngbin0 -> 1649 bytes
-rw-r--r--src/icons/hi16-app-tork_jm.pngbin0 -> 1363 bytes
-rw-r--r--src/icons/hi16-app-tork_jo.pngbin0 -> 1466 bytes
-rw-r--r--src/icons/hi16-app-tork_jp.pngbin0 -> 1505 bytes
-rw-r--r--src/icons/hi16-app-tork_ke.pngbin0 -> 1563 bytes
-rw-r--r--src/icons/hi16-app-tork_kg.pngbin0 -> 1348 bytes
-rw-r--r--src/icons/hi16-app-tork_kh.pngbin0 -> 1499 bytes
-rw-r--r--src/icons/hi16-app-tork_ki.pngbin0 -> 1638 bytes
-rw-r--r--src/icons/hi16-app-tork_km.pngbin0 -> 1500 bytes
-rw-r--r--src/icons/hi16-app-tork_kn.pngbin0 -> 1507 bytes
-rw-r--r--src/icons/hi16-app-tork_konqueroroff.pngbin0 -> 2078 bytes
-rw-r--r--src/icons/hi16-app-tork_konqueroron.pngbin0 -> 2114 bytes
-rw-r--r--src/icons/hi16-app-tork_kp.pngbin0 -> 1463 bytes
-rw-r--r--src/icons/hi16-app-tork_kr.pngbin0 -> 1668 bytes
-rw-r--r--src/icons/hi16-app-tork_kw.pngbin0 -> 1330 bytes
-rw-r--r--src/icons/hi16-app-tork_ky.pngbin0 -> 1585 bytes
-rw-r--r--src/icons/hi16-app-tork_kz.pngbin0 -> 1616 bytes
-rw-r--r--src/icons/hi16-app-tork_la.pngbin0 -> 1474 bytes
-rw-r--r--src/icons/hi16-app-tork_lb.pngbin0 -> 1517 bytes
-rw-r--r--src/icons/hi16-app-tork_lc.pngbin0 -> 1541 bytes
-rw-r--r--src/icons/hi16-app-tork_li.pngbin0 -> 1325 bytes
-rw-r--r--src/icons/hi16-app-tork_lk.pngbin0 -> 1598 bytes
-rw-r--r--src/icons/hi16-app-tork_lr.pngbin0 -> 1587 bytes
-rw-r--r--src/icons/hi16-app-tork_ls.pngbin0 -> 1501 bytes
-rw-r--r--src/icons/hi16-app-tork_lt.pngbin0 -> 1195 bytes
-rw-r--r--src/icons/hi16-app-tork_lu.pngbin0 -> 1457 bytes
-rw-r--r--src/icons/hi16-app-tork_lv.pngbin0 -> 1521 bytes
-rw-r--r--src/icons/hi16-app-tork_ly.pngbin0 -> 1497 bytes
-rw-r--r--src/icons/hi16-app-tork_ma.pngbin0 -> 1328 bytes
-rw-r--r--src/icons/hi16-app-tork_mc.pngbin0 -> 1408 bytes
-rw-r--r--src/icons/hi16-app-tork_md.pngbin0 -> 1538 bytes
-rw-r--r--src/icons/hi16-app-tork_me.pngbin0 -> 1569 bytes
-rw-r--r--src/icons/hi16-app-tork_mg.pngbin0 -> 1384 bytes
-rw-r--r--src/icons/hi16-app-tork_mh.pngbin0 -> 1622 bytes
-rw-r--r--src/icons/hi16-app-tork_mk.pngbin0 -> 1532 bytes
-rw-r--r--src/icons/hi16-app-tork_ml.pngbin0 -> 1331 bytes
-rw-r--r--src/icons/hi16-app-tork_mm.pngbin0 -> 1377 bytes
-rw-r--r--src/icons/hi16-app-tork_mn.pngbin0 -> 1515 bytes
-rw-r--r--src/icons/hi16-app-tork_mo.pngbin0 -> 1456 bytes
-rw-r--r--src/icons/hi16-app-tork_mp.pngbin0 -> 1613 bytes
-rw-r--r--src/icons/hi16-app-tork_mq.pngbin0 -> 1491 bytes
-rw-r--r--src/icons/hi16-app-tork_mr.pngbin0 -> 1329 bytes
-rw-r--r--src/icons/hi16-app-tork_ms.pngbin0 -> 1584 bytes
-rw-r--r--src/icons/hi16-app-tork_msn_protocol.pngbin0 -> 1674 bytes
-rw-r--r--src/icons/hi16-app-tork_mt.pngbin0 -> 1489 bytes
-rw-r--r--src/icons/hi16-app-tork_mu.pngbin0 -> 1253 bytes
-rw-r--r--src/icons/hi16-app-tork_mv.pngbin0 -> 1551 bytes
-rw-r--r--src/icons/hi16-app-tork_mw.pngbin0 -> 1265 bytes
-rw-r--r--src/icons/hi16-app-tork_mx.pngbin0 -> 1473 bytes
-rw-r--r--src/icons/hi16-app-tork_my.pngbin0 -> 1634 bytes
-rw-r--r--src/icons/hi16-app-tork_mz.pngbin0 -> 1469 bytes
-rw-r--r--src/icons/hi16-app-tork_na.pngbin0 -> 1637 bytes
-rw-r--r--src/icons/hi16-app-tork_nc.pngbin0 -> 1491 bytes
-rw-r--r--src/icons/hi16-app-tork_ne.pngbin0 -> 1571 bytes
-rw-r--r--src/icons/hi16-app-tork_nf.pngbin0 -> 1578 bytes
-rw-r--r--src/icons/hi16-app-tork_ng.pngbin0 -> 1610 bytes
-rw-r--r--src/icons/hi16-app-tork_ni.pngbin0 -> 1530 bytes
-rw-r--r--src/icons/hi16-app-tork_nl.pngbin0 -> 1395 bytes
-rw-r--r--src/icons/hi16-app-tork_no.pngbin0 -> 1632 bytes
-rw-r--r--src/icons/hi16-app-tork_np.pngbin0 -> 1111 bytes
-rw-r--r--src/icons/hi16-app-tork_nr.pngbin0 -> 1497 bytes
-rw-r--r--src/icons/hi16-app-tork_nu.pngbin0 -> 1516 bytes
-rw-r--r--src/icons/hi16-app-tork_nz.pngbin0 -> 1591 bytes
-rw-r--r--src/icons/hi16-app-tork_om.pngbin0 -> 1324 bytes
-rw-r--r--src/icons/hi16-app-tork_pa.pngbin0 -> 1570 bytes
-rw-r--r--src/icons/hi16-app-tork_pe.pngbin0 -> 1480 bytes
-rw-r--r--src/icons/hi16-app-tork_pf.pngbin0 -> 1516 bytes
-rw-r--r--src/icons/hi16-app-tork_pg.pngbin0 -> 1409 bytes
-rw-r--r--src/icons/hi16-app-tork_ph.pngbin0 -> 1494 bytes
-rw-r--r--src/icons/hi16-app-tork_pk.pngbin0 -> 1609 bytes
-rw-r--r--src/icons/hi16-app-tork_pl.pngbin0 -> 1205 bytes
-rw-r--r--src/icons/hi16-app-tork_pm.pngbin0 -> 1491 bytes
-rw-r--r--src/icons/hi16-app-tork_pn.pngbin0 -> 1649 bytes
-rw-r--r--src/icons/hi16-app-tork_pr.pngbin0 -> 1579 bytes
-rw-r--r--src/icons/hi16-app-tork_ps.pngbin0 -> 1370 bytes
-rw-r--r--src/icons/hi16-app-tork_pt.pngbin0 -> 1414 bytes
-rw-r--r--src/icons/hi16-app-tork_pw.pngbin0 -> 1540 bytes
-rw-r--r--src/icons/hi16-app-tork_py.pngbin0 -> 1497 bytes
-rw-r--r--src/icons/hi16-app-tork_qa.pngbin0 -> 1568 bytes
-rw-r--r--src/icons/hi16-app-tork_re.pngbin0 -> 1491 bytes
-rw-r--r--src/icons/hi16-app-tork_ro.pngbin0 -> 1595 bytes
-rw-r--r--src/icons/hi16-app-tork_rs.pngbin0 -> 1591 bytes
-rw-r--r--src/icons/hi16-app-tork_rs.woa.pngbin0 -> 1307 bytes
-rw-r--r--src/icons/hi16-app-tork_ru.pngbin0 -> 1231 bytes
-rw-r--r--src/icons/hi16-app-tork_rw.pngbin0 -> 1356 bytes
-rw-r--r--src/icons/hi16-app-tork_sa.pngbin0 -> 1602 bytes
-rw-r--r--src/icons/hi16-app-tork_sb.pngbin0 -> 1558 bytes
-rw-r--r--src/icons/hi16-app-tork_sc.pngbin0 -> 1595 bytes
-rw-r--r--src/icons/hi16-app-tork_sd.pngbin0 -> 1381 bytes
-rw-r--r--src/icons/hi16-app-tork_se.pngbin0 -> 1470 bytes
-rw-r--r--src/icons/hi16-app-tork_sg.pngbin0 -> 1531 bytes
-rw-r--r--src/icons/hi16-app-tork_sh.pngbin0 -> 1570 bytes
-rw-r--r--src/icons/hi16-app-tork_si.pngbin0 -> 1382 bytes
-rw-r--r--src/icons/hi16-app-tork_sj.pngbin0 -> 1632 bytes
-rw-r--r--src/icons/hi16-app-tork_sk.pngbin0 -> 1469 bytes
-rw-r--r--src/icons/hi16-app-tork_sl.pngbin0 -> 1394 bytes
-rw-r--r--src/icons/hi16-app-tork_sm.pngbin0 -> 1562 bytes
-rw-r--r--src/icons/hi16-app-tork_sms_protocol.pngbin0 -> 1714 bytes
-rw-r--r--src/icons/hi16-app-tork_sn.pngbin0 -> 1347 bytes
-rw-r--r--src/icons/hi16-app-tork_so.pngbin0 -> 1610 bytes
-rw-r--r--src/icons/hi16-app-tork_sr.pngbin0 -> 1431 bytes
-rw-r--r--src/icons/hi16-app-tork_st.pngbin0 -> 1376 bytes
-rw-r--r--src/icons/hi16-app-tork_sv.pngbin0 -> 1552 bytes
-rw-r--r--src/icons/hi16-app-tork_sy.pngbin0 -> 1365 bytes
-rw-r--r--src/icons/hi16-app-tork_sz.pngbin0 -> 1686 bytes
-rw-r--r--src/icons/hi16-app-tork_tc.pngbin0 -> 1601 bytes
-rw-r--r--src/icons/hi16-app-tork_td.pngbin0 -> 1595 bytes
-rw-r--r--src/icons/hi16-app-tork_testbed_protocol.pngbin0 -> 1805 bytes
-rw-r--r--src/icons/hi16-app-tork_tf.pngbin0 -> 1523 bytes
-rw-r--r--src/icons/hi16-app-tork_tg.pngbin0 -> 1438 bytes
-rw-r--r--src/icons/hi16-app-tork_th.pngbin0 -> 1320 bytes
-rw-r--r--src/icons/hi16-app-tork_tj.pngbin0 -> 1531 bytes
-rw-r--r--src/icons/hi16-app-tork_tk.pngbin0 -> 1591 bytes
-rw-r--r--src/icons/hi16-app-tork_tl.pngbin0 -> 1484 bytes
-rw-r--r--src/icons/hi16-app-tork_tm.pngbin0 -> 1402 bytes
-rw-r--r--src/icons/hi16-app-tork_tn.pngbin0 -> 1497 bytes
-rw-r--r--src/icons/hi16-app-tork_to.pngbin0 -> 1377 bytes
-rw-r--r--src/icons/hi16-app-tork_tp.pngbin0 -> 1629 bytes
-rw-r--r--src/icons/hi16-app-tork_tr.pngbin0 -> 1412 bytes
-rw-r--r--src/icons/hi16-app-tork_tt.pngbin0 -> 1588 bytes
-rw-r--r--src/icons/hi16-app-tork_tv.pngbin0 -> 1704 bytes
-rw-r--r--src/icons/hi16-app-tork_tw.pngbin0 -> 1351 bytes
-rw-r--r--src/icons/hi16-app-tork_tz.pngbin0 -> 1537 bytes
-rw-r--r--src/icons/hi16-app-tork_ua.pngbin0 -> 1366 bytes
-rw-r--r--src/icons/hi16-app-tork_ug.pngbin0 -> 1385 bytes
-rw-r--r--src/icons/hi16-app-tork_um.pngbin0 -> 1596 bytes
-rw-r--r--src/icons/hi16-app-tork_us.pngbin0 -> 1596 bytes
-rw-r--r--src/icons/hi16-app-tork_uy.pngbin0 -> 1596 bytes
-rw-r--r--src/icons/hi16-app-tork_uz.pngbin0 -> 1563 bytes
-rw-r--r--src/icons/hi16-app-tork_va.pngbin0 -> 1585 bytes
-rw-r--r--src/icons/hi16-app-tork_vc.pngbin0 -> 1453 bytes
-rw-r--r--src/icons/hi16-app-tork_ve.pngbin0 -> 1413 bytes
-rw-r--r--src/icons/hi16-app-tork_vg.pngbin0 -> 1610 bytes
-rw-r--r--src/icons/hi16-app-tork_vi.pngbin0 -> 1715 bytes
-rw-r--r--src/icons/hi16-app-tork_vn.pngbin0 -> 1296 bytes
-rw-r--r--src/icons/hi16-app-tork_vu.pngbin0 -> 1400 bytes
-rw-r--r--src/icons/hi16-app-tork_wf.pngbin0 -> 1491 bytes
-rw-r--r--src/icons/hi16-app-tork_ws.pngbin0 -> 1349 bytes
-rw-r--r--src/icons/hi16-app-tork_yahoo_protocol.pngbin0 -> 1717 bytes
-rw-r--r--src/icons/hi16-app-tork_ye.pngbin0 -> 1230 bytes
-rw-r--r--src/icons/hi16-app-tork_yt.pngbin0 -> 1491 bytes
-rw-r--r--src/icons/hi16-app-tork_yu.pngbin0 -> 1372 bytes
-rw-r--r--src/icons/hi16-app-tork_za.pngbin0 -> 1557 bytes
-rw-r--r--src/icons/hi16-app-tork_zm.pngbin0 -> 1472 bytes
-rw-r--r--src/icons/hi16-app-tork_zw.pngbin0 -> 1570 bytes
-rw-r--r--src/icons/hi22-action-tokr_green.pngbin0 -> 1353 bytes
-rw-r--r--src/icons/hi22-action-tork.pngbin0 -> 3596 bytes
-rw-r--r--src/icons/hi22-action-tork_green.pngbin0 -> 3974 bytes
-rw-r--r--src/icons/hi22-action-tork_green_exit.pngbin0 -> 3854 bytes
-rw-r--r--src/icons/hi22-action-tork_guard_detached.pngbin0 -> 3179 bytes
-rw-r--r--src/icons/hi22-action-tork_guard_down.pngbin0 -> 1330 bytes
-rw-r--r--src/icons/hi22-action-tork_guard_little.pngbin0 -> 3651 bytes
-rw-r--r--src/icons/hi22-action-tork_guard_red.pngbin0 -> 3222 bytes
-rw-r--r--src/icons/hi22-action-tork_guard_unlisted.pngbin0 -> 916 bytes
-rw-r--r--src/icons/hi22-action-tork_guard_unusable.pngbin0 -> 939 bytes
-rw-r--r--src/icons/hi22-action-tork_guard_up.pngbin0 -> 3604 bytes
-rw-r--r--src/icons/hi22-action-tork_konqueror_https.pngbin0 -> 4124 bytes
-rw-r--r--src/icons/hi22-action-tork_konsole_https.pngbin0 -> 3942 bytes
-rw-r--r--src/icons/hi22-action-tork_little.pngbin0 -> 607 bytes
-rw-r--r--src/icons/hi22-action-tork_little_exit.pngbin0 -> 3248 bytes
-rw-r--r--src/icons/hi22-action-tork_none.pngbin0 -> 916 bytes
-rw-r--r--src/icons/hi22-action-tork_orange.pngbin0 -> 837 bytes
-rw-r--r--src/icons/hi22-action-tork_orange_exit.pngbin0 -> 3459 bytes
-rw-r--r--src/icons/hi22-action-tork_play.pngbin0 -> 1371 bytes
-rw-r--r--src/icons/hi22-action-tork_red.pngbin0 -> 1330 bytes
-rw-r--r--src/icons/hi22-action-tork_red_exit.pngbin0 -> 3902 bytes
-rw-r--r--src/icons/hi22-action-tork_server.pngbin0 -> 3417 bytes
-rw-r--r--src/icons/hi22-action-tork_stop.pngbin0 -> 1317 bytes
-rw-r--r--src/icons/hi22-action-tork_tor.pngbin0 -> 3912 bytes
-rw-r--r--src/icons/hi22-action-tork_torsmall.pngbin0 -> 967 bytes
-rw-r--r--src/icons/hi22-action-tork_uncensor.pngbin0 -> 1014 bytes
-rw-r--r--src/icons/hi22-action-tork_yellow.pngbin0 -> 1081 bytes
-rw-r--r--src/icons/hi22-action-tork_yellow_exit.pngbin0 -> 3625 bytes
-rw-r--r--src/icons/hi32-action-tork.pngbin0 -> 4355 bytes
-rw-r--r--src/icons/hi32-action-tork_Apply_Settings.pngbin0 -> 4371 bytes
-rw-r--r--src/icons/hi32-action-tork_DNS_Leak_Warnings.pngbin0 -> 1219 bytes
-rw-r--r--src/icons/hi32-action-tork_Usage_Warnings.pngbin0 -> 4371 bytes
-rw-r--r--src/icons/hi32-action-tork_green.pngbin0 -> 2050 bytes
-rw-r--r--src/icons/hi32-action-tork_none.pngbin0 -> 1288 bytes
-rw-r--r--src/icons/hi32-action-tork_orange.pngbin0 -> 1219 bytes
-rw-r--r--src/icons/hi32-action-tork_red.pngbin0 -> 841 bytes
-rw-r--r--src/icons/hi32-action-tork_yellow.pngbin0 -> 4370 bytes
-rw-r--r--src/icons/hi32-app-tork_FAILED.pngbin0 -> 2127 bytes
-rw-r--r--src/icons/hi32-app-tork_General_Warnings.pngbin0 -> 2127 bytes
-rw-r--r--src/icons/hi32-app-tork_Security_Warnings.pngbin0 -> 2127 bytes
-rw-r--r--src/icons/hi32-app-tork_TorK_Feedback.pngbin0 -> 2127 bytes
-rw-r--r--src/icons/hi32-app-tork_green.pngbin0 -> 2050 bytes
-rw-r--r--src/icons/hi48-app-tork.pngbin0 -> 5378 bytes
-rw-r--r--src/icons/hi48-app-tork_FAILED.pngbin0 -> 3136 bytes
-rw-r--r--src/icons/hi48-app-tork_a1.pngbin0 -> 3260 bytes
-rw-r--r--src/icons/hi48-app-tork_a2.pngbin0 -> 3882 bytes
-rw-r--r--src/icons/hi48-app-tork_agent.pngbin0 -> 3260 bytes
-rw-r--r--src/icons/hi48-app-tork_alert.pngbin0 -> 5355 bytes
-rw-r--r--src/icons/hi48-app-tork_firefox.pngbin0 -> 4723 bytes
-rw-r--r--src/icons/hi48-app-tork_green.pngbin0 -> 3363 bytes
-rw-r--r--src/icons/hi48-app-tork_help.pngbin0 -> 5366 bytes
-rw-r--r--src/icons/hi48-app-tork_identity.pngbin0 -> 3404 bytes
-rw-r--r--src/icons/hi48-app-tork_info.pngbin0 -> 5256 bytes
-rw-r--r--src/icons/hi48-app-tork_internet.pngbin0 -> 4773 bytes
-rw-r--r--src/icons/hi48-app-tork_kgpg.pngbin0 -> 3477 bytes
-rw-r--r--src/icons/hi48-app-tork_konqueror_play.pngbin0 -> 6661 bytes
-rw-r--r--src/icons/hi48-app-tork_konqueror_stop.pngbin0 -> 7135 bytes
-rw-r--r--src/icons/hi48-app-tork_konsole.pngbin0 -> 2440 bytes
-rw-r--r--src/icons/hi48-app-tork_konsolessh.pngbin0 -> 5430 bytes
-rw-r--r--src/icons/hi48-app-tork_mail.pngbin0 -> 3427 bytes
-rw-r--r--src/icons/hi48-app-tork_opera.pngbin0 -> 6176 bytes
-rw-r--r--src/icons/hi48-app-tork_penguin.pngbin0 -> 4083 bytes
-rw-r--r--src/icons/hi48-app-tork_play.pngbin0 -> 5035 bytes
-rw-r--r--src/icons/hi48-app-tork_pressplay.pngbin0 -> 5035 bytes
-rw-r--r--src/icons/hi48-app-tork_privoxy.pngbin0 -> 5447 bytes
-rw-r--r--src/icons/hi48-app-tork_remotetor.pngbin0 -> 5407 bytes
-rw-r--r--src/icons/hi48-app-tork_stop.pngbin0 -> 6208 bytes
-rw-r--r--src/icons/hi48-app-tork_torserver.pngbin0 -> 5346 bytes
-rw-r--r--src/introwizard.ui1858
-rw-r--r--src/introwizard.ui.h25
-rw-r--r--src/kerrylabel.cpp109
-rw-r--r--src/kerrylabel.h57
-rw-r--r--src/konqplugin/Makefile.am14
-rw-r--r--src/konqplugin/hi22-app-tork_konqueroroff.pngbin0 -> 3889 bytes
-rw-r--r--src/konqplugin/hi22-app-tork_konqueroron.pngbin0 -> 3764 bytes
-rw-r--r--src/konqplugin/hi48-app-tork_firefox.pngbin0 -> 4723 bytes
-rw-r--r--src/konqplugin/hi48-app-tork_opera.pngbin0 -> 6176 bytes
-rw-r--r--src/konqplugin/tork_plug_in.cpp197
-rw-r--r--src/konqplugin/tork_plug_in.desktop15
-rw-r--r--src/konqplugin/tork_plug_in.h81
-rw-r--r--src/konqplugin/tork_plug_in.rc11
-rw-r--r--src/konqueror.ui440
-rw-r--r--src/konqueror.ui.h51
-rw-r--r--src/kwidgetlistbox.cpp223
-rw-r--r--src/kwidgetlistbox.h65
-rw-r--r--src/likeback.cpp854
-rw-r--r--src/likeback.h364
-rw-r--r--src/likeback_private.h105
-rw-r--r--src/main.cpp120
-rw-r--r--src/maxmin.ui460
-rw-r--r--src/maxmin.ui.h123
-rw-r--r--src/menu/Makefile.am2
-rw-r--r--src/menu/tork.in4
-rw-r--r--src/mixminion.ui190
-rw-r--r--src/mixminion.ui.h126
-rw-r--r--src/newfirstrunwizard.ui2551
-rw-r--r--src/newfirstrunwizard.ui.h770
-rw-r--r--src/newstreamosd.cpp537
-rw-r--r--src/newstreamosd.h117
-rw-r--r--src/overlayWidget.cpp90
-rw-r--r--src/overlayWidget.h48
-rw-r--r--src/paranoia.ui312
-rw-r--r--src/paranoia.ui.h209
-rw-r--r--src/popupMessage.cpp430
-rw-r--r--src/popupMessage.h123
-rw-r--r--src/portsandicons.h72
-rw-r--r--src/portsandnames.h44
-rw-r--r--src/privoxytemplates/Makefile.am34
-rw-r--r--src/privoxytemplates/blocked270
-rw-r--r--src/privoxytemplates/cgi-error-404154
-rw-r--r--src/privoxytemplates/cgi-error-bad-param161
-rw-r--r--src/privoxytemplates/cgi-error-disabled148
-rw-r--r--src/privoxytemplates/cgi-error-file138
-rw-r--r--src/privoxytemplates/cgi-error-modified162
-rw-r--r--src/privoxytemplates/cgi-error-parse175
-rw-r--r--src/privoxytemplates/cgi-style.css69
-rw-r--r--src/privoxytemplates/connect-failed159
-rw-r--r--src/privoxytemplates/default136
-rw-r--r--src/privoxytemplates/edit-actions-add-url-form205
-rw-r--r--src/privoxytemplates/edit-actions-for-url863
-rw-r--r--src/privoxytemplates/edit-actions-for-url-filter6
-rw-r--r--src/privoxytemplates/edit-actions-list294
-rw-r--r--src/privoxytemplates/edit-actions-list-section111
-rw-r--r--src/privoxytemplates/edit-actions-list-url79
-rw-r--r--src/privoxytemplates/edit-actions-remove-url-form189
-rw-r--r--src/privoxytemplates/edit-actions-url-form207
-rw-r--r--src/privoxytemplates/mod-local-help12
-rw-r--r--src/privoxytemplates/mod-support-and-service24
-rw-r--r--src/privoxytemplates/mod-title4
-rw-r--r--src/privoxytemplates/mod-unstable-warning6
-rw-r--r--src/privoxytemplates/no-such-domain160
-rw-r--r--src/privoxytemplates/show-request158
-rw-r--r--src/privoxytemplates/show-status315
-rw-r--r--src/privoxytemplates/show-status-file150
-rw-r--r--src/privoxytemplates/show-url-info188
-rw-r--r--src/privoxytemplates/show-version163
-rw-r--r--src/privoxytemplates/toggle187
-rw-r--r--src/privoxytemplates/toggle-mini90
-rw-r--r--src/privoxytemplates/untrusted194
-rw-r--r--src/questions.h382
-rw-r--r--src/quickconfig.ui398
-rw-r--r--src/quickconfig.ui.h98
-rw-r--r--src/running.ui593
-rw-r--r--src/running.ui.h228
-rw-r--r--src/server.ui758
-rw-r--r--src/server.ui.h217
-rw-r--r--src/serverwizard.ui234
-rw-r--r--src/serverwizard.ui.h105
-rw-r--r--src/statgraph.cpp253
-rw-r--r--src/statgraph.h229
-rw-r--r--src/testprivacyproxy.cpp69
-rw-r--r--src/testprivacyproxy.h112
-rw-r--r--src/tor_ioslave/Makefile.am15
-rw-r--r--src/tor_ioslave/torioslave.cpp167
-rw-r--r--src/tor_ioslave/torioslave.h43
-rw-r--r--src/tor_ioslave/torioslave.lsm16
-rw-r--r--src/tor_ioslave/torioslave.protocol29
-rw-r--r--src/torclient.cpp1536
-rw-r--r--src/torclient.h274
-rw-r--r--src/torconfig.h318
-rw-r--r--src/tork.152
-rw-r--r--src/tork.cpp4493
-rw-r--r--src/tork.desktop10
-rw-r--r--src/tork.h435
-rw-r--r--src/tork.kcfgc6
-rw-r--r--src/tork.lsm16
-rw-r--r--src/tork.xpm206
-rw-r--r--src/tork_downloadwithfirefox.desktop13
-rw-r--r--src/tork_downloadwithkonqueror.desktop13
-rw-r--r--src/tork_downloadwithopera.desktop13
-rw-r--r--src/torkactivelabel.cpp85
-rw-r--r--src/torkactivelabel.h53
-rw-r--r--src/torkapplet/Makefile.am17
-rw-r--r--src/torkapplet/tork_mnu.cpp203
-rw-r--r--src/torkapplet/tork_mnu.h53
-rw-r--r--src/torkapplet/torkmenu.desktop8
-rw-r--r--src/torkconfig.kcfg695
-rw-r--r--src/torkconfig.kcfgc7
-rw-r--r--src/torkui.rc61
-rw-r--r--src/torkview.cpp2103
-rw-r--r--src/torkview.h529
-rw-r--r--src/torkview_base.ui1005
-rw-r--r--src/torkview_base.ui.h643
-rw-r--r--src/torservers.ui619
-rw-r--r--src/torservers.ui.h450
-rw-r--r--src/trayhoverpopup.cpp154
-rw-r--r--src/trayhoverpopup.h91
-rw-r--r--src/trayicon.cpp270
-rw-r--r--src/trayicon.h105
-rw-r--r--src/update.cpp646
-rw-r--r--src/update.h127
-rw-r--r--src/upnp/Makefile.am14
-rw-r--r--src/upnp/exitoperation.cpp47
-rw-r--r--src/upnp/exitoperation.h67
-rw-r--r--src/upnp/forwardportlist.cpp83
-rw-r--r--src/upnp/forwardportlist.h101
-rw-r--r--src/upnp/httprequest.cpp123
-rw-r--r--src/upnp/httprequest.h98
-rw-r--r--src/upnp/portlist.cpp73
-rw-r--r--src/upnp/portlist.h103
-rw-r--r--src/upnp/soap.cpp53
-rw-r--r--src/upnp/soap.h62
-rw-r--r--src/upnp/upnpdescriptionparser.cpp220
-rw-r--r--src/upnp/upnpdescriptionparser.h49
-rw-r--r--src/upnp/upnpmcastsocket.cpp313
-rw-r--r--src/upnp/upnpmcastsocket.h91
-rw-r--r--src/upnp/upnprouter.cpp531
-rw-r--r--src/upnp/upnprouter.h303
-rw-r--r--src/upnpmanager.cpp173
-rw-r--r--src/upnpmanager.h89
-rw-r--r--src/usability.ui333
-rw-r--r--src/usability.ui.h151
-rw-r--r--src/version.h24
-rw-r--r--src/warnings.h413
554 files changed, 69055 insertions, 0 deletions
diff --git a/src/GeoIP-1.4.0/AUTHORS b/src/GeoIP-1.4.0/AUTHORS
new file mode 100644
index 0000000..b1295b9
--- /dev/null
+++ b/src/GeoIP-1.4.0/AUTHORS
@@ -0,0 +1 @@
+T.J. Mather <tjmather@maxmind.com>
diff --git a/src/GeoIP-1.4.0/COPYING b/src/GeoIP-1.4.0/COPYING
new file mode 100644
index 0000000..5ab7695
--- /dev/null
+++ b/src/GeoIP-1.4.0/COPYING
@@ -0,0 +1,504 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/src/GeoIP-1.4.0/ChangeLog b/src/GeoIP-1.4.0/ChangeLog
new file mode 100644
index 0000000..e127c97
--- /dev/null
+++ b/src/GeoIP-1.4.0/ChangeLog
@@ -0,0 +1,374 @@
+1.4.0 2006-8-7
+ * Changed license from GPL to LGPL, so that PHP Extension can be included in PECL (Olivier Hill)
+ * Rewrote GEOIP_CHECK_CACHE code, fixed numerous bugs
+ - CheckCache now works if GeoIP file is overwriten by mv command
+ - Fixed bug where CheckCache kept reloading in GEOIP_STANDARD_MODE
+ - Fixed segfault issue in GEOIP_MEMORY_CACHE mode
+ - Fixed garbage data appearing in GEOIP_INDEX_CACHE mode
+ - Fixed realloc in case realloc returns new memory block (Andre Morozov of Stone Steps)
+ * Updated geoipupdate to print status messages for each database instead of just last database
+ * Check that gi is not null before running code in GeoIP_delete
+ * Updated LICENSE file to add GPL License Exception for PHP
+ * Fixed alpha-3 codes ordering, replaced TLS,TKM,TUN,TON with TKM,TUN,TON,TLS
+ * TP/East Timor changed to TL/Timor-Leste, reflecting changes in ISO-3166
+ * Added Netware and Windows makefiles (Guenter Knauf)
+ * Fixed NetWare compiler issue with char block[block_size] declaration (Guenter Knauf)
+ * Updated geoipupdate example to run weekly
+
+1.3.17 2006-5-14
+ * Fixed headers for Windows/Netware compilation (Guenter Knauf)
+ * Fixed Received Error -21 (Sanity check database_info string failed)
+ when running geoipupdate with GeoIP Country when UserId and
+ productIds were not specified. Bug was introduced in 1.3.15.
+
+1.3.16 2006-4-17
+ * Fixed compliation error in GeoIPUpdate.c
+
+1.3.15 2006-4-14
+ * Updated README documentation
+ * Updated geoipupdate so that it writes file as it is uncompressed instead
+ of storing entire GeoIP.dat file in memory (Frank Mather)
+ * Updated geoiplookup so that it returns GeoIP Domain Name if available
+ (Frank Mather)
+ * Updated geoipupdate so that it reports whether databases are updated
+ in non-verbose mode (Frank Mather)
+
+1.3.14 2005-9-7
+ * Check if byte, ushort, ulong, u16, u32 are defined in configure
+ script. Fixes compilation issue on FreeBSD systems.
+ * Check for Big Endian byte order (needed for MD5 code in geoipupdate
+ to work properly on Mac OS X and other Big Endian processors)
+ * Fixed GEOIP_CHECK_CACHE mode when used with GEOIP_STANDARD to
+ only refresh upon file change
+ * Fixed memory leak when refreshing file in GEOIP_CHECK_CACHE mode
+ * Updated ltmain.sh to support Debian GNU/k*BSD bug #315425 (Marek Habersack)
+ * Added lookup functions using IP numeric representation as input (Frank Mather)
+ * Removed geoipexport
+ * Replaced Yugoslavia with Serbia and Montenegro
+ * Updated geoiplookup to only perform country lookup once instead of twice by using GeoIP_id_by_name
+
+1.3.13 2005-8-1
+ * Fixed autoconf weirdness that resulted in libraries being
+ installed without .so suffix
+
+1.3.12 2005-7-19
+ * Removed -lGeoIP from libGeoIPUpdate_la_LIBADD - fixes compilation error
+ if GeoIP isn't already installed (Thomas Steudten)
+
+1.3.11 2005-7-7
+ * Fixed gcc warnings and bug. Use int
+ instead of char for checking the return value of getopt in geoipupdate.c.
+ Moved the internal functions to GeoIP_internal.h to get rid
+ of those 'implicit declaration' warnings. (Ludwig Nussel/SUSE)
+ * Cleaned up name space by prefixing internal functions with
+ _GeoIP* (Ludwig Nussel/SUSE)
+ * Memory Leak fix for GeoIP City if fread error
+ * Added more verbose error messages for geoipupdate (Frank Mather)
+ * Added check for zlib.h to configure.in
+
+1.3.10 2005-4-17
+ * Added types.h to Makefile.am - fixes compilation error
+
+1.3.9 2005-4-14
+ * fixed bug with GEOIP_INDEX_CACHE (Frank Mather)
+ * fixed segfault issue if GeoIP.dat not found (Frank Mather)
+ * Updated MD5 checksum code to use GnuPG code which works
+ on 64bit machines (Frank Mather)
+ * Fixed memory leak in test-geoip-isp.c and test-geoip-org.c
+ * Added support for GeoIP Domain Names in geoipupdate
+
+1.3.8 2004-11-7
+ * Updated geoipupdate to report invalid userID and productID errors
+ * Check if gethostbyname_r is version that returns int or is other version
+ - should fix compile errors on Solaris and FreeBSD
+ * Updated URL to get license key, userId, and product Ids in conf/GeoIP.conf.default
+ * Updated test case, removed www.asahi.com
+ * Added support for GEOIP_INDEX_CACHE - which just caches
+ the most frequently access index portion of the database, resulting
+ in faster lookups than GEOIP_STANDARD, but less memory usage than
+ GEOIP_MEMORY_CACHE (Frank Mather)
+
+1.3.7 2004-10-5
+ * Updated test case, removed www.bundesregierung.de added www.asahi.com
+
+1.3.6 2004-8-8
+ * Check for gethostbyname_r support in configure (Mac OS X doesn't support gethostbyname_r)
+ * Made GeoIP City code thread safe
+ * Fixed bug with geoipupdate reading in product ids
+ * Added support for GeoIP Netspeed geoipupdate
+ * Fix memleak in lookupaddress (Ludwig Nussel/SUSE)
+ * Add prototype for _full_path_to to make 64bit clean
+ (Ludwig Nussel/SUSE)
+ * Add return values to test programs (Ludwig Nussel/SUSE)
+
+1.3.5 2004-7-5
+ * Added more documentation to README file
+ * Made GEOIP_CHECK_CACHE work with GEOIP_STANDARD mode - reloads filehandle
+ in case file changes.
+ * Added GeoIP_country_code_by_ipnum and GeoIP_id_by_ipnum to use
+ existing ulong IP Address in numeric form instead of having to
+ convert it to string (Boris Hajduk)
+ * Made code thread safe by replacing gethostbyname with gethostbyname_r
+
+1.3.4 2004-6-4
+ * Fixed bug where *.gz file(s) didn't get removed after geoipupdate
+
+1.3.3 2004-6-2
+ * Added support for NetSpeed lookup to geoiplookup
+ * inet_addr patch for 64 bit systems (Thomas Steudten)
+ * Added Support for automated downloads of GeoIP Region, City, ISP and Organization databases (Frank Mather)
+ * INADDR_NONE Patch for Solaris 9 (John Young)
+
+1.3.2 2004-4-20
+ * Added support for Maxmind NetSpeed
+
+MinGW patch from Stanislaw Pusep
+
+I was re-compiling Geolizer (http://sysd.org/log.php#glzr) on Win32 so I firstly needed to put up-to-date Win32 compatibility of libGeoIP itself. Fortunately MinGW plataform evolved a lot since last time I used it to compile libGeoIP. I'm sending you the patch with changes required for libGeoIP to work on both Win32 and UN*X. UN*X behavior is unaffected. Now, detailed explanation of what I did at all:
+1) Made correct header imports for both Win32 and UN*X. UN*X imports netdb.h & netinet/in.h and Win32 imports windows.h & winsock.h
+2) Win32 gethostbyname() is only able to resolve hostnames, it can't convert "127.0.0.1" string to 32-bit IP address. Thus I added lookupaddress() function that safely resolves any string to IP address and replaced all gethostbyname() calls by it.
+3) Database files were referenced by pre-compiled static strings. I malloc()ed buffers for file names so they can be changed "on fly". Thus, on Win32 version GeoIP.dat & other files are being seeked in the same directory as executable file or library.
+4) Added README.MinGW file with brief explanation on how to get GeoIP working under MinGW system.
+
+1.3.1 2003-11-11
+ * Check for stdint.h in autoconf (Sean Chittenden)
+ * prevent the geoipupdate man page from trying to install itself directly in the system directory (Gyepi Sam)
+
+1.3.0 2003-09-29
+ * Fixed includes to compile on Windows (Fabrice Colin)
+ * Removed the _addr_to_num() calls from GeoIP_*_by_name()
+ * _seek_record() optimizations (Maurice Cinquini)
+ 1) Use a single buf ptr inside the loops.
+ Set to the stack buffer or the cached memory the start of the function.
+ 2) Unroll the i=0,1 loop to allow constant folding.
+ 3) Unroll the j loop for the common case of j = STANDARD_RECORD_LENGTH
+ (I've already done the above changes see attached function.)
+ With gcc -O2 calculating x[0] and x[1] for STANDARD_RECORD_LENGTH now
+ only takes 15 (was > 100) i80x86 instructions with 6 byte accesses of RAM. 4) only calculate x[0], x[1] when needed, may be a bigger win
+ than the above since all the other optimizations above only reduced
+ CPU instructions operating on CPU cached RAM.
+ ! IMPORTANT API Change: Changed GeoIPRegion to have region in structure. Saves space and a malloc.
+ Since GeoIPRegion.region is no longer a pointer but an in-structure
+ array so test the first byte of region == 0 rather testing if the region
+ pointer is NULL. (Maurice Cinquini)
+ * Added GeoIP_assign_region_by_inetaddr which doesn't do any mallocs and made all other region APIs go thru it (Maurice Cinquini)
+ * Replaced _h_addr_to_num() with ntohl() and removed _h_addr_to_num() (Maurice Cinquini)
+ * Fixed bug when IP address not found in region rev1 database (Jason Linhart)
+ * Added added extern "C" to GeoIPCity.h fixes problems when included in C++ library
+
+1.2.2 2003-08-10
+ * Added support for GeoIP ISP Edition identifier
+ * Fixed bug in GeoIP_database_info (Jason Linhart)
+ * Added support for GeoIP AS Number Edition
+ ! renamed GeoIP_org_by_* functions to GeoIP_name_by_* to reduce confusion
+ since these functions are used by GeoIP ISP and GeoIP ASNum as well
+ as GeoIP Organization
+ * Added support for GeoIP Proxy Edition
+ ! renamed GeoIP_country_id_by_* functions to GeoIP_id_by_*
+
+1.2.1 2003-07-12
+ * Added GeoIP_record_id_by_addr and GeoIP_next_record functions
+ * Added support for new GeoIP Region format, including Canadian Provinces
+
+1.2.0 2003-04-26
+ * Added support for GeoIP City format revision 1, including dma code and area code
+ * geoiplookup returns results from GeoIP Region, City, ISP and Organization databases
+ * Standardized location for GeoIP Region, City, ISP and Organization databases
+ * Added GeoIP_open_type to open database from default location for other dbs besides country
+ * Added check to make sure that the appropriate database is loaded for each lookup method
+ * Updated update code to check for first 12 characters of license key
+ * Added GeoIP_country_continent array to lookup continent by country ID
+
+1.1.9 2003-03-10
+ * merged windows patch into main code base (Kenneth R. Robinette)
+ * Changed const int to #define for windows compatibility
+
+1.1.8 2003-03-04
+ * Fixed bug with city database introduced in 1.1.6
+
+1.1.7 2003-03-04
+ * Fixed bug introduced in 1.1.6 when run in GEOIP_STANDARD mode
+ * Added test to test GEOIP_STANDARD
+
+1.1.6 2003-03-03
+ * Added spec for building RPMs (Ryan Weaver)
+ * Added support for 4byte records for Organization database
+ * Changed Taiwan, Province of China to Taiwan
+
+1.1.5 2003-02-10
+ * Added support for GeoIP Organization database
+
+1.1.4 2002-12-30
+ * Cast number to int in _num_to_addr in geoipexport (Ralf S. Engelschall)
+ * Removed printf debug statements from geoipexport
+ * correct library build ordering (Ralf S. Engelschall)
+ * ulong -> unsigned long (Sean Chittenden)
+
+1.1.3 2002-12-24
+ * Added GeoIPUpdate.h to EXTRA_DISTS
+ * Compile fixes for Solaris, FreeBSD (Michael McClennen, Corris Randall)
+ * Handle NULL in printf in test-geoip-region
+
+1.1.2 2002-12-16
+ * Added support for postal codes
+ * Added geoipexport, program to export bit binary file to
+ binary tree format and csv format
+ * Split update code into separate library, GeoIPUpdate.la
+ * Allow passing NULL callback to GeoIP_update_database function
+ (Sean Chittenden)
+ * Added geoipexport program, exports to CSV file
+ * Added GeoIP_database_edition method
+ * Changed DATADIR to GEOIPDATADIR
+
+1.1.1 2002-11-07
+ * Fixed segfault issue with GeoIPRegion_delete
+ * Handle test failures where lookup returns NULL more gracefully
+
+1.1.0 2002-11-06
+ * Perform sanity checking before installing datebase using geoipupdate
+ * Removed file locking, since we install file by renaming instead of writing to it.
+ * Fixed geoipupdate to check for NULL return value
+ * Added constants for different editions
+ * Added O1 code for "Other country", used in per-country city editions
+ * fixed multi-line string literals warning in test-geoip.c
+ * Use enum constants for GeoIP_update_database values
+ * Added GEOIP_CHECK_CACHE option (not working yet)
+
+1.0.10 2002-10-28
+ * IMPORTANT API Change - Return NULL instead of '--' and 'N/A'
+ Be sure to check the return value for NULL to avoid segmentation faults!!!!
+ * Added callback to print messages from GeoIP_update_database
+ * Moved GeoIPConfFile to geoipupdate.c
+ * Changed databaseSegments to unsigned int (Chris Gibbs)
+ * Fixed compiler warnings (Chris Gibbs)
+ * API Change - GeoIPRegion region member set to NULL when no region available
+ * Change short int to int (Chris Gibbs)
+ * Added write/read file locking for GeoIPUpdate.c/GeoIP.c
+
+1.0.9 2002-10-16
+ * removed -ansi from Makefile.am to avoid compile error on Solaris 8
+ * Compile fix for FreeBSD Stable (Kimura Fuyuki)
+
+1.0.8 2002-10-05
+ * Included header required for *BSD (Akinori Musha)
+
+1.0.7 2002-10-05
+ * Fixed compilation error with GeoIPUpdate.c
+
+1.0.6 2002-10-04
+ * Moved update code into separate file
+ * Added md5 checksums to update code
+ * Fixed memory leak when running geoiplookup -v
+ * Moved const RECORD_LENGTH to #define RECORD_LENGTH for Windows compatibility
+ (Randy Kobes)
+ * Cleaned up GeoIP_new code
+
+1.0.5 2002-09-23
+ * Supports GeoIP Regional Edition
+ * Macau is now "Macao" per ISO 3166-1 change
+ * Romania "ROM" is now "ROU" per ISO 3166-1 change
+ * Added #define for memcpy -> BSD's bcopy (Chris Gibbs)
+ * Removed "private" functions from GeoIP.h
+
+1.0.4 2002-08-27
+ * rewrote _seek_country to use loop instead of recursion for faster performance
+ * Removed "orphan" nodes from demo database resulting in smaller size (Jason Linhart)
+ * Moved changes for building windows DLL into separate patch
+ * Fixed segfaults when passed malformed IP addresses
+
+1.0.3 2002-08-26
+ * Added more changes for windows compatibility
+ (Stanislaw Pusep)
+ * Added benchmark program
+
+1.0.2 2002-08-21
+ * Open database using "rb" for windows compatibility
+ (Stanislaw Pusep)
+ * Removed superfluous inet_ntop command (Stanislaw Pusep)
+
+1.0.1 2002-08-20
+ * Fixed bug with resolving hostnames
+ * More fixes for compiler warnings (Chris Gibbs)
+ * Changed int to unsigned int in _is_ipaddr (Chris Gibbs)
+
+1.0.0 2002-08-12
+ * Changed license to GPL
+ * Don't perform Reverse DNS lookups on IP addresses
+ * Only include getopt.h on Linux (OpenPKG patch)
+ * Avoid the_license_key_str warning (OpenPKG patch)
+ * Added license for March 2002 database
+
+0.3.0 2002-08-04
+ * Added support for 'A2', Satellite Providers
+
+0.2.8 2002-07-30
+ * Handle malformed input gracefully
+ * Added section to README on Solaris workarounds
+ * Added geoipupdate man page
+
+0.2.7 2002-07-27
+ * Added section to README on automatic updates
+ * link to socket library on solaris
+
+0.2.6 2002-07-25
+ * optimized GeoIP_open (Chris Gibbs)
+ * check for partial file read in GeoIP_open (Chris Gibbs)
+ * optimized _addr_to_num() (Chris Gibbs)
+ * changed write and read to send and recv for sockets
+ * Only install GeoIP.conf and GeoIP.dat if not already installed
+
+0.2.5 2002-07-22
+ * Added verbose option to GeoIP_update_database
+
+0.2.4 2002-07-22
+ * Fix for GeoIP_update_database
+
+0.2.3 2002-07-22
+ * Fixes for FreeBSD
+ * All calls to malloc are checked for NULL pointer (Chris Gibbs)
+ * Fixed spelling of "Kazakhstan" (Chris Gibbs)
+ * Initialize cache_buf to NULL (Chris Gibbs)
+ * More memory leak fixes (Chris Gibbs)
+
+0.2.2 2002-07-18
+ * Added update database function
+ * Fixed memory leak in GeoIP_new (Chris Gibbs)
+
+0.2.1 2002-07-03
+ * Added support for anonymous proxies
+
+0.2.0 2002-06-23
+ * Added new memory caching option for improved performance
+
+0.1.7 2002-05-29
+ * Only add -lnsl for systems that support libnsl
+ * Added decl for 3 letter country code array to GeoIP.h
+
+0.1.6 2002-05-25
+ * Added 3 letter country code
+
+0.1.5 2002-05-23
+ * Added -lnsl fixed compile errors
+
+0.1.4 2002-05-11
+ * Fixed bugs in demo March 2002 database
+
+0.1.3 2002-04-21
+ * Fixed bug related to signed int (Brian Grossman)
+ * Better error handling when hostname not found
+ * Fixed bug when netmask=32 for netblock
+
+0.1.2 2002-04-20
+ * Added two new functions, GeoIP_country_id_by_addr
+ and GeoIP_country_id_by_name.
+ * Made GeoIP_country_code and GeoIP_country_name
+ viewable outside of library, to be with with
+ GeoIP_country_id_by_* functions.
+
+0.1.1 2002-04-07
+ * GeoIP.h is now installed to includedir
+ * constructor and destructor are now provided by
+ GeoIP_new, GeoIP_open, and GeoIP_delete
+
+0.1.0 2002-04-07
+ * Initial release
diff --git a/src/GeoIP-1.4.0/GeoIP-LICENSE.txt b/src/GeoIP-1.4.0/GeoIP-LICENSE.txt
new file mode 100644
index 0000000..457710d
--- /dev/null
+++ b/src/GeoIP-1.4.0/GeoIP-LICENSE.txt
@@ -0,0 +1,74 @@
+There are two licenses, one for the C library software, and one for
+the database.
+
+SOFTWARE LICENSE (C library)
+
+The GeoIP C Library is licensed under the GPL. For details see
+the COPYING file.
+
+OPEN DATA LICENSE (GeoIP Standard Edition Database)
+
+Copyright (c) 2003 MaxMind LLC. All Rights Reserved.
+
+All advertising materials and documentation mentioning features or use of
+this database must display the following acknowledgment:
+"This product includes GeoIP data created by MaxMind, available from
+http://maxmind.com/"
+
+Redistribution and use with or without modification, are permitted provided
+that the following conditions are met:
+1. Redistributions must retain the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other
+materials provided with the distribution.
+2. All advertising materials and documentation mentioning features or use of
+this database must display the following acknowledgement:
+"This product includes GeoIP data created by MaxMind, available from
+http://maxmind.com/"
+3. "MaxMind" may not be used to endorse or promote products derived from this
+database without specific prior written permission.
+
+THIS DATABASE IS PROVIDED BY MAXMIND.COM ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL MAXMIND.COM BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+DATABASE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Some parts of this software distribution are derived from the APNIC, ARIN and
+RIPE databases (copyright details below). The author of this module makes no
+claims of ownership on those parts.
+
+APNIC conditions of use:
+
+The files are freely available for download and use on the condition that APNIC
+will not be held responsible for any loss or damage arising from the application
+of the information contained in these reports.
+
+APNIC endeavours to the best of its ability to ensure the accuracy of these
+reports; however, APNIC makes no guarantee in this regard.
+
+In particular, it should be noted that these reports seek to indicate the
+country where resources were first allocated or assigned. It is not intended
+that these reports be considered as an authoritative statement of the location
+in which any specific resource may currently be in use.
+
+ARIN database copyright:
+
+Copyright (c) American Registry for Internet Numbers. All rights reserved.
+
+RIPE database copyright:
+
+The information in the RIPE Database is available to the public for agreed
+Internet operation purposes, but is under copyright. The copyright statement is:
+
+"Except for agreed Internet operational purposes, no part of this publication
+may be reproduced, stored in a retrieval system, or transmitted, in any form or
+by any means, electronic, mechanical, recording, or otherwise, without prior
+permission of the RIPE NCC on behalf of the copyright holders. Any use of this
+material to target advertising or similar activities is explicitly forbidden and
+may be prosecuted. The RIPE NCC requests to be notified of any such activities
+or suspicions thereof."
diff --git a/src/GeoIP-1.4.0/INSTALL b/src/GeoIP-1.4.0/INSTALL
new file mode 100644
index 0000000..b42a17a
--- /dev/null
+++ b/src/GeoIP-1.4.0/INSTALL
@@ -0,0 +1,182 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
diff --git a/src/GeoIP-1.4.0/Makefile.am b/src/GeoIP-1.4.0/Makefile.am
new file mode 100644
index 0000000..38cd92f
--- /dev/null
+++ b/src/GeoIP-1.4.0/Makefile.am
@@ -0,0 +1,10 @@
+NULL =
+
+INCLUDES = -Wall -ansi
+
+SUBDIRS = \
+ data \
+ libGeoIP \
+ $(NULL)
+
+EXTRA_DIST = READMEwin32.txt GeoIPWinDLL.patch TODO bootstrap GeoIP.spec GeoIP.spec.in
diff --git a/src/GeoIP-1.4.0/NEWS b/src/GeoIP-1.4.0/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/GeoIP-1.4.0/NEWS
diff --git a/src/GeoIP-1.4.0/README b/src/GeoIP-1.4.0/README
new file mode 100644
index 0000000..9e09c98
--- /dev/null
+++ b/src/GeoIP-1.4.0/README
@@ -0,0 +1,132 @@
+ GeoIP 1.4.0
+ -----------
+
+IMPORTANT API Change for 1.3.x and above users for GeoIP Region database
+GeoIPRegion.region is no longer a pointer but an in-structure
+array so test the first byte of region == 0 rather testing if the region
+pointer is NULL.
+
+IMPORTANT API Change for 1.1.x and above users - as of GeoIP 1.1.0 the
+GeoIP_country_xxx_by_xxx functions return NULL if a country can not
+be found (it used to return '--' or 'N/A'. Be sure to check the
+return value for NULL, to avoid segmentation faults!
+
+GeoIP is a C library that enables the user to find geographical and
+network information of an IP address.
+Included is a free GeoLite Country database
+that is updated at the beginning of every month.
+To download the latest free GeoLite Country database, go to:
+http://www.maxmind.com/app/geoip_country
+
+There is also a free city-level geolocation database, GeoLite City,
+available from:
+http://www.maxmind.com/app/geolitecity
+
+We also offer commercial GeoIP databases with greater accuracy and
+additional network information, for more details, see:
+http://www.maxmind.com/app/products
+
+As of version 1.3.6, the GeoIP C library is thread safe.
+
+This module can be used to automatically select the geographically closest
+mirror, to analyze your web server logs to determine the countries of your
+visitors, for credit card fraud detection, and for software export controls.
+
+If you use GeoIP to block access from high risk countries in order
+to reduce fraud or abuse, you should also block access from known
+proxy servers. For more details, see:
+http://www.maxmind.com/app/proxy
+
+To install, run:
+
+./configure
+make
+make check
+make install
+
+The GeoIP C library relies on GNU make, not on BSD make
+
+MEMORY CACHING AND OTHER OPTIONS
+
+There are four options available:
+
+GEOIP_STANDARD - read database from filesystem, uses least memory.
+
+GEOIP_MEMORY_CACHE - load database into memory, faster performance
+ but uses more memory
+
+GEOIP_CHECK_CACHE - check for updated database. If database has been updated,
+ reload filehandle and/or memory cache.
+
+GEOIP_INDEX_CACHE - just cache
+ the most frequently accessed index portion of the database, resulting
+ in faster lookups than GEOIP_STANDARD, but less memory usage than
+ GEOIP_MEMORY_CACHE - useful for larger databases such as
+ GeoIP Organization and GeoIP City. Note, for GeoIP Country, Region
+ and Netspeed databases, GEOIP_INDEX_CACHE is equivalent to GEOIP_MEMORY_CACHE
+
+The options can be combined using bit operators. For example you can
+use both GEOIP_MEMORY_CACHE and GEOIP_CHECK_CACHE by calling:
+
+ GeoIP_open("/path/to/GeoIP.dat", GEOIP_MEMORY_CACHE | GEOIP_CHECK_CACHE);
+
+EXAMPLES
+
+See
+test/
+ test-geoip.c
+ test-geoip-region.c
+ test-geoip-city.c
+ test-geoip-isp.c
+ test-geoip-org.c
+ test-geoip-netspeed.c
+
+For examples of how to use the API. The test-geoip.c works with both the free and paid
+GeoIP Country databases. The other example programs require the paid databases available
+from http://www.maxmind.com/app/products
+
+AUTOMATIC UPDATES
+
+MaxMind offers a service where you can have your database updated
+automically each week. For more details see:
+
+http://www.maxmind.com/app/license_key
+
+TROUBLESHOOTING
+
+Note that it is recommended that you use GNU make. Also, if you are using
+OpenBSD, GeoIP requires OpenBSD 3.1 or greater.
+
+if you get "cannot load shared object file: No such file or directory"
+error, add the directory libGeoIP.so was installed to to /etc/ld.so.conf
+and run ldconfig
+
+On Solaris, if you get a
+ld: fatal: relocations remain against allocatable but non-writable sections
+error, try running
+
+# make clean
+# ./configure --disable-shared
+# make
+
+If you get a "ar : command not found" error, make sure that ar is
+in your path. On Solaris, ar is typically found in /usr/ccs/bin
+
+If you get a "geoipupdate.c:24: getopt.h: No such file or directory"
+error, run
+
+# export CPPFLAGS="-I/usr/local/include"
+
+(assuming that getopt.h is in /usr/local/include)
+
+If you get a "zlib.h: No such file or directory" error, make sure
+that the zlib development libraries are installed on your server.
+These are typically included in a "zlib-devel" package.
+
+If you get a "bad interpreter: No such file or directory" error
+when running ./configure, make sure that there are no DOS
+returns in the configure script. To remove DOS returns,
+run perl -pi -e 's!\r!!g' configure.
+
+Please contact support@maxmind.com with any questions or bug
+reports.
diff --git a/src/GeoIP-1.4.0/TODO b/src/GeoIP-1.4.0/TODO
new file mode 100644
index 0000000..32a6c80
--- /dev/null
+++ b/src/GeoIP-1.4.0/TODO
@@ -0,0 +1,54 @@
+Rutger Okhuizen 7/31/2006
+
+Implement waiting algorithm for GEOIP_CHECK_CACHE,
+so stat is called on every lookup.
+
+-----------------------
+
+Maurice Cinquini
+
+*** ifndef WIN32 on netdb.h ? ***
+In GeoIPCity.c you don't "#ifndef WIN32" the netdb.h include,
+but in GeoIP.c you do. Which one is right?
+
+*** Warnings in GeoIP-1.2.1 before I made changes ***
+GeoIPUpdate.c:73: warning: implicit declaration of function `_setup_dbfilename'
+ I suggest a GeoIP_private.h file to include prototypes for
+ _setup_dbfilename and other private functions also used by GeoIPCity.c
+
+*** Drop the GeoIP_*_by_addr API calls ***
+And now that I think of it, why do you need a seperate
+GeoIP_region_by_addr and GeoIP_region_by_name since
+the later does the work of the former just as efficently.
+For backward compatibility you could #define GeoIP_region_by_addr
+to GeoIP_region_by_name
+
+
+
+
+Performance improvements suggested by Jason Linhart
+1. cluster nodes to improve disk performance when using GEOIP_STANDARD
+2. evaluate preformance of replacing binary tree with nodes containing 4 children
+
+Write function to list countries, sorted by name. Chris Gibbs contributed this which could be
+used:
+
+ int GeoIP_country_sorted_index[246] = {
+ 0, 5, 8, 61, 14, 3, 11, 7, 12, 6, 13, 9, 17, 1, 16, 15, 18, 32, 25, 21,
+ 20,36, 22, 37, 27, 28, 33, 30, 19, 35, 34, 31, 104, 29, 24, 23, 26,
+114, 47, 38, 52,121, 41, 207, 46, 48, 53, 39, 49, 116, 42, 40, 45,
+ 50, 44, 97, 51, 54, 55, 58, 57, 59, 60, 216, 62, 64, 203, 87, 66,
+ 63, 68, 2, 71, 73, 70, 69, 74, 75, 80, 170,208, 76, 84, 79, 56, 81,
+82, 88, 83, 78, 86, 91, 90, 85, 92, 93, 98, 95, 228, 96,94, 99, 107,
+ 103, 100, 106, 105, 101, 102, 108, 109, 111, 110, 122, 112, 115,
+ 118,119, 120, 113, 123, 132, 124, 129, 128, 133, 126, 130, 131,
+ 143, 139, 137,151,153, 150, 140, 148, 138, 145, 146, 149, 238,
+ 152, 72, 136, 135, 142, 147, 134,154, 141, 155, 164, 163, 161,
+10, 156, 166, 160, 157, 159, 165, 158, 144, 162, 167,173, 180,
+178, 168, 171, 181, 169, 172, 176, 174, 179, 177, 182, 183, 184,
+185,186, 193, 117, 125, 175, 229, 236, 198, 202, 187, 199, 189,
+197, 192, 196,194,188, 200, 240, 89, 67, 127, 190, 201, 195, 205,
+191, 43, 204, 220, 211, 221,210,209, 212, 215, 218, 214, 217,
+213,206, 219, 223, 222, 4, 77, 225, 224, 226,227,234, 230, 233,
+ 231,232, 235, 65, 237, 239, 242, 241, 243, 244, 245};
+
diff --git a/src/GeoIP-1.4.0/data/GeoIP-LICENSE.txt b/src/GeoIP-1.4.0/data/GeoIP-LICENSE.txt
new file mode 100644
index 0000000..a6bc1ac
--- /dev/null
+++ b/src/GeoIP-1.4.0/data/GeoIP-LICENSE.txt
@@ -0,0 +1,76 @@
+There are two licenses, one for the C library software, and one for
+the database.
+
+SOFTWARE LICENSE (C library)
+
+The GeoIP C Library is licensed under the GPL. For details see
+the COPYING file.
+
+OPEN DATA LICENSE (GeoIP Standard Edition Database)
+
+Copyright (c) 2003 MaxMind LLC. All Rights Reserved.
+
+All advertising materials and documentation mentioning features or use of
+this database must display the following acknowledgment:
+"This product includes GeoIP data created by MaxMind, available from
+http://maxmind.com/"
+
+Redistribution and use with or without modification, are permitted provided
+that the following conditions are met:
+1. Redistributions must retain the above copyright notice, this list of
+conditions and the following disclaimer in the documentation and/or other
+materials provided with the distribution.
+2. All advertising materials and documentation mentioning features or use of
+this database must display the following acknowledgement:
+"This product includes GeoIP data created by MaxMind, available from
+http://maxmind.com/"
+3. "MaxMind" may not be used to endorse or promote products derived from this
+database without specific prior written permission.
+
+THIS DATABASE IS PROVIDED BY MAXMIND.COM ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL MAXMIND.COM BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+DATABASE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Some parts of this software distribution are derived from the APNIC, ARIN and
+RIPE databases (copyright details below). The author of this module makes no
+claims of ownership on those parts.
+
+APNIC conditions of use:
+
+The files are freely available for download and use on the condition that APNIC
+will not be held responsible for any loss or damage arising from the application
+of the information contained in these reports.
+
+APNIC endeavours to the best of its ability to ensure the accuracy of these
+reports; however, APNIC makes no guarantee in this regard.
+
+In particular, it should be noted that these reports seek to indicate the
+country where resources were first allocated or assigned. It is not intended
+that these reports be considered as an authoritative statement of the location
+in which any specific resource may currently be in use.
+
+ARIN database copyright:
+
+Copyright (c) American Registry for Internet Numbers. All rights reserved.
+
+RIPE database copyright:
+
+The information in the RIPE Database is available to the public for agreed
+Internet operation purposes, but is under copyright. The copyright statement is:
+
+"Except for agreed Internet operational purposes, no part of this publication
+may be reproduced, stored in a retrieval system, or transmitted, in any form or
+by any means, electronic, mechanical, recording, or otherwise, without prior
+permission of the RIPE NCC on behalf of the copyright holders. Any use of this
+material to target advertising or similar activities is explicitly forbidden and
+may be prosecuted. The RIPE NCC requests to be notified of any such activities
+or suspicions thereof."
+
+.
diff --git a/src/GeoIP-1.4.0/data/GeoIP.dat b/src/GeoIP-1.4.0/data/GeoIP.dat
new file mode 100644
index 0000000..7775938
--- /dev/null
+++ b/src/GeoIP-1.4.0/data/GeoIP.dat
Binary files differ
diff --git a/src/GeoIP-1.4.0/data/Makefile.am b/src/GeoIP-1.4.0/data/Makefile.am
new file mode 100644
index 0000000..1109aa8
--- /dev/null
+++ b/src/GeoIP-1.4.0/data/Makefile.am
@@ -0,0 +1,7 @@
+METASOURCES = AUTO
+
+geotorkdatadir = $(kde_datadir)/tork/geoip
+
+GEOIP_FILES = GeoIP.dat GeoIP-LICENSE.txt
+
+geotorkdata_DATA = $(GEOIP_FILES) \ No newline at end of file
diff --git a/src/GeoIP-1.4.0/data/README b/src/GeoIP-1.4.0/data/README
new file mode 100644
index 0000000..ef76422
--- /dev/null
+++ b/src/GeoIP-1.4.0/data/README
@@ -0,0 +1,2 @@
+wget http://www.maxmind.com/download/geoip/database/GeoIP.dat.gz
+gunzip GeoIP.dat.gz
diff --git a/src/GeoIP-1.4.0/libGeoIP/GeoIP.c b/src/GeoIP-1.4.0/libGeoIP/GeoIP.c
new file mode 100644
index 0000000..0cb6bc0
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/GeoIP.c
@@ -0,0 +1,994 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
+/* GeoIP.c
+ *
+ * Copyright (C) 2006 MaxMind LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "GeoIP.h"
+#include "GeoIP_internal.h"
+
+#ifndef WIN32
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h> /* For ntohl */
+#include <arpa/inet.h>
+#else
+#include <windows.h>
+#define snprintf _snprintf
+#endif
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h> /* for fstat */
+#include <sys/stat.h> /* for fstat */
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h> /* For uint32_t */
+#endif
+
+#ifndef INADDR_NONE
+#define INADDR_NONE -1
+#endif
+
+#define COUNTRY_BEGIN 16776960
+#define STATE_BEGIN_REV0 16700000
+#define STATE_BEGIN_REV1 16000000
+#define STRUCTURE_INFO_MAX_SIZE 20
+#define DATABASE_INFO_MAX_SIZE 100
+#define MAX_ORG_RECORD_LENGTH 300
+#define US_OFFSET 1
+#define CANADA_OFFSET 677
+#define WORLD_OFFSET 1353
+#define FIPS_RANGE 360
+
+#define CHECK_ERR(err, msg) { \
+ if (err != Z_OK) { \
+ fprintf(stderr, "%s error: %d\n", msg, err); \
+ exit(1); \
+ } \
+}
+
+const char GeoIP_country_code[251][3] = { "--","AP","EU","AD","AE","AF","AG","AI","AL","AM","AN",
+ "AO","AQ","AR","AS","AT","AU","AW","AZ","BA","BB",
+ "BD","BE","BF","BG","BH","BI","BJ","BM","BN","BO",
+ "BR","BS","BT","BV","BW","BY","BZ","CA","CC","CD",
+ "CF","CG","CH","CI","CK","CL","CM","CN","CO","CR",
+ "CU","CV","CX","CY","CZ","DE","DJ","DK","DM","DO",
+ "DZ","EC","EE","EG","EH","ER","ES","ET","FI","FJ",
+ "FK","FM","FO","FR","FX","GA","GB","GD","GE","GF",
+ "GH","GI","GL","GM","GN","GP","GQ","GR","GS","GT",
+ "GU","GW","GY","HK","HM","HN","HR","HT","HU","ID",
+ "IE","IL","IN","IO","IQ","IR","IS","IT","JM","JO",
+ "JP","KE","KG","KH","KI","KM","KN","KP","KR","KW",
+ "KY","KZ","LA","LB","LC","LI","LK","LR","LS","LT",
+ "LU","LV","LY","MA","MC","MD","MG","MH","MK","ML",
+ "MM","MN","MO","MP","MQ","MR","MS","MT","MU","MV",
+ "MW","MX","MY","MZ","NA","NC","NE","NF","NG","NI",
+ "NL","NO","NP","NR","NU","NZ","OM","PA","PE","PF",
+ "PG","PH","PK","PL","PM","PN","PR","PS","PT","PW",
+ "PY","QA","RE","RO","RU","RW","SA","SB","SC","SD",
+ "SE","SG","SH","SI","SJ","SK","SL","SM","SN","SO",
+ "SR","ST","SV","SY","SZ","TC","TD","TF","TG","TH",
+ "TJ","TK","TM","TN","TO","TL","TR","TT","TV","TW",
+ "TZ","UA","UG","UM","US","UY","UZ","VA","VC","VE",
+ "VG","VI","VN","VU","WF","WS","YE","YT","RS","ZA",
+ "ZM","ME","ZW","A1","A2","O1","AX","GG","IM","JE"};
+
+const char GeoIP_country_code3[251][4] = { "--","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","ANT",
+ "AGO","AQ","ARG","ASM","AUT","AUS","ABW","AZE","BIH","BRB",
+ "BGD","BEL","BFA","BGR","BHR","BDI","BEN","BMU","BRN","BOL",
+ "BRA","BHS","BTN","BV","BWA","BLR","BLZ","CAN","CC","COD",
+ "CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI",
+ "CUB","CPV","CX","CYP","CZE","DEU","DJI","DNK","DMA","DOM",
+ "DZA","ECU","EST","EGY","ESH","ERI","ESP","ETH","FIN","FJI",
+ "FLK","FSM","FRO","FRA","FX","GAB","GBR","GRD","GEO","GUF",
+ "GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","GS","GTM",
+ "GUM","GNB","GUY","HKG","HM","HND","HRV","HTI","HUN","IDN",
+ "IRL","ISR","IND","IO","IRQ","IRN","ISL","ITA","JAM","JOR",
+ "JPN","KEN","KGZ","KHM","KIR","COM","KNA","PRK","KOR","KWT",
+ "CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU",
+ "LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI",
+ "MMR","MNG","MAC","MNP","MTQ","MRT","MSR","MLT","MUS","MDV",
+ "MWI","MEX","MYS","MOZ","NAM","NCL","NER","NFK","NGA","NIC",
+ "NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER","PYF",
+ "PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW",
+ "PRY","QAT","REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN",
+ "SWE","SGP","SHN","SVN","SJM","SVK","SLE","SMR","SEN","SOM",
+ "SUR","STP","SLV","SYR","SWZ","TCA","TCD","TF","TGO","THA",
+ "TJK","TKL","TKM","TUN","TON","TLS","TUR","TTO","TUV","TWN",
+ "TZA","UKR","UGA","UM","USA","URY","UZB","VAT","VCT","VEN",
+ "VGB","VIR","VNM","VUT","WLF","WSM","YEM","YT","SRB","ZAF",
+ "ZMB","MNE","ZWE","A1","A2","O1","ALA","GGY","IMN","JEY"};
+
+const char * GeoIP_country_name[251] = {"N/A","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Netherlands Antilles",
+ "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados",
+ "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia",
+ "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the",
+ "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica",
+ "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic",
+ "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji",
+ "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","France, Metropolitan","Gabon","United Kingdom","Grenada","Georgia","French Guiana",
+ "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala",
+ "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia",
+ "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan",
+ "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait",
+ "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania",
+ "Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali",
+ "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives",
+ "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua",
+ "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia",
+ "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau",
+ "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan",
+ "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname",
+ "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand",
+ "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan",
+ "Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela",
+ "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa",
+ "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey"};
+
+/* Possible continent codes are AF, AS, EU, NA, OC, SA for Africa, Asia, Europe, North America, Oceania
+and South America. */
+
+const char GeoIP_country_continent[251][3] = {"--","AS","EU","EU","AS","AS","SA","SA","EU","AS","SA",
+ "AF","AN","SA","OC","EU","OC","SA","AS","EU","SA",
+ "AS","EU","AF","EU","AS","AF","AF","SA","AS","SA",
+ "SA","SA","AS","AF","AF","EU","SA","NA","AS","AF",
+ "AF","AF","EU","AF","OC","SA","AF","AS","SA","SA",
+ "SA","AF","AS","AS","EU","EU","AF","EU","SA","SA",
+ "AF","SA","EU","AF","AF","AF","EU","AF","EU","OC",
+ "SA","OC","EU","EU","EU","AF","EU","SA","AS","SA",
+ "AF","EU","SA","AF","AF","SA","AF","EU","SA","SA",
+ "OC","AF","SA","AS","AF","SA","EU","SA","EU","AS",
+ "EU","AS","AS","AS","AS","AS","EU","EU","SA","AS",
+ "AS","AF","AS","AS","OC","AF","SA","AS","AS","AS",
+ "SA","AS","AS","AS","SA","EU","AS","AF","AF","EU",
+ "EU","EU","AF","AF","EU","EU","AF","OC","EU","AF",
+ "AS","AS","AS","OC","SA","AF","SA","EU","AF","AS",
+ "AF","NA","AS","AF","AF","OC","AF","OC","AF","SA",
+ "EU","EU","AS","OC","OC","OC","AS","SA","SA","OC",
+ "OC","AS","AS","EU","SA","OC","SA","AS","EU","OC",
+ "SA","AS","AF","EU","AS","AF","AS","OC","AF","AF",
+ "EU","AS","AF","EU","EU","EU","AF","EU","AF","AF",
+ "SA","AF","SA","AS","AF","SA","AF","AF","AF","AS",
+ "AS","OC","AS","AF","OC","AS","AS","SA","OC","AS",
+ "AF","EU","AF","OC","NA","SA","AS","EU","SA","SA",
+ "SA","SA","AS","OC","OC","OC","AS","AF","EU","AF",
+ "AF","EU","AF","--","--","--","EU","EU","EU","EU"};
+
+const char * GeoIPDBDescription[NUM_DB_TYPES] = {NULL, "GeoIP Country Edition", "GeoIP City Edition, Rev 1", "GeoIP Region Edition, Rev 1", "GeoIP ISP Edition", "GeoIP Organization Edition", "GeoIP City Edition, Rev 0", "GeoIP Region Edition, Rev 0","GeoIP Proxy Edition","GeoIP ASNum Edition","GeoIP Netspeed Edition","GeoIP Domain Name Edition"};
+
+char * custom_directory = NULL;
+
+void GeoIP_setup_custom_directory (char * dir) {
+ custom_directory = dir;
+}
+
+char *_GeoIP_full_path_to(const char *file_name) {
+ int len;
+ char *path = malloc(sizeof(char) * 1024);
+
+ if (custom_directory == NULL){
+#ifndef WIN32
+ memset(path, 0, sizeof(char) * 1024);
+ snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", GEOIPDATADIR, file_name);
+#else
+ char buf[MAX_PATH], *p, *q = NULL;
+ memset(buf, 0, sizeof(buf));
+ len = GetModuleFileName(GetModuleHandle(NULL), buf, sizeof(buf) - 1);
+ for (p = buf + len; p > buf; p--)
+ if (*p == '\\')
+ {
+ if (!q)
+ q = p;
+ else
+ *p = '/';
+ }
+ *q = 0;
+ memset(path, 0, sizeof(char) * 1024);
+ snprintf(path, sizeof(char) * 1024 - 1, "%s/%s", buf, file_name);
+#endif
+ } else {
+ len = strlen(custom_directory);
+ if (custom_directory[len-1] != '/') {
+ snprintf(path, sizeof(char) * 1024 - 1, "%s/%s",custom_directory, file_name);
+ } else {
+ snprintf(path, sizeof(char) * 1024 - 1, "%s%s", custom_directory, file_name);
+ }
+ }
+ return path;
+}
+
+char ** GeoIPDBFileName = NULL;
+
+extern void _GeoIP_setup_dbfilename() {
+ if (NULL == GeoIPDBFileName) {
+ GeoIPDBFileName = malloc(sizeof(char *) * NUM_DB_TYPES);
+ memset(GeoIPDBFileName, 0, sizeof(char *) * NUM_DB_TYPES);
+
+ GeoIPDBFileName[GEOIP_COUNTRY_EDITION] = _GeoIP_full_path_to("GeoIP.dat");
+ GeoIPDBFileName[GEOIP_REGION_EDITION_REV0] = _GeoIP_full_path_to("GeoIPRegion.dat");
+ GeoIPDBFileName[GEOIP_REGION_EDITION_REV1] = _GeoIP_full_path_to("GeoIPRegion.dat");
+ GeoIPDBFileName[GEOIP_CITY_EDITION_REV0] = _GeoIP_full_path_to("GeoIPCity.dat");
+ GeoIPDBFileName[GEOIP_CITY_EDITION_REV1] = _GeoIP_full_path_to("GeoIPCity.dat");
+ GeoIPDBFileName[GEOIP_ISP_EDITION] = _GeoIP_full_path_to("GeoIPISP.dat");
+ GeoIPDBFileName[GEOIP_ORG_EDITION] = _GeoIP_full_path_to("GeoIPOrg.dat");
+ GeoIPDBFileName[GEOIP_PROXY_EDITION] = _GeoIP_full_path_to("GeoIPProxy.dat");
+ GeoIPDBFileName[GEOIP_ASNUM_EDITION] = _GeoIP_full_path_to("GeoIPASNum.dat");
+ GeoIPDBFileName[GEOIP_NETSPEED_EDITION] = _GeoIP_full_path_to("GeoIPNetSpeed.dat");
+ GeoIPDBFileName[GEOIP_DOMAIN_EDITION] = _GeoIP_full_path_to("GeoIPDomain.dat");
+ }
+}
+
+static
+int _file_exists(const char *file_name) {
+ struct stat file_stat;
+ return( (stat(file_name, &file_stat) == 0) ? 1:0);
+}
+
+int GeoIP_db_avail(int type) {
+ const char * filePath;
+ if (type < 0 || type >= NUM_DB_TYPES) {
+ return 0;
+ }
+ _GeoIP_setup_dbfilename();
+ filePath = GeoIPDBFileName[type];
+ if (NULL == filePath) {
+ return 0;
+ }
+ return _file_exists(filePath);
+}
+
+static
+void _setup_segments(GeoIP * gi) {
+ int i, j;
+ unsigned char delim[3];
+ unsigned char buf[SEGMENT_RECORD_LENGTH];
+
+ gi->databaseSegments = NULL;
+
+ /* default to GeoIP Country Edition */
+ gi->databaseType = GEOIP_COUNTRY_EDITION;
+ gi->record_length = STANDARD_RECORD_LENGTH;
+ fseek(gi->GeoIPDatabase, -3l, SEEK_END);
+ for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) {
+ fread(delim, 1, 3, gi->GeoIPDatabase);
+ if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) {
+ fread(&gi->databaseType, 1, 1, gi->GeoIPDatabase);
+ if (gi->databaseType >= 106) {
+ /* backwards compatibility with databases from April 2003 and earlier */
+ gi->databaseType -= 105;
+ }
+
+ if (gi->databaseType == GEOIP_REGION_EDITION_REV0) {
+ /* Region Edition, pre June 2003 */
+ gi->databaseSegments = malloc(sizeof(int));
+ gi->databaseSegments[0] = STATE_BEGIN_REV0;
+ } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) {
+ /* Region Edition, post June 2003 */
+ gi->databaseSegments = malloc(sizeof(int));
+ gi->databaseSegments[0] = STATE_BEGIN_REV1;
+ } else if (gi->databaseType == GEOIP_CITY_EDITION_REV0 ||
+ gi->databaseType == GEOIP_CITY_EDITION_REV1 ||
+ gi->databaseType == GEOIP_ORG_EDITION ||
+ gi->databaseType == GEOIP_ISP_EDITION ||
+ gi->databaseType == GEOIP_ASNUM_EDITION) {
+ /* City/Org Editions have two segments, read offset of second segment */
+ gi->databaseSegments = malloc(sizeof(int));
+ gi->databaseSegments[0] = 0;
+ fread(buf, SEGMENT_RECORD_LENGTH, 1, gi->GeoIPDatabase);
+ for (j = 0; j < SEGMENT_RECORD_LENGTH; j++) {
+ gi->databaseSegments[0] += (buf[j] << (j * 8));
+ }
+ if (gi->databaseType == GEOIP_ORG_EDITION ||
+ gi->databaseType == GEOIP_ISP_EDITION)
+ gi->record_length = ORG_RECORD_LENGTH;
+ }
+ break;
+ } else {
+ fseek(gi->GeoIPDatabase, -4l, SEEK_CUR);
+ }
+ }
+ if (gi->databaseType == GEOIP_COUNTRY_EDITION ||
+ gi->databaseType == GEOIP_PROXY_EDITION ||
+ gi->databaseType == GEOIP_NETSPEED_EDITION) {
+ gi->databaseSegments = malloc(sizeof(int));
+ gi->databaseSegments[0] = COUNTRY_BEGIN;
+ }
+}
+
+static
+int _check_mtime(GeoIP *gi) {
+ struct stat buf;
+ if (gi->flags & GEOIP_CHECK_CACHE) {
+ if (stat(gi->file_path, &buf) != -1) {
+ if (buf.st_mtime != gi->mtime) {
+ /* GeoIP Database file updated */
+ if (gi->flags & GEOIP_MEMORY_CACHE) {
+ /* reload database into memory cache */
+ if ((gi->cache = (unsigned char*) realloc(gi->cache, buf.st_size)) == NULL) {
+ fprintf(stderr,"Out of memory when reloading %s\n",gi->file_path);
+ return -1;
+ }
+ }
+ /* refresh filehandle */
+ fclose(gi->GeoIPDatabase);
+ gi->GeoIPDatabase = fopen(gi->file_path,"rb");
+ if (gi->GeoIPDatabase == NULL) {
+ fprintf(stderr,"Error Opening file %s when reloading\n",gi->file_path);
+ return -1;
+ }
+ gi->mtime = buf.st_mtime;
+ if (gi->flags & GEOIP_MEMORY_CACHE) {
+ if (fread(gi->cache, sizeof(unsigned char), buf.st_size, gi->GeoIPDatabase) != (size_t) buf.st_size) {
+ fprintf(stderr,"Error reading file %s when reloading\n",gi->file_path);
+ return -1;
+ }
+ }
+ if (gi->databaseSegments != NULL) {
+ free(gi->databaseSegments);
+ gi->databaseSegments = NULL;
+ }
+ _setup_segments(gi);
+ if (gi->databaseSegments == NULL) {
+ fprintf(stderr, "Error reading file %s -- corrupt\n", gi->file_path);
+ return -1;
+ }
+ if (gi->flags & GEOIP_INDEX_CACHE) {
+ gi->index_cache = (unsigned char *) realloc(gi->index_cache, sizeof(unsigned char) * ((gi->databaseSegments[0] * (long)gi->record_length * 2)));
+ if (gi->index_cache != NULL) {
+ fseek(gi->GeoIPDatabase, 0, SEEK_SET);
+ if (fread(gi->index_cache, sizeof(unsigned char), gi->databaseSegments[0] * (long)gi->record_length * 2, gi->GeoIPDatabase) != (size_t) (gi->databaseSegments[0]*(long)gi->record_length * 2)) {
+ fprintf(stderr,"Error reading file %s where reloading\n",gi->file_path);
+ return -1;
+ }
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+unsigned int _GeoIP_seek_record (GeoIP *gi, unsigned long ipnum) {
+ int depth;
+ unsigned int x;
+ unsigned char stack_buffer[2 * MAX_RECORD_LENGTH];
+ const unsigned char *buf = (gi->cache == NULL) ? stack_buffer : NULL;
+ unsigned int offset = 0;
+
+ const unsigned char * p;
+ int j;
+
+ _check_mtime(gi);
+ for (depth = 31; depth >= 0; depth--) {
+ if (gi->cache == NULL && gi->index_cache == NULL) {
+ /* read from disk */
+ fseek(gi->GeoIPDatabase, (long)gi->record_length * 2 * offset, SEEK_SET);
+ fread(stack_buffer,gi->record_length,2,gi->GeoIPDatabase);
+ } else if (gi->index_cache == NULL) {
+ /* simply point to record in memory */
+ buf = gi->cache + (long)gi->record_length * 2 *offset;
+ } else {
+ buf = gi->index_cache + (long)gi->record_length * 2 * offset;
+ }
+
+ if (ipnum & (1 << depth)) {
+ /* Take the right-hand branch */
+ if ( gi->record_length == 3 ) {
+ /* Most common case is completely unrolled and uses constants. */
+ x = (buf[3*1 + 0] << (0*8))
+ + (buf[3*1 + 1] << (1*8))
+ + (buf[3*1 + 2] << (2*8));
+
+ } else {
+ /* General case */
+ j = gi->record_length;
+ p = &buf[2*j];
+ x = 0;
+ do {
+ x <<= 8;
+ x += *(--p);
+ } while ( --j );
+ }
+
+ } else {
+ /* Take the left-hand branch */
+ if ( gi->record_length == 3 ) {
+ /* Most common case is completely unrolled and uses constants. */
+ x = (buf[3*0 + 0] << (0*8))
+ + (buf[3*0 + 1] << (1*8))
+ + (buf[3*0 + 2] << (2*8));
+ } else {
+ /* General case */
+ j = gi->record_length;
+ p = &buf[1*j];
+ x = 0;
+ do {
+ x <<= 8;
+ x += *(--p);
+ } while ( --j );
+ }
+ }
+
+ if (x >= gi->databaseSegments[0]) {
+ gi->netmask = 32 - depth;
+ return x;
+ }
+ offset = x;
+ }
+
+ /* shouldn't reach here */
+ fprintf(stderr,"Error Traversing Database for ipnum = %lu - Perhaps database is corrupt?\n",ipnum);
+ return 0;
+}
+
+unsigned long _GeoIP_addr_to_num (const char *addr) {
+ int i;
+ char tok[4];
+ int octet;
+ int j = 0, k = 0;
+ unsigned long ipnum = 0;
+ char c = 0;
+
+ for (i=0; i<4; i++) {
+ for (;;) {
+ c = addr[k++];
+ if (c == '.' || c == '\0') {
+ tok[j] = '\0';
+ octet = atoi(tok);
+ if (octet > 255)
+ return 0;
+ ipnum += (octet << ((3-i)*8));
+ j = 0;
+ break;
+ } else if (c >= '0' && c<= '9') {
+ if (j > 2) {
+ return 0;
+ }
+ tok[j++] = c;
+ } else {
+ return 0;
+ }
+ }
+ if(c == '\0' && i<3) {
+ return 0;
+ }
+ }
+ return ipnum;
+}
+
+GeoIP* GeoIP_open_type (int type, int flags) {
+ GeoIP * gi;
+ const char * filePath;
+ if (type < 0 || type >= NUM_DB_TYPES) {
+ printf("Invalid database type %d\n", type);
+ return NULL;
+ }
+ _GeoIP_setup_dbfilename();
+ filePath = GeoIPDBFileName[type];
+ if (filePath == NULL) {
+ printf("Invalid database type %d\n", type);
+ return NULL;
+ }
+ gi = GeoIP_open (filePath, flags);
+ return gi;
+}
+
+GeoIP* GeoIP_new (int flags) {
+ GeoIP * gi;
+ _GeoIP_setup_dbfilename();
+ gi = GeoIP_open (GeoIPDBFileName[GEOIP_COUNTRY_EDITION], flags);
+ return gi;
+}
+
+GeoIP* GeoIP_open (const char * filename, int flags) {
+ struct stat buf;
+ GeoIP * gi;
+ size_t len;
+
+#ifdef WIN32
+ WSADATA wsa;
+ if (WSAStartup(MAKEWORD(1, 1), &wsa) != 0)
+ return NULL;
+#endif
+
+ gi = (GeoIP *)malloc(sizeof(GeoIP));
+ if (gi == NULL)
+ return NULL;
+ len = sizeof(char) * (strlen(filename)+1);
+ gi->file_path = malloc(len);
+ if (gi->file_path == NULL) {
+ free(gi);
+ return NULL;
+ }
+ strncpy(gi->file_path, filename, len);
+ gi->GeoIPDatabase = fopen(filename,"rb");
+ if (gi->GeoIPDatabase == NULL) {
+ fprintf(stderr,"Error Opening file %s\n",filename);
+ free(gi->file_path);
+ free(gi);
+ return NULL;
+ } else {
+ if (flags & GEOIP_MEMORY_CACHE) {
+ if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) {
+ fprintf(stderr,"Error stating file %s\n",filename);
+ free(gi->file_path);
+ free(gi);
+ return NULL;
+ }
+ gi->mtime = buf.st_mtime;
+ gi->cache = (unsigned char *) malloc(sizeof(unsigned char) * buf.st_size);
+ if (gi->cache != NULL) {
+ if (fread(gi->cache, sizeof(unsigned char), buf.st_size, gi->GeoIPDatabase) != (size_t) buf.st_size) {
+ fprintf(stderr,"Error reading file %s\n",filename);
+ free(gi->cache);
+ free(gi->file_path);
+ free(gi);
+ return NULL;
+ }
+ }
+ } else {
+ if (flags & GEOIP_CHECK_CACHE) {
+ if (fstat(fileno(gi->GeoIPDatabase), &buf) == -1) {
+ fprintf(stderr,"Error stating file %s\n",filename);
+ free(gi->file_path);
+ free(gi);
+ return NULL;
+ }
+ gi->mtime = buf.st_mtime;
+ }
+ gi->cache = NULL;
+ }
+ gi->flags = flags;
+ gi->charset = GEOIP_CHARSET_ISO_8859_1;
+
+ _setup_segments(gi);
+ if (flags & GEOIP_INDEX_CACHE) {
+ gi->index_cache = (unsigned char *) malloc(sizeof(unsigned char) * ((gi->databaseSegments[0] * (long)gi->record_length * 2)));
+ if (gi->index_cache != NULL) {
+ fseek(gi->GeoIPDatabase, 0, SEEK_SET);
+ if (fread(gi->index_cache, sizeof(unsigned char), gi->databaseSegments[0] * (long)gi->record_length * 2, gi->GeoIPDatabase) != (size_t) (gi->databaseSegments[0]*(long)gi->record_length * 2)) {
+ fprintf(stderr,"Error reading file %s\n",filename);
+ free(gi->databaseSegments);
+ free(gi->index_cache);
+ free(gi);
+ return NULL;
+ }
+ }
+ } else {
+ gi->index_cache = NULL;
+ }
+ return gi;
+ }
+}
+
+void GeoIP_delete (GeoIP *gi) {
+ if (gi == NULL )
+ return;
+ if (gi->GeoIPDatabase != NULL)
+ fclose(gi->GeoIPDatabase);
+ if (gi->cache != NULL)
+ free(gi->cache);
+ if (gi->index_cache != NULL)
+ free(gi->index_cache);
+ if (gi->file_path != NULL)
+ free(gi->file_path);
+ if (gi->databaseSegments != NULL)
+ free(gi->databaseSegments);
+ free(gi);
+}
+
+const char *GeoIP_country_code_by_name (GeoIP* gi, const char *name) {
+ int country_id;
+ country_id = GeoIP_id_by_name(gi, name);
+ return (country_id > 0) ? GeoIP_country_code[country_id] : NULL;
+}
+
+const char *GeoIP_country_code3_by_name (GeoIP* gi, const char *name) {
+ int country_id;
+ country_id = GeoIP_id_by_name(gi, name);
+ return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL;
+}
+
+const char *GeoIP_country_name_by_name (GeoIP* gi, const char *name) {
+ int country_id;
+ country_id = GeoIP_id_by_name(gi, name);
+ return (country_id > 0) ? GeoIP_country_name[country_id] : NULL;
+}
+
+unsigned long _GeoIP_lookupaddress (const char *host) {
+ unsigned long addr = inet_addr(host);
+ struct hostent phe2;
+ struct hostent * phe = &phe2;
+ char *buf = NULL;
+#ifdef HAVE_GETHOSTBYNAME_R
+ int buflength = 16384;
+ int herr = 0;
+#endif
+ int result = 0;
+#ifdef HAVE_GETHOSTBYNAME_R
+ buf = malloc(buflength);
+#endif
+ if (addr == INADDR_NONE) {
+#ifdef HAVE_GETHOSTBYNAME_R
+ while (1) {
+ /* we use gethostbyname_r here because it is thread-safe and gethostbyname is not */
+#ifdef GETHOSTBYNAME_R_RETURNS_INT
+ result = gethostbyname_r(host,&phe2,buf,buflength,&phe,&herr);
+#else
+ phe = gethostbyname_r(host,&phe2,buf,buflength,&herr);
+#endif
+ if (herr != ERANGE)
+ break;
+ if (result == 0)
+ break;
+ /* double the buffer if the buffer is too small */
+ buflength = buflength * 2;
+ buf = realloc(buf,buflength);
+ }
+#endif
+#ifndef HAVE_GETHOSTBYNAME_R
+ /* Some systems do not support gethostbyname_r, such as Mac OS X */
+ phe = gethostbyname(host);
+#endif
+ if (!phe || result != 0) {
+ free(buf);
+ return 0;
+ }
+ addr = *((unsigned long *) phe->h_addr_list[0]);
+ }
+#ifdef HAVE_GETHOSTBYNAME_R
+ free(buf);
+#endif
+ return ntohl(addr);
+}
+
+int GeoIP_id_by_name (GeoIP* gi, const char *name) {
+ unsigned long ipnum;
+ int ret;
+ if (name == NULL) {
+ return 0;
+ }
+ if (gi->databaseType != GEOIP_COUNTRY_EDITION && gi->databaseType != GEOIP_PROXY_EDITION && gi->databaseType != GEOIP_NETSPEED_EDITION) {
+ printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_COUNTRY_EDITION]);
+ return 0;
+ }
+ if (!(ipnum = _GeoIP_lookupaddress(name)))
+ return 0;
+ ret = _GeoIP_seek_record(gi, ipnum) - COUNTRY_BEGIN;
+ return ret;
+
+}
+
+const char *GeoIP_country_code_by_addr (GeoIP* gi, const char *addr) {
+ int country_id;
+ country_id = GeoIP_id_by_addr(gi, addr);
+ return (country_id > 0) ? GeoIP_country_code[country_id] : NULL;
+}
+
+const char *GeoIP_country_code3_by_addr (GeoIP* gi, const char *addr) {
+ int country_id;
+ country_id = GeoIP_id_by_addr(gi, addr);
+ return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL;
+ return GeoIP_country_code3[country_id];
+}
+
+const char *GeoIP_country_name_by_addr (GeoIP* gi, const char *addr) {
+ int country_id;
+ country_id = GeoIP_id_by_addr(gi, addr);
+ return (country_id > 0) ? GeoIP_country_name[country_id] : NULL;
+ return GeoIP_country_name[country_id];
+}
+
+const char *GeoIP_country_name_by_ipnum (GeoIP* gi, unsigned long ipnum) {
+ int country_id;
+ country_id = GeoIP_id_by_ipnum(gi, ipnum);
+ return (country_id > 0) ? GeoIP_country_name[country_id] : NULL;
+}
+
+const char *GeoIP_country_code_by_ipnum (GeoIP* gi, unsigned long ipnum) {
+ int country_id;
+ country_id = GeoIP_id_by_ipnum(gi, ipnum);
+ return (country_id > 0) ? GeoIP_country_code[country_id] : NULL;
+}
+
+const char *GeoIP_country_code3_by_ipnum (GeoIP* gi, unsigned long ipnum) {
+ int country_id;
+ country_id = GeoIP_id_by_ipnum(gi, ipnum);
+ return (country_id > 0) ? GeoIP_country_code3[country_id] : NULL;
+}
+
+int GeoIP_country_id_by_addr (GeoIP* gi, const char *addr) {
+ return GeoIP_id_by_addr(gi, addr);
+}
+
+int GeoIP_country_id_by_name (GeoIP* gi, const char *host) {
+ return GeoIP_id_by_name(gi, host);
+}
+
+int GeoIP_id_by_addr (GeoIP* gi, const char *addr) {
+ unsigned long ipnum;
+ int ret;
+ if (addr == NULL) {
+ return 0;
+ }
+ if (gi->databaseType != GEOIP_COUNTRY_EDITION &&
+ gi->databaseType != GEOIP_PROXY_EDITION &&
+ gi->databaseType != GEOIP_NETSPEED_EDITION) {
+ printf("Invalid database type %s, expected %s\n",
+ GeoIPDBDescription[(int)gi->databaseType],
+ GeoIPDBDescription[GEOIP_COUNTRY_EDITION]);
+ return 0;
+ }
+ ipnum = _GeoIP_addr_to_num(addr);
+ ret = _GeoIP_seek_record(gi, ipnum) - COUNTRY_BEGIN;
+ return ret;
+}
+
+int GeoIP_id_by_ipnum (GeoIP* gi, unsigned long ipnum) {
+ int ret;
+ if (ipnum == 0) {
+ return 0;
+ }
+ if (gi->databaseType != GEOIP_COUNTRY_EDITION &&
+ gi->databaseType != GEOIP_PROXY_EDITION &&
+ gi->databaseType != GEOIP_NETSPEED_EDITION) {
+ printf("Invalid database type %s, expected %s\n",
+ GeoIPDBDescription[(int)gi->databaseType],
+ GeoIPDBDescription[GEOIP_COUNTRY_EDITION]);
+ return 0;
+ }
+ ret = _GeoIP_seek_record(gi, ipnum) - COUNTRY_BEGIN;
+ return ret;
+}
+
+char *GeoIP_database_info (GeoIP* gi) {
+ int i;
+ unsigned char buf[3];
+ char *retval;
+ int hasStructureInfo = 0;
+
+ if(gi == NULL)
+ return NULL;
+
+ _check_mtime(gi);
+ fseek(gi->GeoIPDatabase, -3l, SEEK_END);
+
+ /* first get past the database structure information */
+ for (i = 0; i < STRUCTURE_INFO_MAX_SIZE; i++) {
+ fread(buf, 1, 3, gi->GeoIPDatabase);
+ if (buf[0] == 255 && buf[1] == 255 && buf[2] == 255) {
+ hasStructureInfo = 1;
+ break;
+ }
+ fseek(gi->GeoIPDatabase, -4l, SEEK_CUR);
+ }
+ if (hasStructureInfo == 1) {
+ fseek(gi->GeoIPDatabase, -6l, SEEK_CUR);
+ } else {
+ /* no structure info, must be pre Sep 2002 database, go back to end */
+ fseek(gi->GeoIPDatabase, -3l, SEEK_END);
+ }
+
+ for (i = 0; i < DATABASE_INFO_MAX_SIZE; i++) {
+ fread(buf, 1, 3, gi->GeoIPDatabase);
+ if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0) {
+ retval = malloc(sizeof(char) * (i+1));
+ if (retval == NULL) {
+ return NULL;
+ }
+ fread(retval, 1, i, gi->GeoIPDatabase);
+ retval[i] = '\0';
+ return retval;
+ }
+ fseek(gi->GeoIPDatabase, -4l, SEEK_CUR);
+ }
+ return NULL;
+}
+
+/* GeoIP Region Edition functions */
+
+void GeoIP_assign_region_by_inetaddr(GeoIP* gi, unsigned long inetaddr, GeoIPRegion *region) {
+ unsigned int seek_region;
+
+ /* This also writes in the terminating NULs (if you decide to
+ * keep them) and clear any fields that are not set. */
+ memset(region, 0, sizeof(GeoIPRegion));
+
+ seek_region = _GeoIP_seek_record(gi, ntohl(inetaddr));
+
+ if (gi->databaseType == GEOIP_REGION_EDITION_REV0) {
+ /* Region Edition, pre June 2003 */
+ seek_region -= STATE_BEGIN_REV0;
+ if (seek_region >= 1000) {
+ region->country_code[0] = 'U';
+ region->country_code[1] = 'S';
+ region->region[0] = (char) ((seek_region - 1000)/26 + 65);
+ region->region[1] = (char) ((seek_region - 1000)%26 + 65);
+ } else {
+ memcpy(region->country_code, GeoIP_country_code[seek_region], 2);
+ }
+ } else if (gi->databaseType == GEOIP_REGION_EDITION_REV1) {
+ /* Region Edition, post June 2003 */
+ seek_region -= STATE_BEGIN_REV1;
+ if (seek_region < US_OFFSET) {
+ /* Unknown */
+ /* we don't need to do anything here b/c we memset region to 0 */
+ } else if (seek_region < CANADA_OFFSET) {
+ /* USA State */
+ region->country_code[0] = 'U';
+ region->country_code[1] = 'S';
+ region->region[0] = (char) ((seek_region - US_OFFSET)/26 + 65);
+ region->region[1] = (char) ((seek_region - US_OFFSET)%26 + 65);
+ } else if (seek_region < WORLD_OFFSET) {
+ /* Canada Province */
+ region->country_code[0] = 'C';
+ region->country_code[1] = 'A';
+ region->region[0] = (char) ((seek_region - CANADA_OFFSET)/26 + 65);
+ region->region[1] = (char) ((seek_region - CANADA_OFFSET)%26 + 65);
+ } else {
+ /* Not US or Canada */
+ memcpy(region->country_code, GeoIP_country_code[(seek_region - WORLD_OFFSET) / FIPS_RANGE], 2);
+ }
+ }
+}
+
+static
+GeoIPRegion * _get_region(GeoIP* gi, unsigned long ipnum) {
+ GeoIPRegion * region;
+
+ region = malloc(sizeof(GeoIPRegion));
+ if (region) {
+ GeoIP_assign_region_by_inetaddr(gi, htonl(ipnum), region);
+ }
+ return region;
+}
+
+GeoIPRegion * GeoIP_region_by_addr (GeoIP* gi, const char *addr) {
+ unsigned long ipnum;
+ if (addr == NULL) {
+ return 0;
+ }
+ if (gi->databaseType != GEOIP_REGION_EDITION_REV0 &&
+ gi->databaseType != GEOIP_REGION_EDITION_REV1) {
+ printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]);
+ return 0;
+ }
+ ipnum = _GeoIP_addr_to_num(addr);
+ return _get_region(gi, ipnum);
+}
+
+GeoIPRegion * GeoIP_region_by_name (GeoIP* gi, const char *name) {
+ unsigned long ipnum;
+ if (name == NULL) {
+ return 0;
+ }
+ if (gi->databaseType != GEOIP_REGION_EDITION_REV0 &&
+ gi->databaseType != GEOIP_REGION_EDITION_REV1) {
+ printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]);
+ return 0;
+ }
+ if (!(ipnum = _GeoIP_lookupaddress(name)))
+ return 0;
+ return _get_region(gi, ipnum);
+}
+
+GeoIPRegion * GeoIP_region_by_ipnum (GeoIP* gi, unsigned long ipnum) {
+ if (gi->databaseType != GEOIP_REGION_EDITION_REV0 &&
+ gi->databaseType != GEOIP_REGION_EDITION_REV1) {
+ printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_REGION_EDITION_REV1]);
+ return 0;
+ }
+ return _get_region(gi, ipnum);
+}
+
+void GeoIPRegion_delete (GeoIPRegion *gir) {
+ free(gir);
+}
+
+/* GeoIP Organization, ISP and AS Number Edition private method */
+static
+char *_get_name (GeoIP* gi, unsigned long ipnum) {
+ unsigned int seek_org;
+ char buf[MAX_ORG_RECORD_LENGTH];
+ char * org_buf, * buf_pointer;
+ int record_pointer;
+ size_t len;
+
+ if (gi->databaseType != GEOIP_ORG_EDITION &&
+ gi->databaseType != GEOIP_ISP_EDITION &&
+ gi->databaseType != GEOIP_ASNUM_EDITION) {
+ printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_ORG_EDITION]);
+ return 0;
+ }
+
+ seek_org = _GeoIP_seek_record(gi, ipnum);
+ if (seek_org == gi->databaseSegments[0])
+ return NULL;
+
+ record_pointer = seek_org + (2 * gi->record_length - 1) * gi->databaseSegments[0];
+
+ if (gi->cache == NULL) {
+ fseek(gi->GeoIPDatabase, record_pointer, SEEK_SET);
+ fread(buf, sizeof(char), MAX_ORG_RECORD_LENGTH, gi->GeoIPDatabase);
+ len = sizeof(char) * (strlen(buf)+1);
+ org_buf = malloc(len);
+ strncpy(org_buf, buf, len);
+ } else {
+ buf_pointer = (char *)gi->cache + (long)record_pointer;
+ len = sizeof(char) * (strlen(buf_pointer)+1);
+ org_buf = malloc(len);
+ strncpy(org_buf, buf_pointer, len);
+ }
+ return org_buf;
+}
+
+char *GeoIP_name_by_ipnum (GeoIP* gi, unsigned long ipnum) {
+ return _get_name(gi,ipnum);
+}
+
+char *GeoIP_name_by_addr (GeoIP* gi, const char *addr) {
+ unsigned long ipnum;
+ if (addr == NULL) {
+ return 0;
+ }
+ ipnum = _GeoIP_addr_to_num(addr);
+ return _get_name(gi, ipnum);
+}
+
+char *GeoIP_name_by_name (GeoIP* gi, const char *name) {
+ unsigned long ipnum;
+ if (name == NULL) {
+ return 0;
+ }
+ if (!(ipnum = _GeoIP_lookupaddress(name)))
+ return 0;
+ return _get_name(gi, ipnum);
+}
+
+char *GeoIP_org_by_ipnum (GeoIP* gi, unsigned long ipnum) {
+ return GeoIP_name_by_ipnum(gi, ipnum);
+}
+
+char *GeoIP_org_by_addr (GeoIP* gi, const char *addr) {
+ return GeoIP_name_by_addr(gi, addr);
+}
+
+char *GeoIP_org_by_name (GeoIP* gi, const char *name) {
+ return GeoIP_name_by_name(gi, name);
+}
+
+unsigned char GeoIP_database_edition (GeoIP* gi) {
+ return gi->databaseType;
+}
+
+int GeoIP_charset( GeoIP* gi){
+ return gi->charset;
+}
+
+int GeoIP_set_charset( GeoIP* gi, int charset ){
+ int old_charset = gi->charset;
+ gi->charset = charset;
+ return old_charset;
+}
+
+int GeoIP_last_netmask (GeoIP* gi) {
+ return gi->netmask;
+}
+
diff --git a/src/GeoIP-1.4.0/libGeoIP/GeoIP.h b/src/GeoIP-1.4.0/libGeoIP/GeoIP.h
new file mode 100644
index 0000000..edac45b
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/GeoIP.h
@@ -0,0 +1,183 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
+/* GeoIP.h
+ *
+ * Copyright (C) 2006 MaxMind LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef GEOIP_H
+#define GEOIP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include <sys/types.h> /* for fstat */
+#include <sys/stat.h> /* for fstat */
+
+#define SEGMENT_RECORD_LENGTH 3
+#define STANDARD_RECORD_LENGTH 3
+#define ORG_RECORD_LENGTH 4
+#define MAX_RECORD_LENGTH 4
+#define NUM_DB_TYPES 20
+
+typedef struct GeoIPTag {
+ FILE *GeoIPDatabase;
+ char *file_path;
+ unsigned char *cache;
+ unsigned char *index_cache;
+ unsigned int *databaseSegments;
+ char databaseType;
+ time_t mtime;
+ int flags;
+ char record_length;
+ int charset; /* 0 iso-8859-1 1 utf8 */
+ int record_iter; /* used in GeoIP_next_record */
+ int netmask; /* netmask of last lookup - set using depth in _GeoIP_seek_record */
+} GeoIP;
+
+
+typedef enum {
+ GEOIP_CHARSET_ISO_8859_1 = 0,
+ GEOIP_CHARSET_UTF8 = 1
+} GeoIPCharset;
+
+typedef struct GeoIPRegionTag {
+ char country_code[3];
+ char region[3];
+} GeoIPRegion;
+
+typedef enum {
+ GEOIP_STANDARD = 0,
+ GEOIP_MEMORY_CACHE = 1,
+ GEOIP_CHECK_CACHE = 2,
+ GEOIP_INDEX_CACHE = 4,
+} GeoIPOptions;
+
+typedef enum {
+ GEOIP_COUNTRY_EDITION = 1,
+ GEOIP_REGION_EDITION_REV0 = 7,
+ GEOIP_CITY_EDITION_REV0 = 6,
+ GEOIP_ORG_EDITION = 5,
+ GEOIP_ISP_EDITION = 4,
+ GEOIP_CITY_EDITION_REV1 = 2,
+ GEOIP_REGION_EDITION_REV1 = 3,
+ GEOIP_PROXY_EDITION = 8,
+ GEOIP_ASNUM_EDITION = 9,
+ GEOIP_NETSPEED_EDITION = 10,
+ GEOIP_DOMAIN_EDITION = 11
+} GeoIPDBTypes;
+
+typedef enum {
+ GEOIP_ANON_PROXY = 1,
+ GEOIP_HTTP_X_FORWARDED_FOR_PROXY = 2,
+ GEOIP_HTTP_CLIENT_IP_PROXY = 3,
+} GeoIPProxyTypes;
+
+typedef enum {
+ GEOIP_UNKNOWN_SPEED = 0,
+ GEOIP_DIALUP_SPEED = 1,
+ GEOIP_CABLEDSL_SPEED = 2,
+ GEOIP_CORPORATE_SPEED = 3,
+} GeoIPNetspeedValues;
+
+extern char **GeoIPDBFileName;
+extern const char * GeoIPDBDescription[NUM_DB_TYPES];
+extern const char *GeoIPCountryDBFileName;
+extern const char *GeoIPRegionDBFileName;
+extern const char *GeoIPCityDBFileName;
+extern const char *GeoIPOrgDBFileName;
+extern const char *GeoIPISPDBFileName;
+
+extern const char GeoIP_country_code[251][3];
+extern const char GeoIP_country_code3[251][4];
+extern const char * GeoIP_country_name[251];
+extern const char GeoIP_country_continent[251][3];
+
+#ifdef DLL
+#define GEOIP_API __declspec(dllexport)
+#else
+#define GEOIP_API
+#endif /* DLL */
+
+GEOIP_API void GeoIP_setup_custom_directory(char *dir);
+GEOIP_API GeoIP* GeoIP_open_type (int type, int flags);
+GEOIP_API GeoIP* GeoIP_new(int flags);
+GEOIP_API GeoIP* GeoIP_open(const char * filename, int flags);
+GEOIP_API int GeoIP_db_avail(int type);
+GEOIP_API void GeoIP_delete(GeoIP* gi);
+GEOIP_API const char *GeoIP_country_code_by_addr (GeoIP* gi, const char *addr);
+GEOIP_API const char *GeoIP_country_code_by_name (GeoIP* gi, const char *host);
+GEOIP_API const char *GeoIP_country_code3_by_addr (GeoIP* gi, const char *addr);
+GEOIP_API const char *GeoIP_country_code3_by_name (GeoIP* gi, const char *host);
+GEOIP_API const char *GeoIP_country_name_by_addr (GeoIP* gi, const char *addr);
+GEOIP_API const char *GeoIP_country_name_by_name (GeoIP* gi, const char *host);
+GEOIP_API const char *GeoIP_country_name_by_ipnum (GeoIP* gi, unsigned long ipnum);
+GEOIP_API const char *GeoIP_country_code_by_ipnum (GeoIP* gi, unsigned long ipnum);
+GEOIP_API const char *GeoIP_country_code3_by_ipnum (GeoIP* gi, unsigned long ipnum);
+
+/* Deprecated - for backwards compatibility only */
+GEOIP_API int GeoIP_country_id_by_addr (GeoIP* gi, const char *addr);
+GEOIP_API int GeoIP_country_id_by_name (GeoIP* gi, const char *host);
+GEOIP_API char *GeoIP_org_by_addr (GeoIP* gi, const char *addr);
+GEOIP_API char *GeoIP_org_by_ipnum (GeoIP* gi, unsigned long ipnum);
+GEOIP_API char *GeoIP_org_by_name (GeoIP* gi, const char *host);
+/* End deprecated */
+
+GEOIP_API int GeoIP_id_by_addr (GeoIP* gi, const char *addr);
+GEOIP_API int GeoIP_id_by_name (GeoIP* gi, const char *host);
+GEOIP_API int GeoIP_id_by_ipnum (GeoIP* gi, unsigned long ipnum);
+
+GEOIP_API GeoIPRegion * GeoIP_region_by_addr (GeoIP* gi, const char *addr);
+GEOIP_API GeoIPRegion * GeoIP_region_by_name (GeoIP* gi, const char *host);
+GEOIP_API GeoIPRegion * GeoIP_region_by_ipnum (GeoIP *gi, unsigned long ipnum);
+
+/* Warning - don't call this after GeoIP_assign_region_by_inetaddr calls */
+GEOIP_API void GeoIPRegion_delete (GeoIPRegion *gir);
+
+GEOIP_API void GeoIP_assign_region_by_inetaddr(GeoIP* gi, unsigned long inetaddr, GeoIPRegion *gir);
+
+/* Used to query GeoIP Organization, ISP and AS Number databases */
+GEOIP_API char *GeoIP_name_by_ipnum (GeoIP* gi, unsigned long ipnum);
+GEOIP_API char *GeoIP_name_by_addr (GeoIP* gi, const char *addr);
+GEOIP_API char *GeoIP_name_by_name (GeoIP* gi, const char *host);
+
+GEOIP_API char *GeoIP_database_info (GeoIP* gi);
+GEOIP_API unsigned char GeoIP_database_edition (GeoIP* gi);
+
+GEOIP_API int GeoIP_charset (GeoIP* gi);
+GEOIP_API int GeoIP_set_charset (GeoIP* gi, int charset);
+
+GEOIP_API int GeoIP_last_netmask (GeoIP* gi);
+
+/* Convert region code to region name */
+GEOIP_API const char * GeoIP_region_name_by_code(const char *country_code, const char *region_code);
+
+/* Get timezone from country and region code */
+GEOIP_API const char * GeoIP_time_zone_by_country_and_region(const char *country_code, const char *region_code);
+
+#ifdef BSD
+#define memcpy(dest, src, n) bcopy(src, dest, n)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GEOIP_H */
diff --git a/src/GeoIP-1.4.0/libGeoIP/GeoIPCity.c b/src/GeoIP-1.4.0/libGeoIP/GeoIPCity.c
new file mode 100644
index 0000000..46fcf79
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/GeoIPCity.c
@@ -0,0 +1,244 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
+/* GeoIPCity.c
+ *
+ * Copyright (C) 2006 MaxMind LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <GeoIP.h>
+#include <GeoIP_internal.h>
+#include <GeoIPCity.h>
+#ifndef WIN32
+#include <netdb.h>
+#include <netinet/in.h> /* For ntohl */
+#else
+#include <windows.h>
+#include <winsock.h>
+#endif
+#include <sys/types.h> /* For uint32_t */
+#ifdef HAVE_STDINT_H
+#include <stdint.h> /* For uint32_t */
+#endif
+
+static
+const int FULL_RECORD_LENGTH = 50;
+
+static
+GeoIPRecord * _extract_record(GeoIP* gi, unsigned int seek_record, int *next_record_ptr) {
+ int record_pointer;
+ unsigned char *record_buf = NULL;
+ unsigned char *begin_record_buf = NULL;
+ GeoIPRecord * record;
+ int str_length = 0;
+ int j;
+ double latitude = 0, longitude = 0;
+ int dmaarea_combo = 0;
+ int bytes_read = 0;
+ if (seek_record == gi->databaseSegments[0])
+ return NULL;
+
+ record = malloc(sizeof(GeoIPRecord));
+ memset(record, 0, sizeof(GeoIPRecord));
+
+ record->charset = gi->charset;
+
+ record_pointer = seek_record + (2 * gi->record_length - 1) * gi->databaseSegments[0];
+
+ if (gi->cache == NULL) {
+ fseek(gi->GeoIPDatabase, record_pointer, SEEK_SET);
+ begin_record_buf = record_buf = malloc(sizeof(char) * FULL_RECORD_LENGTH);
+ bytes_read = fread(record_buf, sizeof(char), FULL_RECORD_LENGTH, gi->GeoIPDatabase);
+ if (bytes_read == 0) {
+ /* eof or other error */
+ free(begin_record_buf);
+ free(record);
+ return NULL;
+ }
+ } else {
+ record_buf = gi->cache + (long)record_pointer;
+ }
+
+ /* get country */
+ record->continent_code = (char *) GeoIP_country_continent[record_buf[0]];
+ record->country_code = (char *) GeoIP_country_code [record_buf[0]];
+ record->country_code3 = (char *) GeoIP_country_code3[record_buf[0]];
+ record->country_name = (char *) GeoIP_country_name [record_buf[0]];
+ record_buf++;
+
+ /* get region */
+ while (record_buf[str_length] != '\0')
+ str_length++;
+ if (str_length > 0) {
+ record->region = malloc(str_length+1);
+ strncpy(record->region, (char *)record_buf, str_length+1);
+ }
+ record_buf += str_length + 1;
+ str_length = 0;
+
+ /* get city */
+ while (record_buf[str_length] != '\0')
+ str_length++;
+ if (str_length > 0) {
+ if ( gi->charset == GEOIP_CHARSET_UTF8 ) {
+ record->city = _iso_8859_1__utf8( (const char * ) record_buf );
+ } else {
+ record->city = malloc(str_length+1);
+ strncpy(record->city, ( const char * ) record_buf, str_length+1);
+ }
+ }
+ record_buf += (str_length + 1);
+ str_length = 0;
+
+ /* get postal code */
+ while (record_buf[str_length] != '\0')
+ str_length++;
+ if (str_length > 0) {
+ record->postal_code = malloc(str_length+1);
+ strncpy(record->postal_code, (char *)record_buf, str_length+1);
+ }
+ record_buf += (str_length + 1);
+
+ /* get latitude */
+for (j = 0; j < 3; ++j)
+ latitude += (record_buf[j] << (j * 8));
+ record->latitude = latitude/10000 - 180;
+ record_buf += 3;
+
+ /* get longitude */
+ for (j = 0; j < 3; ++j)
+ longitude += (record_buf[j] << (j * 8));
+ record->longitude = longitude/10000 - 180;
+
+ /* get area code and dma code for post April 2002 databases and for US locations */
+ if (GEOIP_CITY_EDITION_REV1 == gi->databaseType) {
+ if (!strcmp(record->country_code, "US")) {
+ record_buf += 3;
+ for (j = 0; j < 3; ++j)
+ dmaarea_combo += (record_buf[j] << (j * 8));
+ record->dma_code = dmaarea_combo/1000;
+ record->area_code = dmaarea_combo % 1000;
+ }
+ }
+
+ if (gi->cache == NULL)
+ free(begin_record_buf);
+
+ /* Used for GeoIP_next_record */
+ if (next_record_ptr != NULL)
+ *next_record_ptr = seek_record + record_buf - begin_record_buf + 3;
+
+ return record;
+}
+
+static
+GeoIPRecord * _get_record(GeoIP* gi, unsigned long ipnum) {
+ unsigned int seek_record;
+
+ if (gi->databaseType != GEOIP_CITY_EDITION_REV0 &&
+ gi->databaseType != GEOIP_CITY_EDITION_REV1) {
+ printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]);
+ return 0;
+ }
+
+ seek_record = _GeoIP_seek_record(gi, ipnum);
+ return _extract_record(gi, seek_record, NULL);
+}
+
+GeoIPRecord * GeoIP_record_by_ipnum (GeoIP* gi, unsigned long ipnum) {
+ return _get_record(gi, ipnum);
+}
+
+GeoIPRecord * GeoIP_record_by_addr (GeoIP* gi, const char *addr) {
+ unsigned long ipnum;
+ if (addr == NULL) {
+ return 0;
+ }
+ ipnum = _GeoIP_addr_to_num(addr);
+ return _get_record(gi, ipnum);
+}
+
+GeoIPRecord * GeoIP_record_by_name (GeoIP* gi, const char *name) {
+ unsigned long ipnum;
+ if (name == NULL) {
+ return 0;
+ }
+ ipnum = _GeoIP_lookupaddress(name);
+ return _get_record(gi, ipnum);
+}
+
+int GeoIP_record_id_by_addr (GeoIP* gi, const char *addr) {
+ unsigned long ipnum;
+ if (gi->databaseType != GEOIP_CITY_EDITION_REV0 &&
+ gi->databaseType != GEOIP_CITY_EDITION_REV1) {
+ printf("Invalid database type %s, expected %s\n", GeoIPDBDescription[(int)gi->databaseType], GeoIPDBDescription[GEOIP_CITY_EDITION_REV1]);
+ return 0;
+ }
+ if (addr == NULL) {
+ return 0;
+ }
+ ipnum = _GeoIP_addr_to_num(addr);
+ return _GeoIP_seek_record(gi, ipnum);
+}
+
+int GeoIP_init_record_iter (GeoIP* gi) {
+ return gi->databaseSegments[0] + 1;
+}
+
+int GeoIP_next_record (GeoIP* gi, GeoIPRecord **gir, int *record_iter) {
+ if (gi->cache != NULL) {
+ printf("GeoIP_next_record not supported in memory cache mode\n");
+ return 1;
+ }
+ *gir = _extract_record(gi, *record_iter, record_iter);
+ return 0;
+}
+
+void GeoIPRecord_delete (GeoIPRecord *gir) {
+ free(gir->region);
+ free(gir->city);
+ free(gir->postal_code);
+ free(gir);
+}
+
+
+
+char * _iso_8859_1__utf8(const char * iso) {
+ char c, k;
+ char * p;
+ char * t = (char *)iso;
+ int len = 0;
+ while ( ( c = *t++) ){
+ if ( c < 0 )
+ len++;
+ }
+ len += t - iso;
+ t = p = malloc( len );
+
+ if ( p ){
+ while ( ( c = *iso++ ) ) {
+ if (c < 0 ) {
+ k = 0xc2;
+ if (c >= -64 )
+ k++;
+ *t++ = k;
+ c &= ~0x40;
+ }
+ *t++ = c;
+ }
+ *t++ = 0x00;
+ }
+ return p;
+}
diff --git a/src/GeoIP-1.4.0/libGeoIP/GeoIPCity.h b/src/GeoIP-1.4.0/libGeoIP/GeoIPCity.h
new file mode 100644
index 0000000..c6ddf1b
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/GeoIPCity.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
+/* GeoIPCity.h
+ *
+ * Copyright (C) 2006 MaxMind LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef GEOIPCITY_H
+#define GEOIPCITY_H
+
+#include "GeoIP.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct GeoIPRecordTag {
+ char *country_code;
+ char *country_code3;
+ char *country_name;
+ char *region;
+ char *city;
+ char *postal_code;
+ float latitude;
+ float longitude;
+ int dma_code;
+ int area_code;
+ int charset;
+ char *continent_code;
+} GeoIPRecord;
+
+GeoIPRecord * GeoIP_record_by_ipnum (GeoIP* gi, unsigned long ipnum);
+GeoIPRecord * GeoIP_record_by_addr (GeoIP* gi, const char *addr);
+GeoIPRecord * GeoIP_record_by_name (GeoIP* gi, const char *host);
+
+int GeoIP_record_id_by_addr (GeoIP* gi, const char *addr);
+int GeoIP_init_record_iter (GeoIP* gi);
+/* returns 0 on success, 1 on failure */
+int GeoIP_next_record (GeoIP* gi, GeoIPRecord **gir, int *record_iter);
+
+void GeoIPRecord_delete (GeoIPRecord *gir);
+
+/* NULL on failure otherwise a malloced string in utf8 */
+char * _iso_8859_1__utf8(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GEOIPCITY_H */
diff --git a/src/GeoIP-1.4.0/libGeoIP/GeoIPUpdate.c b/src/GeoIP-1.4.0/libGeoIP/GeoIPUpdate.c
new file mode 100644
index 0000000..a7bec6b
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/GeoIPUpdate.c
@@ -0,0 +1,850 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
+/* GeoIPUpdate.c
+ *
+ * Copyright (C) 2006 MaxMind LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "GeoIPCity.h"
+#include "GeoIP.h"
+#include "GeoIPUpdate.h"
+#include "GeoIP_internal.h"
+
+#include "global.h"
+#include "md5.h"
+#include <sys/types.h>
+#ifndef WIN32
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#else
+#include <windows.h>
+#include <winsock.h>
+#endif
+#include <zlib.h>
+#include <time.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#define BLOCK_SIZE 1024
+
+const char *GeoIPUpdateHost = "updates.maxmind.com";
+const char *GeoIPHTTPRequest = "GET /app/update?license_key=%s&md5=%s HTTP/1.0\nHost: updates.maxmind.com\n\n";
+const char *GeoIPHTTPRequestMD5 = "GET /app/update_secure?db_md5=%s&challenge_md5=%s&user_id=%s&edition_id=%s HTTP/1.0\nHost: updates.maxmind.com\n\n";
+
+/* messages */
+const char *NoCurrentDB = "%s can't be opened, proceeding to download database\n";
+const char *MD5Info = "MD5 Digest of installed database is %s\n";
+const char *SavingGzip = "Saving gzip file to %s ... ";
+const char *WritingFile = "Writing uncompressed data to %s ...";
+
+/* TODO replace printf with GeoIP_printf - we need someway of having vargs with GeoIP_printf */
+
+const char * GeoIP_get_error_message(int i) {
+ switch (i) {
+ case GEOIP_NO_NEW_UPDATES:
+ return "no new updates";
+ case GEOIP_SUCCESS:
+ return "Success";
+ case GEOIP_LICENSE_KEY_INVALID_ERR:
+ return "License Key Invalid";
+ case GEOIP_DNS_ERR:
+ return "Unable to resolve hostname";
+ case GEOIP_NON_IPV4_ERR:
+ return "Non - IPv4 address";
+ case GEOIP_SOCKET_OPEN_ERR:
+ return "Error opening socket";
+ case GEOIP_CONNECTION_ERR:
+ return "Unable to connect";
+ case GEOIP_GZIP_IO_ERR:
+ return "Unable to write GeoIP.dat.gz file";
+ case GEOIP_TEST_IO_ERR:
+ return "Unable to write GeoIP.dat.test file";
+ case GEOIP_GZIP_READ_ERR:
+ return "Unable to read gzip data";
+ case GEOIP_OUT_OF_MEMORY_ERR:
+ return "Out of memory error";
+ case GEOIP_SOCKET_READ_ERR:
+ return "Error reading from socket, see errno";
+ case GEOIP_SANITY_OPEN_ERR:
+ return "Sanity check GeoIP_open error";
+ case GEOIP_SANITY_INFO_FAIL:
+ return "Sanity check database_info string failed";
+ case GEOIP_SANITY_LOOKUP_FAIL:
+ return "Sanity check ip address lookup failed";
+ case GEOIP_RENAME_ERR:
+ return "Rename error while installing db, check errno";
+ case GEOIP_USER_ID_INVALID_ERR:
+ return "Invalid userID";
+ case GEOIP_PRODUCT_ID_INVALID_ERR:
+ return "Invalid product ID or subscription expired";
+ case GEOIP_INVALID_SERVER_RESPONSE:
+ return "Server returned something unexpected";
+ default:
+ return "no error";
+ }
+}
+
+void GeoIP_printf(void (*f)(char *), const char *str) {
+ char * f_str;
+ size_t len = strlen(str)+1;
+ f_str = malloc(len);
+ strncpy(f_str,str,len);
+ if (f != NULL)
+ (*f)(f_str);
+ free(f_str);
+}
+
+short int GeoIP_update_database (char * license_key, int verbose, void (*f)( char *)) {
+ struct hostent *hostlist;
+ int sock;
+ char * buf;
+ struct sockaddr_in sa;
+ int offset = 0, err;
+ char * request_uri;
+ char * compr;
+ unsigned long comprLen;
+ FILE *comp_fh, *cur_db_fh, *gi_fh;
+ gzFile gz_fh;
+ char * file_path_gz, * file_path_test;
+ MD5_CONTEXT context;
+ unsigned char buffer[1024], digest[16];
+ char hex_digest[33] = "00000000000000000000000000000000\0";
+ unsigned int i;
+ char *f_str;
+ GeoIP * gi;
+ char * db_info;
+ char block[BLOCK_SIZE];
+ int block_size = BLOCK_SIZE;
+ size_t len;
+
+ _GeoIP_setup_dbfilename();
+
+ /* get MD5 of current GeoIP database file */
+ if ((cur_db_fh = fopen (GeoIPDBFileName[GEOIP_COUNTRY_EDITION], "rb")) == NULL) {
+ len = strlen(NoCurrentDB) + strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) - 1;
+ f_str = malloc(len);
+ snprintf(f_str, len, NoCurrentDB, GeoIPDBFileName[GEOIP_COUNTRY_EDITION]);
+ if (f != NULL)
+ (*f)(f_str);
+ free(f_str);
+ } else {
+ md5_init(&context);
+ while ((len = fread (buffer, 1, 1024, cur_db_fh)) > 0)
+ md5_write (&context, buffer, len);
+ md5_final (&context);
+ memcpy(digest,context.buf,16);
+ fclose (cur_db_fh);
+ for (i = 0; i < 16; i++) {
+ /*"%02x" will write 3 chars*/
+ snprintf (&hex_digest[2*i], 3, "%02x", digest[i]);
+ }
+ len = strlen(MD5Info) + strlen(hex_digest) - 1;
+ f_str = malloc(len);
+ snprintf(f_str, len, MD5Info, hex_digest);
+ if (f != NULL)
+ (*f)(f_str);
+ free(f_str);
+ }
+
+ hostlist = gethostbyname(GeoIPUpdateHost);
+
+ if (hostlist == NULL)
+ return GEOIP_DNS_ERR;
+
+ if (hostlist->h_addrtype != AF_INET)
+ return GEOIP_NON_IPV4_ERR;
+
+ if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ return GEOIP_SOCKET_OPEN_ERR;
+ }
+
+ memset(&sa, 0, sizeof(struct sockaddr_in));
+ sa.sin_port = htons(80);
+ memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length);
+ sa.sin_family = AF_INET;
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Connecting to MaxMind GeoIP Update server\n");
+
+ /* Download gzip file */
+ if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0)
+ return GEOIP_CONNECTION_ERR;
+
+ request_uri = malloc(sizeof(char) * (strlen(license_key) + strlen(GeoIPHTTPRequest)+36));
+ if (request_uri == NULL)
+ return GEOIP_OUT_OF_MEMORY_ERR;
+ sprintf(request_uri,GeoIPHTTPRequest,license_key, hex_digest);
+ send(sock, request_uri, strlen(request_uri),0);
+ free(request_uri);
+
+ buf = malloc(sizeof(char) * block_size);
+ if (buf == NULL)
+ return GEOIP_OUT_OF_MEMORY_ERR;
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Downloading gzipped GeoIP Database...\n");
+
+ for (;;) {
+ int amt;
+ amt = recv(sock, &buf[offset], block_size,0);
+ if (amt == 0) {
+ break;
+ } else if (amt == -1) {
+ free(buf);
+ return GEOIP_SOCKET_READ_ERR;
+ }
+ offset += amt;
+ buf = realloc(buf, offset+block_size);
+ if (buf == NULL)
+ return GEOIP_OUT_OF_MEMORY_ERR;
+ }
+
+ compr = strstr(buf, "\r\n\r\n") + 4;
+ comprLen = offset + buf - compr;
+
+ if (strstr(compr, "License Key Invalid") != NULL) {
+ if (verbose == 1)
+ GeoIP_printf(f,"Failed\n");
+ free(buf);
+ return GEOIP_LICENSE_KEY_INVALID_ERR;
+ } else if (strstr(compr, "No new updates available") != NULL) {
+ free(buf);
+ return GEOIP_NO_NEW_UPDATES;
+ }
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Done\n");
+
+ /* save gzip file */
+ file_path_gz = malloc(sizeof(char) * (strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) + 4));
+ if (file_path_gz == NULL)
+ return GEOIP_OUT_OF_MEMORY_ERR;
+ strcpy(file_path_gz,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]);
+ strcat(file_path_gz,".gz");
+ if (verbose == 1) {
+ len = strlen(SavingGzip) + strlen(file_path_gz) - 1;
+ f_str = malloc(len);
+ snprintf(f_str, len, SavingGzip,file_path_gz);
+ if (f != NULL)
+ (*f)(f_str);
+ free(f_str);
+ }
+ comp_fh = fopen(file_path_gz, "wb");
+
+ if(comp_fh == NULL) {
+ free(file_path_gz);
+ free(buf);
+ return GEOIP_GZIP_IO_ERR;
+ }
+
+ fwrite(compr, 1, comprLen, comp_fh);
+ fclose(comp_fh);
+ free(buf);
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Done\n");
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Uncompressing gzip file ... ");
+
+ /* uncompress gzip file */
+ gz_fh = gzopen(file_path_gz, "rb");
+ file_path_test = malloc(sizeof(char) * (strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) + 6));
+ if (file_path_test == NULL)
+ return GEOIP_OUT_OF_MEMORY_ERR;
+ strcpy(file_path_test,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]);
+ strcat(file_path_test,".test");
+ gi_fh = fopen(file_path_test, "wb");
+
+ if(gi_fh == NULL) {
+ free(file_path_test);
+ return GEOIP_TEST_IO_ERR;
+ }
+ for (;;) {
+ int amt;
+ amt = gzread(gz_fh, block, block_size);
+ if (amt == -1) {
+ free(file_path_test);
+ fclose(gi_fh);
+ gzclose(gz_fh);
+ return GEOIP_GZIP_READ_ERR;
+ }
+ if (amt == 0) {
+ break;
+ }
+ fwrite(block,1,amt,gi_fh);
+ }
+ gzclose(gz_fh);
+ unlink(file_path_gz);
+ free(file_path_gz);
+ fclose(gi_fh);
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Done\n");
+
+ if (verbose == 1) {
+ f_str = malloc(strlen(WritingFile) + strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) - 1);
+ sprintf(f_str,WritingFile,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]);
+ if (f != NULL)
+ (*f)(f_str);
+ free(f_str);
+ }
+
+ /* sanity check */
+ gi = GeoIP_open(file_path_test, GEOIP_STANDARD);
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Performing santity checks ... ");
+
+ if (gi == NULL) {
+ GeoIP_printf(f,"Error opening sanity check database\n");
+ return GEOIP_SANITY_OPEN_ERR;
+ }
+
+ /* this checks to make sure the files is complete, since info is at the end */
+ /* dependent on future databases having MaxMind in info */
+ if (verbose == 1)
+ GeoIP_printf(f,"database_info ");
+ db_info = GeoIP_database_info(gi);
+ if (db_info == NULL) {
+ GeoIP_delete(gi);
+ if (verbose == 1)
+ GeoIP_printf(f,"FAIL\n");
+ return GEOIP_SANITY_INFO_FAIL;
+ }
+ if (strstr(db_info, "MaxMind") == NULL) {
+ free(db_info);
+ GeoIP_delete(gi);
+ if (verbose == 1)
+ GeoIP_printf(f,"FAIL\n");
+ return GEOIP_SANITY_INFO_FAIL;
+ }
+ free(db_info);
+ if (verbose == 1)
+ GeoIP_printf(f,"PASS ");
+
+ /* this performs an IP lookup test of a US IP address */
+ if (verbose == 1)
+ GeoIP_printf(f,"lookup ");
+ if (strcmp(GeoIP_country_code_by_addr(gi,"24.24.24.24"), "US") != 0) {
+ GeoIP_delete(gi);
+ if (verbose == 1)
+ GeoIP_printf(f,"FAIL\n");
+ return GEOIP_SANITY_LOOKUP_FAIL;
+ }
+ GeoIP_delete(gi);
+ if (verbose == 1)
+ GeoIP_printf(f,"PASS\n");
+
+ /* install GeoIP.dat.test -> GeoIP.dat */
+ err = rename(file_path_test, GeoIPDBFileName[GEOIP_COUNTRY_EDITION]);
+ if (err != 0) {
+ GeoIP_printf(f,"GeoIP Install error while renaming file\n");
+ return GEOIP_RENAME_ERR;
+ }
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Done\n");
+
+ return 0;
+}
+
+short int GeoIP_update_database_general (char * user_id,char * license_key,char *data_base_type, int verbose,char ** client_ipaddr, void (*f)( char *)) {
+ struct hostent *hostlist;
+ int sock;
+ char * buf;
+ struct sockaddr_in sa;
+ int offset = 0, err;
+ char * request_uri;
+ char * compr;
+ unsigned long comprLen;
+ FILE *comp_fh, *cur_db_fh, *gi_fh;
+ gzFile gz_fh;
+ char * file_path_gz, * file_path_test;
+ MD5_CONTEXT context;
+ MD5_CONTEXT context2;
+ unsigned char buffer[1024], digest[16] ,digest2[16];
+ char hex_digest[33] = "0000000000000000000000000000000\0";
+ char hex_digest2[33] = "0000000000000000000000000000000\0";
+ unsigned int i;
+ char *f_str;
+ GeoIP * gi;
+ char * db_info;
+ char *ipaddress;
+ char *geoipfilename;
+ char *tmpstr;
+ int dbtype;
+ int lookupresult = 1;
+ char block[BLOCK_SIZE];
+ int block_size = BLOCK_SIZE;
+ size_t len;
+ size_t request_uri_len;
+
+ hostlist = gethostbyname(GeoIPUpdateHost);
+
+ if (hostlist == NULL)
+ return GEOIP_DNS_ERR;
+
+ if (hostlist->h_addrtype != AF_INET)
+ return GEOIP_NON_IPV4_ERR;
+ if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ return GEOIP_SOCKET_OPEN_ERR;
+ }
+
+ memset(&sa, 0, sizeof(struct sockaddr_in));
+ sa.sin_port = htons(80);
+ memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length);
+ sa.sin_family = AF_INET;
+ if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0)
+ return GEOIP_CONNECTION_ERR;
+ request_uri = malloc(sizeof(char) * (strlen(license_key) + strlen(GeoIPHTTPRequestMD5)+1036));
+ if (request_uri == NULL)
+ return GEOIP_OUT_OF_MEMORY_ERR;
+
+ /* get the file name from a web page using the product id */
+ sprintf(request_uri,"GET /app/update_getfilename?product_id=%s HTTP/1.0\nHost: %s\n\n",data_base_type,GeoIPUpdateHost);
+ if (verbose == 1) {
+ printf("sending request %s \n",request_uri);
+ }
+ send(sock, request_uri, strlen(request_uri),0); /* send the request */
+ free(request_uri);
+ buf = malloc(sizeof(char) * (block_size+4));
+ if (buf == NULL)
+ return GEOIP_OUT_OF_MEMORY_ERR;
+ offset = 0;
+ for (;;){
+ int amt;
+ amt = recv(sock, &buf[offset], block_size,0);
+ if (amt == 0){
+ break;
+ } else if (amt == -1) {
+ free(buf);
+ return GEOIP_SOCKET_READ_ERR;
+ }
+ offset += amt;
+ buf = realloc(buf, offset + block_size + 4);
+ }
+ buf[offset] = 0;
+ offset = 0;
+ tmpstr = strstr(buf, "\r\n\r\n") + 4;
+ if (tmpstr[0] == '.' || strchr(tmpstr, '/') != NULL) {
+ free(buf);
+ return GEOIP_INVALID_SERVER_RESPONSE;
+ }
+ geoipfilename = _GeoIP_full_path_to(tmpstr);
+ free(buf);
+
+ /* print the database product id and the database filename */
+ if (verbose == 1){
+ printf("database product id %s database file name %s \n",data_base_type,geoipfilename);
+ }
+ _GeoIP_setup_dbfilename();
+
+ /* get MD5 of current GeoIP database file */
+ if ((cur_db_fh = fopen (geoipfilename, "rb")) == NULL) {
+ len = strlen(NoCurrentDB) + strlen(geoipfilename) - 1;
+ f_str = malloc(len);
+ snprintf(f_str, len, NoCurrentDB, geoipfilename);
+
+ if (f != NULL)
+ (*f)(f_str);
+ free(f_str);
+ } else {
+ md5_init(&context);
+ while ((len = fread (buffer, 1, 1024, cur_db_fh)) > 0)
+ md5_write (&context, buffer, len);
+ md5_final (&context);
+ memcpy(digest,context.buf,16);
+ fclose (cur_db_fh);
+ for (i = 0; i < 16; i++)
+ sprintf (&hex_digest[2*i], "%02x", digest[i]);
+ len = strlen(MD5Info) + strlen(hex_digest) - 1;
+ f_str = malloc(len);
+ snprintf(f_str, len, MD5Info, hex_digest);
+ if (f != NULL)
+ (*f)(f_str);
+ free(f_str);
+ }
+ if (verbose == 1) {
+ printf("MD5 sum of database %s is %s \n",geoipfilename,hex_digest);
+ }
+ if (client_ipaddr[0] == NULL) {
+ /* We haven't gotten our IP address yet, so let's request it */
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ free(geoipfilename);
+ return GEOIP_SOCKET_OPEN_ERR;
+ }
+
+ memset(&sa, 0, sizeof(struct sockaddr_in));
+ sa.sin_port = htons(80);
+ memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length);
+ sa.sin_family = AF_INET;
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Connecting to MaxMind GeoIP Update server\n");
+
+ /* Download gzip file */
+ if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0) {
+ free(geoipfilename);
+ return GEOIP_CONNECTION_ERR;
+ }
+ request_uri = malloc(sizeof(char) * (strlen(license_key) + strlen(GeoIPHTTPRequestMD5)+1036));
+ if (request_uri == NULL) {
+ free(geoipfilename);
+ return GEOIP_OUT_OF_MEMORY_ERR;
+ }
+
+ /* get client ip address from MaxMind web page */
+ sprintf(request_uri,"GET /app/update_getipaddr HTTP/1.0\nHost: %s\n\n",GeoIPUpdateHost);
+ send(sock, request_uri, strlen(request_uri),0); /* send the request */
+ if (verbose == 1) {
+ printf("sending request %s", request_uri);
+ }
+ free(request_uri);
+ buf = malloc(sizeof(char) * (block_size+1));
+ if (buf == NULL) {
+ free(geoipfilename);
+ return GEOIP_OUT_OF_MEMORY_ERR;
+ }
+ offset = 0;
+
+ for (;;){
+ int amt;
+ amt = recv(sock, &buf[offset], block_size,0);
+ if (amt == 0) {
+ break;
+ } else if (amt == -1) {
+ free(buf);
+ return GEOIP_SOCKET_READ_ERR;
+ }
+ offset += amt;
+ buf = realloc(buf, offset+block_size+1);
+ }
+
+ buf[offset] = 0;
+ offset = 0;
+ ipaddress = strstr(buf, "\r\n\r\n") + 4; /* get the ip address */
+ ipaddress = malloc(strlen(strstr(buf, "\r\n\r\n") + 4)+5);
+ strcpy(ipaddress,strstr(buf, "\r\n\r\n") + 4);
+ client_ipaddr[0] = ipaddress;
+ if (verbose == 1) {
+ printf("client ip address: %s\n",ipaddress);
+ }
+ free(buf);
+ close(sock);
+ }
+
+ ipaddress = client_ipaddr[0];
+
+ /* make a md5 sum of ip address and license_key and store it in hex_digest2 */
+ request_uri_len = sizeof(char) * 2036;
+ request_uri = malloc(request_uri_len);
+ md5_init(&context2);
+ md5_write (&context2, (unsigned char *)license_key, 12); /*add license key to the md5 sum*/
+ md5_write (&context2, (unsigned char *)ipaddress, strlen(ipaddress)); /*add ip address to the md5 sum*/
+ md5_final (&context2);
+ memcpy(digest2,context2.buf,16);
+ for (i = 0; i < 16; i++)
+ snprintf (&hex_digest2[2*i], 3, "%02x", digest2[i]); /*change the digest to a hex digest*/
+ if (verbose == 1) {
+ printf("md5sum of ip address and license key is %s \n",hex_digest2);
+ }
+
+ /* send the request using the user id,product id,
+ * md5 sum of the prev database and
+ * the md5 sum of the license_key and ip address */
+ if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ return GEOIP_SOCKET_OPEN_ERR;
+ }
+ memset(&sa, 0, sizeof(struct sockaddr_in));
+ sa.sin_port = htons(80);
+ memcpy(&sa.sin_addr, hostlist->h_addr_list[0], hostlist->h_length);
+ sa.sin_family = AF_INET;
+ if (connect(sock, (struct sockaddr *)&sa, sizeof(struct sockaddr))< 0)
+ return GEOIP_CONNECTION_ERR;
+ snprintf(request_uri, request_uri_len, GeoIPHTTPRequestMD5,hex_digest,hex_digest2,user_id,data_base_type);
+ send(sock, request_uri, strlen(request_uri),0);
+ if (verbose == 1) {
+ printf("sending request %s\n",request_uri);
+ }
+
+ free(request_uri);
+
+ offset = 0;
+ buf = malloc(sizeof(char) * block_size);
+ if (buf == NULL)
+ return GEOIP_OUT_OF_MEMORY_ERR;
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Downloading gzipped GeoIP Database...\n");
+
+ for (;;) {
+ int amt;
+ amt = recv(sock, &buf[offset], block_size,0);
+
+ if (amt == 0) {
+ break;
+ } else if (amt == -1) {
+ free(buf);
+ return GEOIP_SOCKET_READ_ERR;
+ }
+ offset += amt;
+ buf = realloc(buf, offset+block_size);
+ if (buf == NULL)
+ return GEOIP_OUT_OF_MEMORY_ERR;
+ }
+
+ compr = strstr(buf, "\r\n\r\n") + 4;
+ comprLen = offset + buf - compr;
+
+ if (strstr(compr, "License Key Invalid") != NULL) {
+ if (verbose == 1)
+ GeoIP_printf(f,"Failed\n");
+ free(buf);
+ return GEOIP_LICENSE_KEY_INVALID_ERR;
+ } else if (strstr(compr, "No new updates available") != NULL) {
+ free(buf);
+ printf("%s is up to date, no updates required\n", geoipfilename);
+ return GEOIP_NO_NEW_UPDATES;
+ } else if (strstr(compr, "Invalid UserId") != NULL){
+ free(buf);
+ return GEOIP_USER_ID_INVALID_ERR;
+ } else if (strstr(compr, "Invalid product ID or subscription expired") != NULL){
+ free(buf);
+ return GEOIP_PRODUCT_ID_INVALID_ERR;
+ }
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Done\n");
+
+ printf("Updating %s\n", geoipfilename);
+
+ /* save gzip file */
+ file_path_gz = malloc(sizeof(char) * (strlen(geoipfilename) + 4));
+
+ if (file_path_gz == NULL)
+ return GEOIP_OUT_OF_MEMORY_ERR;
+ strcpy(file_path_gz,geoipfilename);
+ strcat(file_path_gz,".gz");
+ if (verbose == 1) {
+ len = strlen(SavingGzip) + strlen(file_path_gz) - 1;
+ f_str = malloc(len);
+ snprintf(f_str,len,SavingGzip,file_path_gz);
+ if (f != NULL)
+ (*f)(f_str);
+ free(f_str);
+ }
+ comp_fh = fopen(file_path_gz, "wb");
+
+ if(comp_fh == NULL) {
+ free(file_path_gz);
+ free(buf);
+ return GEOIP_GZIP_IO_ERR;
+ }
+
+ fwrite(compr, 1, comprLen, comp_fh);
+ fclose(comp_fh);
+ free(buf);
+
+ if (verbose == 1) {
+ printf("download data to a gz file named %s \n",file_path_gz);
+ }
+ if (verbose == 1)
+ GeoIP_printf(f,"Done\n");
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Uncompressing gzip file ... ");
+
+ file_path_test = malloc(sizeof(char) * (strlen(GeoIPDBFileName[GEOIP_COUNTRY_EDITION]) + 6));
+ if (file_path_test == NULL) {
+ free(file_path_gz);
+ return GEOIP_OUT_OF_MEMORY_ERR;
+ }
+ strcpy(file_path_test,GeoIPDBFileName[GEOIP_COUNTRY_EDITION]);
+ strcat(file_path_test,".test");
+ gi_fh = fopen(file_path_test, "wb");
+ if(gi_fh == NULL) {
+ free(file_path_test);
+ free(file_path_gz);
+ return GEOIP_TEST_IO_ERR;
+ }
+ /* uncompress gzip file */
+ offset = 0;
+ gz_fh = gzopen(file_path_gz, "rb");
+ for (;;) {
+ int amt;
+ amt = gzread(gz_fh, block, block_size);
+ if (amt == -1) {
+ free(file_path_gz);
+ free(file_path_test);
+ gzclose(gz_fh);
+ fclose(gi_fh);
+ return GEOIP_GZIP_READ_ERR;
+ }
+ if (amt == 0) {
+ break;
+ }
+ fwrite(block,1,amt,gi_fh);
+ }
+ gzclose(gz_fh);
+ unlink(file_path_gz);
+ free(file_path_gz);
+ fclose(gi_fh);
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Done\n");
+
+ if (verbose == 1) {
+ len = strlen(WritingFile) + strlen(geoipfilename) - 1;
+ f_str = malloc(len);
+ snprintf(f_str,len,WritingFile,geoipfilename);
+ free(f_str);
+ }
+
+ /* sanity check */
+ gi = GeoIP_open(file_path_test, GEOIP_STANDARD);
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Performing santity checks ... ");
+
+ if (gi == NULL) {
+ GeoIP_printf(f,"Error opening sanity check database\n");
+ return GEOIP_SANITY_OPEN_ERR;
+ }
+
+
+ /* get the database type */
+ dbtype = GeoIP_database_edition(gi);
+ if (verbose == 1) {
+ printf("Database type is %d\n",dbtype);
+ }
+
+ /* this checks to make sure the files is complete, since info is at the end
+ dependent on future databases having MaxMind in info (ISP and Organization databases currently don't have info string */
+
+ if ((dbtype != GEOIP_ISP_EDITION)&&
+ (dbtype != GEOIP_ORG_EDITION)) {
+ if (verbose == 1)
+ GeoIP_printf(f,"database_info ");
+ db_info = GeoIP_database_info(gi);
+ if (db_info == NULL) {
+ GeoIP_delete(gi);
+ if (verbose == 1)
+ GeoIP_printf(f,"FAIL null\n");
+ return GEOIP_SANITY_INFO_FAIL;
+ }
+ if (strstr(db_info, "MaxMind") == NULL) {
+ free(db_info);
+ GeoIP_delete(gi);
+ if (verbose == 1)
+ GeoIP_printf(f,"FAIL maxmind\n");
+ return GEOIP_SANITY_INFO_FAIL;
+ }
+ free(db_info);
+ if (verbose == 1)
+ GeoIP_printf(f,"PASS ");
+ }
+
+ /* this performs an IP lookup test of a US IP address */
+ if (verbose == 1)
+ GeoIP_printf(f,"lookup ");
+ if (dbtype == GEOIP_NETSPEED_EDITION) {
+ int netspeed = GeoIP_id_by_name(gi,"24.24.24.24");
+ lookupresult = 0;
+ if (netspeed == GEOIP_CABLEDSL_SPEED){
+ lookupresult = 1;
+ }
+ }
+ if (dbtype == GEOIP_COUNTRY_EDITION) {
+ /* if data base type is country then call the function
+ * named GeoIP_country_code_by_addr */
+ lookupresult = 1;
+ if (strcmp(GeoIP_country_code_by_addr(gi,"24.24.24.24"), "US") != 0) {
+ lookupresult = 0;
+ }
+ if (verbose == 1) {
+ GeoIP_printf(f,"testing GEOIP_COUNTRY_EDITION\n");
+ }
+ }
+ if (dbtype == GEOIP_REGION_EDITION_REV1) {
+ /* if data base type is region then call the function
+ * named GeoIP_region_by_addr */
+ GeoIPRegion *r = GeoIP_region_by_addr(gi,"24.24.24.24");
+ lookupresult = 0;
+ if (r != NULL) {
+ lookupresult = 1;
+ free(r);
+ }
+ if (verbose == 1) {
+ GeoIP_printf(f,"testing GEOIP_REGION_EDITION\n");
+ }
+ }
+ if (dbtype == GEOIP_CITY_EDITION_REV1) {
+ /* if data base type is city then call the function
+ * named GeoIP_record_by_addr */
+ GeoIPRecord *r = GeoIP_record_by_addr(gi,"24.24.24.24");
+ lookupresult = 0;
+ if (r != NULL) {
+ lookupresult = 1;
+ free(r);
+ }
+ if (verbose == 1) {
+ GeoIP_printf(f,"testing GEOIP_CITY_EDITION\n");
+ }
+ }
+ if ((dbtype == GEOIP_ISP_EDITION)||
+ (dbtype == GEOIP_ORG_EDITION)) {
+ /* if data base type is isp or org then call the function
+ * named GeoIP_org_by_addr */
+ GeoIPRecord *r = (GeoIPRecord*)GeoIP_org_by_addr(gi,"24.24.24.24");
+ lookupresult = 0;
+ if (r != NULL) {
+ lookupresult = 1;
+ free(r);
+ }
+ if (verbose == 1) {
+ if (dbtype == GEOIP_ISP_EDITION) {
+ GeoIP_printf(f,"testing GEOIP_ISP_EDITION\n");
+ }
+ if (dbtype == GEOIP_ORG_EDITION) {
+ GeoIP_printf(f,"testing GEOIP_ORG_EDITION\n");
+ }
+ }
+ }
+ if (lookupresult == 0) {
+ GeoIP_delete(gi);
+ if (verbose == 1)
+ GeoIP_printf(f,"FAIL\n");
+ return GEOIP_SANITY_LOOKUP_FAIL;
+ }
+ GeoIP_delete(gi);
+ if (verbose == 1)
+ GeoIP_printf(f,"PASS\n");
+
+ /* install GeoIP.dat.test -> GeoIP.dat */
+ err = rename(file_path_test, geoipfilename);
+ if (err != 0) {
+ GeoIP_printf(f,"GeoIP Install error while renaming file\n");
+ return GEOIP_RENAME_ERR;
+ }
+
+ if (verbose == 1)
+ GeoIP_printf(f,"Done\n");
+ free(geoipfilename);
+ return 0;
+}
diff --git a/src/GeoIP-1.4.0/libGeoIP/GeoIPUpdate.h b/src/GeoIP-1.4.0/libGeoIP/GeoIPUpdate.h
new file mode 100644
index 0000000..c39df6e
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/GeoIPUpdate.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
+/* GeoIP.h
+ *
+ * Copyright (C) 2006 MaxMind LLC
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef GEOIPUPDATE_H
+#define GEOIPUPDATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ GEOIP_NO_NEW_UPDATES = 1, /* Database up-to-date, no action taken */
+ GEOIP_SUCCESS = 0, /* Success */
+ GEOIP_LICENSE_KEY_INVALID_ERR = -1, /* License Key Invalid */
+ GEOIP_DNS_ERR = -11, /* Unable to resolve hostname */
+ GEOIP_NON_IPV4_ERR = -12, /* Non - IPv4 address */
+ GEOIP_SOCKET_OPEN_ERR = -13, /* Error opening socket */
+ GEOIP_CONNECTION_ERR = -14, /* Unable to connect */
+ GEOIP_GZIP_IO_ERR = -15, /* Unable to write GeoIP.dat.gz file */
+ GEOIP_TEST_IO_ERR = -16, /* Unable to write GeoIP.dat.test file */
+ GEOIP_GZIP_READ_ERR = -17, /* Unable to read gzip data */
+ GEOIP_OUT_OF_MEMORY_ERR = -18, /* Out of memory error */
+ GEOIP_SOCKET_READ_ERR = -19, /* Error reading from socket, see errno */
+ GEOIP_SANITY_OPEN_ERR = -20, /* Sanity check GeoIP_open error */
+ GEOIP_SANITY_INFO_FAIL = -21, /* Sanity check database_info string failed */
+ GEOIP_SANITY_LOOKUP_FAIL = -22, /* Sanity check ip address lookup failed */
+ GEOIP_RENAME_ERR = -23, /* Rename error while installing db, check errno */
+ GEOIP_USER_ID_INVALID_ERR = -24, /* Invalid userID */
+ GEOIP_PRODUCT_ID_INVALID_ERR = -25, /* Invalid product ID or subscription expired */
+ GEOIP_INVALID_SERVER_RESPONSE = -26 /* Server returned invalid response */
+} GeoIPUpdateCode;
+
+const char * GeoIP_get_error_message(int i);
+
+/* Original Update Function, just for MaxMind GeoIP Country database */
+short int GeoIP_update_database (char * license_key, int verbose, void (*f)( char *));
+
+/* More generalized update function that works more databases */
+short int GeoIP_update_database_general (char * user_id, char * license_key,char * data_base_type, int verbose,char ** client_ipaddr, void (*f)( char *));
+void GeoIP_printf(void (*f)(char *), const char *str);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GEOIPUPDATE_H */
diff --git a/src/GeoIP-1.4.0/libGeoIP/GeoIP_internal.h b/src/GeoIP-1.4.0/libGeoIP/GeoIP_internal.h
new file mode 100644
index 0000000..8ec5c95
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/GeoIP_internal.h
@@ -0,0 +1,11 @@
+#ifndef GEOIP_INTERNAL_H
+#define GEOIP_INTERNAL_H
+
+GEOIP_API unsigned int _GeoIP_seek_record (GeoIP *gi, unsigned long ipnum);
+GEOIP_API unsigned long _GeoIP_addr_to_num (const char *addr);
+
+unsigned long _GeoIP_lookupaddress (const char *host);
+extern void _GeoIP_setup_dbfilename(void);
+extern char *_GeoIP_full_path_to(const char *file_name);
+
+#endif
diff --git a/src/GeoIP-1.4.0/libGeoIP/Makefile.am b/src/GeoIP-1.4.0/libGeoIP/Makefile.am
new file mode 100644
index 0000000..fdecb0a
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/Makefile.am
@@ -0,0 +1,17 @@
+noinst_LTLIBRARIES = libGeoIP.la libGeoIPUpdate.la
+
+EXTRA_DIST = md5.h global.h types.h GeoIP_internal.h
+
+AM_CPPFLAGS = -DGEOIPDATADIR=\"$(pkgdatadir)\" -Wall
+
+if WITH_CITY
+libGeoIP_la_SOURCES = GeoIP.c GeoIPCity.c regionName.c timeZone.c
+else
+libGeoIP_la_SOURCES = GeoIP.c regionName.c timeZone.c
+endif
+
+libGeoIPUpdate_la_SOURCES = GeoIPUpdate.c md5.c
+
+#libGeoIP_la_LDFLAGS = -version-info @GEOIP_VERSION_INFO@
+
+libGeoIPUpdate_la_LIBADD = -lz libGeoIP.la
diff --git a/src/GeoIP-1.4.0/libGeoIP/global.h b/src/GeoIP-1.4.0/libGeoIP/global.h
new file mode 100644
index 0000000..22c5684
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/global.h
@@ -0,0 +1,32 @@
+/* GLOBAL.H - RSAREF types and constants
+ */
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+ function argument prototyping.
+The following makes PROTOTYPES default to 0 if it has not already
+
+ been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 0
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+/* UINT4 defines a four byte word */
+typedef unsigned long int UINT4;
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+ returns an empty list.
+ */
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else
+#define PROTO_LIST(list) ()
+#endif
+
diff --git a/src/GeoIP-1.4.0/libGeoIP/md5.c b/src/GeoIP-1.4.0/libGeoIP/md5.c
new file mode 100644
index 0000000..fc761cc
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/md5.c
@@ -0,0 +1,332 @@
+/* md5.c - MD5 Message-Digest Algorithm
+ * Copyright (C) 1995, 1996, 1998, 1999,
+ * 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ *
+ * According to the definition of MD5 in RFC 1321 from April 1992.
+ * NOTE: This is *not* the same file as the one from glibc.
+ */
+/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
+/* Heavily modified for GnuPG by <wk@gnupg.org> */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "types.h"
+
+
+#ifdef WORDS_BIGENDIAN
+#define BIG_ENDIAN_HOST
+#endif
+
+/*#define DIM(v) (sizeof(v)/sizeof((v)[0]))*/
+#define wipememory2(_ptr,_set,_len) do { volatile char *_vptr=(volatile char *)(_ptr); size_t _vlen=(_len); while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } } while(0)
+#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+
+typedef struct {
+ u32 A,B,C,D; /* chaining variables */
+ u32 nblocks;
+ byte buf[64];
+ int count;
+} MD5_CONTEXT;
+
+void md5_init( MD5_CONTEXT *ctx );
+void md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen);
+void md5_final( MD5_CONTEXT *hd );
+
+
+void
+md5_init( MD5_CONTEXT *ctx )
+{
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
+
+ ctx->nblocks = 0;
+ ctx->count = 0;
+}
+
+
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+ and defined in the RFC 1321. The first function is a little bit optimized
+ (as found in Colin Plumbs public domain implementation). */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+static void
+burn_stack (int bytes)
+{
+ char buf[128];
+
+ wipememory(buf,sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
+
+
+
+/****************
+ * transform n*64 bytes
+ */
+static void
+/*transform( MD5_CONTEXT *ctx, const void *buffer, size_t len )*/
+transform( MD5_CONTEXT *ctx, byte *data )
+{
+ u32 correct_words[16];
+ u32 A = ctx->A;
+ u32 B = ctx->B;
+ u32 C = ctx->C;
+ u32 D = ctx->D;
+ u32 *cwp = correct_words;
+
+#ifdef BIG_ENDIAN_HOST
+ { int i;
+ byte *p2, *p1;
+ for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 ) {
+ p2[3] = *p1++;
+ p2[2] = *p1++;
+ p2[1] = *p1++;
+ p2[0] = *p1++;
+ }
+ }
+#else
+ memcpy( correct_words, data, 64 );
+#endif
+
+
+#define OP(a, b, c, d, s, T) \
+ do \
+ { \
+ a += FF (b, c, d) + (*cwp++) + T; \
+ a = rol(a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* Before we start, one word about the strange constants.
+ They are defined in RFC 1321 as
+
+ T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+ */
+
+ /* Round 1. */
+ OP (A, B, C, D, 7, 0xd76aa478);
+ OP (D, A, B, C, 12, 0xe8c7b756);
+ OP (C, D, A, B, 17, 0x242070db);
+ OP (B, C, D, A, 22, 0xc1bdceee);
+ OP (A, B, C, D, 7, 0xf57c0faf);
+ OP (D, A, B, C, 12, 0x4787c62a);
+ OP (C, D, A, B, 17, 0xa8304613);
+ OP (B, C, D, A, 22, 0xfd469501);
+ OP (A, B, C, D, 7, 0x698098d8);
+ OP (D, A, B, C, 12, 0x8b44f7af);
+ OP (C, D, A, B, 17, 0xffff5bb1);
+ OP (B, C, D, A, 22, 0x895cd7be);
+ OP (A, B, C, D, 7, 0x6b901122);
+ OP (D, A, B, C, 12, 0xfd987193);
+ OP (C, D, A, B, 17, 0xa679438e);
+ OP (B, C, D, A, 22, 0x49b40821);
+
+#undef OP
+#define OP(f, a, b, c, d, k, s, T) \
+ do \
+ { \
+a += f (b, c, d) + correct_words[k] + T; \
+a = rol(a, s); \
+a += b; \
+ } \
+ while (0)
+
+ /* Round 2. */
+ OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
+ OP (FG, D, A, B, C, 6, 9, 0xc040b340);
+ OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+ OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
+ OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
+ OP (FG, D, A, B, C, 10, 9, 0x02441453);
+ OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+ OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
+ OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
+ OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
+ OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
+ OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
+ OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
+ OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
+ OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
+ OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+ /* Round 3. */
+ OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
+ OP (FH, D, A, B, C, 8, 11, 0x8771f681);
+ OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+ OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+ OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
+ OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
+ OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
+ OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+ OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
+ OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
+ OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
+ OP (FH, B, C, D, A, 6, 23, 0x04881d05);
+ OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
+ OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+ OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+ OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
+
+ /* Round 4. */
+ OP (FI, A, B, C, D, 0, 6, 0xf4292244);
+ OP (FI, D, A, B, C, 7, 10, 0x432aff97);
+ OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+ OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
+ OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
+ OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
+ OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+ OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
+ OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
+ OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+ OP (FI, C, D, A, B, 6, 15, 0xa3014314);
+ OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+ OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
+ OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+ OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
+ OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
+
+ /* Put checksum in context given as argument. */
+ ctx->A += A;
+ ctx->B += B;
+ ctx->C += C;
+ ctx->D += D;
+}
+
+
+
+/* The routine updates the message-digest context to
+ * account for the presence of each of the characters inBuf[0..inLen-1]
+ * in the message whose digest is being computed.
+ */
+void
+md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen)
+{
+ if( hd->count == 64 ) { /* flush the buffer */
+ transform( hd, hd->buf );
+ burn_stack (80+6*sizeof(void*));
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if( !inbuf )
+ return;
+ if( hd->count ) {
+ for( ; inlen && hd->count < 64; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+ md5_write( hd, NULL, 0 );
+ if( !inlen )
+ return;
+ }
+
+ while( inlen >= 64 ) {
+ transform( hd, inbuf );
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 64;
+ inbuf += 64;
+ }
+ burn_stack (80+6*sizeof(void*));
+ for( ; inlen && hd->count < 64; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+}
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD5 cycle.
+ * Returns 16 bytes representing the digest.
+ */
+
+void
+md5_final( MD5_CONTEXT *hd )
+{
+ u32 t, msb, lsb;
+ byte *p;
+
+ md5_write(hd, NULL, 0); /* flush */;
+
+ t = hd->nblocks;
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if( hd->count < 56 ) { /* enough room */
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while( hd->count < 56 )
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else { /* need one extra block */
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while( hd->count < 64 )
+ hd->buf[hd->count++] = 0;
+ md5_write(hd, NULL, 0); /* flush */;
+ memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ }
+ /* append the 64 bit count */
+ hd->buf[56] = lsb ;
+ hd->buf[57] = lsb >> 8;
+ hd->buf[58] = lsb >> 16;
+ hd->buf[59] = lsb >> 24;
+ hd->buf[60] = msb ;
+ hd->buf[61] = msb >> 8;
+ hd->buf[62] = msb >> 16;
+ hd->buf[63] = msb >> 24;
+ transform( hd, hd->buf );
+ burn_stack (80+6*sizeof(void*));
+
+ p = hd->buf;
+#ifdef BIG_ENDIAN_HOST
+#define X(a) do { *p++ = hd-> a ; *p++ = hd-> a >> 8; \
+ *p++ = hd-> a >> 16; *p++ = hd-> a >> 24; } while(0)
+#else /* little endian */
+#define X(a) do { *(u32*)p = hd-> a ; p += 4; } while(0)
+#endif
+ X(A);
+ X(B);
+ X(C);
+ X(D);
+#undef X
+
+}
+/*
+static byte *
+md5_read( MD5_CONTEXT *hd )
+{
+ return hd->buf;
+}*/
diff --git a/src/GeoIP-1.4.0/libGeoIP/md5.h b/src/GeoIP-1.4.0/libGeoIP/md5.h
new file mode 100644
index 0000000..e1607be
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/md5.h
@@ -0,0 +1,40 @@
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* MD5 context. */
+
+#include "types.h"
+
+typedef struct {
+ u32 A,B,C,D; /* chaining variables */
+ u32 nblocks;
+ byte buf[64];
+ int count;
+} MD5_CONTEXT;
+
+void md5_init( MD5_CONTEXT *ctx );
+void md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen);
+void md5_final( MD5_CONTEXT *hd );
+
diff --git a/src/GeoIP-1.4.0/libGeoIP/regionName.c b/src/GeoIP-1.4.0/libGeoIP/regionName.c
new file mode 100644
index 0000000..023137a
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/regionName.c
@@ -0,0 +1,13311 @@
+#include <string.h>
+#include <stdio.h>
+#include "GeoIP.h"
+const char * GeoIP_region_name_by_code(const char * country_code,const char * region_code) {
+ const char * name = NULL;
+ int region_code2 = -1;
+ if (region_code == NULL) { return NULL; }
+ if ((region_code[0] >= 65) & (region_code[0] < (65 + 26))) {
+ if ((region_code[1] >= 65) & (region_code[1] < (65 + 26))) {
+ if ((strcmp(country_code,"US") == 0) |
+ (strcmp(country_code,"CA") == 0)) {
+ region_code2 = ((region_code[0]-65)*26)+(region_code[1]-65);
+ }
+ }
+ if ((region_code[1] >= 48) & (region_code[1] < (48 + 10))) {
+ region_code2 = ((region_code[0]-65)*10)+(region_code[1]-48)+100;
+ }
+ }
+ if ((region_code[0] >= 48) & (region_code[0] < (48 + 10))) {
+ if ((region_code[1] >= 48) & (region_code[1] < (48 + 10))) {
+ region_code2 = ((region_code[0]-48)*10)+(region_code[1]-48);
+ }
+ }
+ if (region_code2 == -1) {return NULL;}
+ if (strcmp(country_code,"CA") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Alberta";
+ break;
+ case 28:
+ name = "British Columbia";
+ break;
+ case 313:
+ name = "Manitoba";
+ break;
+ case 339:
+ name = "New Brunswick";
+ break;
+ case 343:
+ name = "Newfoundland";
+ break;
+ case 356:
+ name = "Nova Scotia";
+ break;
+ case 358:
+ name = "Nunavut";
+ break;
+ case 377:
+ name = "Ontario";
+ break;
+ case 394:
+ name = "Prince Edward Island";
+ break;
+ case 418:
+ name = "Quebec";
+ break;
+ case 478:
+ name = "Saskatchewan";
+ break;
+ case 357:
+ name = "Northwest Territories";
+ break;
+ case 643:
+ name = "Yukon Territory";
+ break;
+ }
+ }
+ if (strcmp(country_code,"US") == 0) {
+ switch (region_code2) {
+ case 0:
+ name = "Armed Forces Americas";
+ break;
+ case 4:
+ name = "Armed Forces Europe";
+ break;
+ case 10:
+ name = "Alaska";
+ break;
+ case 11:
+ name = "Alabama";
+ break;
+ case 15:
+ name = "Armed Forces Pacific";
+ break;
+ case 17:
+ name = "Arkansas";
+ break;
+ case 18:
+ name = "American Samoa";
+ break;
+ case 25:
+ name = "Arizona";
+ break;
+ case 52:
+ name = "California";
+ break;
+ case 66:
+ name = "Colorado";
+ break;
+ case 71:
+ name = "Connecticut";
+ break;
+ case 80:
+ name = "District of Columbia";
+ break;
+ case 82:
+ name = "Delaware";
+ break;
+ case 141:
+ name = "Florida";
+ break;
+ case 142:
+ name = "Federated States of Micronesia";
+ break;
+ case 156:
+ name = "Georgia";
+ break;
+ case 176:
+ name = "Guam";
+ break;
+ case 190:
+ name = "Hawaii";
+ break;
+ case 208:
+ name = "Iowa";
+ break;
+ case 211:
+ name = "Idaho";
+ break;
+ case 219:
+ name = "Illinois";
+ break;
+ case 221:
+ name = "Indiana";
+ break;
+ case 278:
+ name = "Kansas";
+ break;
+ case 284:
+ name = "Kentucky";
+ break;
+ case 286:
+ name = "Louisiana";
+ break;
+ case 312:
+ name = "Massachusetts";
+ break;
+ case 315:
+ name = "Maryland";
+ break;
+ case 316:
+ name = "Maine";
+ break;
+ case 319:
+ name = "Marshall Islands";
+ break;
+ case 320:
+ name = "Michigan";
+ break;
+ case 325:
+ name = "Minnesota";
+ break;
+ case 326:
+ name = "Missouri";
+ break;
+ case 327:
+ name = "Northern Mariana Islands";
+ break;
+ case 330:
+ name = "Mississippi";
+ break;
+ case 331:
+ name = "Montana";
+ break;
+ case 340:
+ name = "North Carolina";
+ break;
+ case 341:
+ name = "North Dakota";
+ break;
+ case 342:
+ name = "Nebraska";
+ break;
+ case 345:
+ name = "New Hampshire";
+ break;
+ case 347:
+ name = "New Jersey";
+ break;
+ case 350:
+ name = "New Mexico";
+ break;
+ case 359:
+ name = "Nevada";
+ break;
+ case 362:
+ name = "New York";
+ break;
+ case 371:
+ name = "Ohio";
+ break;
+ case 374:
+ name = "Oklahoma";
+ break;
+ case 381:
+ name = "Oregon";
+ break;
+ case 390:
+ name = "Pennsylvania";
+ break;
+ case 407:
+ name = "Puerto Rico";
+ break;
+ case 412:
+ name = "Palau";
+ break;
+ case 450:
+ name = "Rhode Island";
+ break;
+ case 470:
+ name = "South Carolina";
+ break;
+ case 471:
+ name = "South Dakota";
+ break;
+ case 507:
+ name = "Tennessee";
+ break;
+ case 517:
+ name = "Texas";
+ break;
+ case 539:
+ name = "Utah";
+ break;
+ case 546:
+ name = "Virginia";
+ break;
+ case 554:
+ name = "Virgin Islands";
+ break;
+ case 565:
+ name = "Vermont";
+ break;
+ case 572:
+ name = "Washington";
+ break;
+ case 593:
+ name = "West Virginia";
+ break;
+ case 580:
+ name = "Wisconsin";
+ break;
+ case 596:
+ name = "Wyoming";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AD") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Canillo";
+ break;
+ case 3:
+ name = "Encamp";
+ break;
+ case 4:
+ name = "La Massana";
+ break;
+ case 5:
+ name = "Ordino";
+ break;
+ case 6:
+ name = "Sant Julia de Loria";
+ break;
+ case 7:
+ name = "Andorra la Vella";
+ break;
+ case 8:
+ name = "Escaldes-Engordany";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Abu Dhabi";
+ break;
+ case 2:
+ name = "Ajman";
+ break;
+ case 3:
+ name = "Dubai";
+ break;
+ case 4:
+ name = "Fujairah";
+ break;
+ case 5:
+ name = "Ras Al Khaimah";
+ break;
+ case 6:
+ name = "Sharjah";
+ break;
+ case 7:
+ name = "Umm Al Quwain";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AF") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Badakhshan";
+ break;
+ case 2:
+ name = "Badghis";
+ break;
+ case 3:
+ name = "Baghlan";
+ break;
+ case 5:
+ name = "Bamian";
+ break;
+ case 6:
+ name = "Farah";
+ break;
+ case 7:
+ name = "Faryab";
+ break;
+ case 8:
+ name = "Ghazni";
+ break;
+ case 9:
+ name = "Ghowr";
+ break;
+ case 10:
+ name = "Helmand";
+ break;
+ case 11:
+ name = "Herat";
+ break;
+ case 13:
+ name = "Kabol";
+ break;
+ case 14:
+ name = "Kapisa";
+ break;
+ case 15:
+ name = "Konar";
+ break;
+ case 16:
+ name = "Laghman";
+ break;
+ case 17:
+ name = "Lowgar";
+ break;
+ case 18:
+ name = "Nangarhar";
+ break;
+ case 19:
+ name = "Nimruz";
+ break;
+ case 20:
+ name = "Oruzgan";
+ break;
+ case 21:
+ name = "Paktia";
+ break;
+ case 22:
+ name = "Parvan";
+ break;
+ case 23:
+ name = "Kandahar";
+ break;
+ case 24:
+ name = "Kondoz";
+ break;
+ case 26:
+ name = "Takhar";
+ break;
+ case 27:
+ name = "Vardak";
+ break;
+ case 28:
+ name = "Zabol";
+ break;
+ case 29:
+ name = "Paktika";
+ break;
+ case 30:
+ name = "Balkh";
+ break;
+ case 31:
+ name = "Jowzjan";
+ break;
+ case 32:
+ name = "Samangan";
+ break;
+ case 33:
+ name = "Sar-e Pol";
+ break;
+ case 34:
+ name = "Konar";
+ break;
+ case 35:
+ name = "Laghman";
+ break;
+ case 36:
+ name = "Paktia";
+ break;
+ case 37:
+ name = "Khowst";
+ break;
+ case 38:
+ name = "Nurestan";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AG") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Barbuda";
+ break;
+ case 3:
+ name = "Saint George";
+ break;
+ case 4:
+ name = "Saint John";
+ break;
+ case 5:
+ name = "Saint Mary";
+ break;
+ case 6:
+ name = "Saint Paul";
+ break;
+ case 7:
+ name = "Saint Peter";
+ break;
+ case 8:
+ name = "Saint Philip";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AL") == 0) {
+ switch (region_code2) {
+ case 40:
+ name = "Berat";
+ break;
+ case 41:
+ name = "Diber";
+ break;
+ case 42:
+ name = "Durres";
+ break;
+ case 43:
+ name = "Elbasan";
+ break;
+ case 44:
+ name = "Fier";
+ break;
+ case 45:
+ name = "Gjirokaster";
+ break;
+ case 46:
+ name = "Korce";
+ break;
+ case 47:
+ name = "Kukes";
+ break;
+ case 48:
+ name = "Lezhe";
+ break;
+ case 49:
+ name = "Shkoder";
+ break;
+ case 50:
+ name = "Tirane";
+ break;
+ case 51:
+ name = "Vlore";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Aragatsotn";
+ break;
+ case 2:
+ name = "Ararat";
+ break;
+ case 3:
+ name = "Armavir";
+ break;
+ case 4:
+ name = "Geghark'unik'";
+ break;
+ case 5:
+ name = "Kotayk'";
+ break;
+ case 6:
+ name = "Lorri";
+ break;
+ case 7:
+ name = "Shirak";
+ break;
+ case 8:
+ name = "Syunik'";
+ break;
+ case 9:
+ name = "Tavush";
+ break;
+ case 10:
+ name = "Vayots' Dzor";
+ break;
+ case 11:
+ name = "Yerevan";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AO") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Benguela";
+ break;
+ case 2:
+ name = "Bie";
+ break;
+ case 3:
+ name = "Cabinda";
+ break;
+ case 4:
+ name = "Cuando Cubango";
+ break;
+ case 5:
+ name = "Cuanza Norte";
+ break;
+ case 6:
+ name = "Cuanza Sul";
+ break;
+ case 7:
+ name = "Cunene";
+ break;
+ case 8:
+ name = "Huambo";
+ break;
+ case 9:
+ name = "Huila";
+ break;
+ case 12:
+ name = "Malanje";
+ break;
+ case 14:
+ name = "Moxico";
+ break;
+ case 15:
+ name = "Uige";
+ break;
+ case 16:
+ name = "Zaire";
+ break;
+ case 17:
+ name = "Lunda Norte";
+ break;
+ case 18:
+ name = "Lunda Sul";
+ break;
+ case 19:
+ name = "Bengo";
+ break;
+ case 20:
+ name = "Luanda";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Buenos Aires";
+ break;
+ case 2:
+ name = "Catamarca";
+ break;
+ case 3:
+ name = "Chaco";
+ break;
+ case 4:
+ name = "Chubut";
+ break;
+ case 5:
+ name = "Cordoba";
+ break;
+ case 6:
+ name = "Corrientes";
+ break;
+ case 7:
+ name = "Distrito Federal";
+ break;
+ case 8:
+ name = "Entre Rios";
+ break;
+ case 9:
+ name = "Formosa";
+ break;
+ case 10:
+ name = "Jujuy";
+ break;
+ case 11:
+ name = "La Pampa";
+ break;
+ case 12:
+ name = "La Rioja";
+ break;
+ case 13:
+ name = "Mendoza";
+ break;
+ case 14:
+ name = "Misiones";
+ break;
+ case 15:
+ name = "Neuquen";
+ break;
+ case 16:
+ name = "Rio Negro";
+ break;
+ case 17:
+ name = "Salta";
+ break;
+ case 18:
+ name = "San Juan";
+ break;
+ case 19:
+ name = "San Luis";
+ break;
+ case 20:
+ name = "Santa Cruz";
+ break;
+ case 21:
+ name = "Santa Fe";
+ break;
+ case 22:
+ name = "Santiago del Estero";
+ break;
+ case 23:
+ name = "Tierra del Fuego";
+ break;
+ case 24:
+ name = "Tucuman";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AT") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Burgenland";
+ break;
+ case 2:
+ name = "Karnten";
+ break;
+ case 3:
+ name = "Niederosterreich";
+ break;
+ case 4:
+ name = "Oberosterreich";
+ break;
+ case 5:
+ name = "Salzburg";
+ break;
+ case 6:
+ name = "Steiermark";
+ break;
+ case 7:
+ name = "Tirol";
+ break;
+ case 8:
+ name = "Vorarlberg";
+ break;
+ case 9:
+ name = "Wien";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AU") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Australian Capital Territory";
+ break;
+ case 2:
+ name = "New South Wales";
+ break;
+ case 3:
+ name = "Northern Territory";
+ break;
+ case 4:
+ name = "Queensland";
+ break;
+ case 5:
+ name = "South Australia";
+ break;
+ case 6:
+ name = "Tasmania";
+ break;
+ case 7:
+ name = "Victoria";
+ break;
+ case 8:
+ name = "Western Australia";
+ break;
+ }
+ }
+ if (strcmp(country_code,"AZ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Abseron";
+ break;
+ case 2:
+ name = "Agcabadi";
+ break;
+ case 3:
+ name = "Agdam";
+ break;
+ case 4:
+ name = "Agdas";
+ break;
+ case 5:
+ name = "Agstafa";
+ break;
+ case 6:
+ name = "Agsu";
+ break;
+ case 7:
+ name = "Ali Bayramli";
+ break;
+ case 8:
+ name = "Astara";
+ break;
+ case 9:
+ name = "Baki";
+ break;
+ case 10:
+ name = "Balakan";
+ break;
+ case 11:
+ name = "Barda";
+ break;
+ case 12:
+ name = "Beylaqan";
+ break;
+ case 13:
+ name = "Bilasuvar";
+ break;
+ case 14:
+ name = "Cabrayil";
+ break;
+ case 15:
+ name = "Calilabad";
+ break;
+ case 16:
+ name = "Daskasan";
+ break;
+ case 17:
+ name = "Davaci";
+ break;
+ case 18:
+ name = "Fuzuli";
+ break;
+ case 19:
+ name = "Gadabay";
+ break;
+ case 20:
+ name = "Ganca";
+ break;
+ case 21:
+ name = "Goranboy";
+ break;
+ case 22:
+ name = "Goycay";
+ break;
+ case 23:
+ name = "Haciqabul";
+ break;
+ case 24:
+ name = "Imisli";
+ break;
+ case 25:
+ name = "Ismayilli";
+ break;
+ case 26:
+ name = "Kalbacar";
+ break;
+ case 27:
+ name = "Kurdamir";
+ break;
+ case 28:
+ name = "Lacin";
+ break;
+ case 29:
+ name = "Lankaran";
+ break;
+ case 30:
+ name = "Lankaran";
+ break;
+ case 31:
+ name = "Lerik";
+ break;
+ case 32:
+ name = "Masalli";
+ break;
+ case 33:
+ name = "Mingacevir";
+ break;
+ case 34:
+ name = "Naftalan";
+ break;
+ case 35:
+ name = "Naxcivan";
+ break;
+ case 36:
+ name = "Neftcala";
+ break;
+ case 37:
+ name = "Oguz";
+ break;
+ case 38:
+ name = "Qabala";
+ break;
+ case 39:
+ name = "Qax";
+ break;
+ case 40:
+ name = "Qazax";
+ break;
+ case 41:
+ name = "Qobustan";
+ break;
+ case 42:
+ name = "Quba";
+ break;
+ case 43:
+ name = "Qubadli";
+ break;
+ case 44:
+ name = "Qusar";
+ break;
+ case 45:
+ name = "Saatli";
+ break;
+ case 46:
+ name = "Sabirabad";
+ break;
+ case 47:
+ name = "Saki";
+ break;
+ case 48:
+ name = "Saki";
+ break;
+ case 49:
+ name = "Salyan";
+ break;
+ case 50:
+ name = "Samaxi";
+ break;
+ case 51:
+ name = "Samkir";
+ break;
+ case 52:
+ name = "Samux";
+ break;
+ case 53:
+ name = "Siyazan";
+ break;
+ case 54:
+ name = "Sumqayit";
+ break;
+ case 55:
+ name = "Susa";
+ break;
+ case 56:
+ name = "Susa";
+ break;
+ case 57:
+ name = "Tartar";
+ break;
+ case 58:
+ name = "Tovuz";
+ break;
+ case 59:
+ name = "Ucar";
+ break;
+ case 60:
+ name = "Xacmaz";
+ break;
+ case 61:
+ name = "Xankandi";
+ break;
+ case 62:
+ name = "Xanlar";
+ break;
+ case 63:
+ name = "Xizi";
+ break;
+ case 64:
+ name = "Xocali";
+ break;
+ case 65:
+ name = "Xocavand";
+ break;
+ case 66:
+ name = "Yardimli";
+ break;
+ case 67:
+ name = "Yevlax";
+ break;
+ case 68:
+ name = "Yevlax";
+ break;
+ case 69:
+ name = "Zangilan";
+ break;
+ case 70:
+ name = "Zaqatala";
+ break;
+ case 71:
+ name = "Zardab";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BA") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Federation of Bosnia and Herzegovina";
+ break;
+ case 2:
+ name = "Republika Srpska";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BB") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Christ Church";
+ break;
+ case 2:
+ name = "Saint Andrew";
+ break;
+ case 3:
+ name = "Saint George";
+ break;
+ case 4:
+ name = "Saint James";
+ break;
+ case 5:
+ name = "Saint John";
+ break;
+ case 6:
+ name = "Saint Joseph";
+ break;
+ case 7:
+ name = "Saint Lucy";
+ break;
+ case 8:
+ name = "Saint Michael";
+ break;
+ case 9:
+ name = "Saint Peter";
+ break;
+ case 10:
+ name = "Saint Philip";
+ break;
+ case 11:
+ name = "Saint Thomas";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BD") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Barisal";
+ break;
+ case 4:
+ name = "Bandarban";
+ break;
+ case 5:
+ name = "Comilla";
+ break;
+ case 12:
+ name = "Mymensingh";
+ break;
+ case 13:
+ name = "Noakhali";
+ break;
+ case 15:
+ name = "Patuakhali";
+ break;
+ case 22:
+ name = "Bagerhat";
+ break;
+ case 23:
+ name = "Bhola";
+ break;
+ case 24:
+ name = "Bogra";
+ break;
+ case 25:
+ name = "Barguna";
+ break;
+ case 26:
+ name = "Brahmanbaria";
+ break;
+ case 27:
+ name = "Chandpur";
+ break;
+ case 28:
+ name = "Chapai Nawabganj";
+ break;
+ case 29:
+ name = "Chattagram";
+ break;
+ case 30:
+ name = "Chuadanga";
+ break;
+ case 31:
+ name = "Cox's Bazar";
+ break;
+ case 32:
+ name = "Dhaka";
+ break;
+ case 33:
+ name = "Dinajpur";
+ break;
+ case 34:
+ name = "Faridpur";
+ break;
+ case 35:
+ name = "Feni";
+ break;
+ case 36:
+ name = "Gaibandha";
+ break;
+ case 37:
+ name = "Gazipur";
+ break;
+ case 38:
+ name = "Gopalganj";
+ break;
+ case 39:
+ name = "Habiganj";
+ break;
+ case 40:
+ name = "Jaipurhat";
+ break;
+ case 41:
+ name = "Jamalpur";
+ break;
+ case 42:
+ name = "Jessore";
+ break;
+ case 43:
+ name = "Jhalakati";
+ break;
+ case 44:
+ name = "Jhenaidah";
+ break;
+ case 45:
+ name = "Khagrachari";
+ break;
+ case 46:
+ name = "Khulna";
+ break;
+ case 47:
+ name = "Kishorganj";
+ break;
+ case 48:
+ name = "Kurigram";
+ break;
+ case 49:
+ name = "Kushtia";
+ break;
+ case 50:
+ name = "Laksmipur";
+ break;
+ case 51:
+ name = "Lalmonirhat";
+ break;
+ case 52:
+ name = "Madaripur";
+ break;
+ case 53:
+ name = "Magura";
+ break;
+ case 54:
+ name = "Manikganj";
+ break;
+ case 55:
+ name = "Meherpur";
+ break;
+ case 56:
+ name = "Moulavibazar";
+ break;
+ case 57:
+ name = "Munshiganj";
+ break;
+ case 58:
+ name = "Naogaon";
+ break;
+ case 59:
+ name = "Narail";
+ break;
+ case 60:
+ name = "Narayanganj";
+ break;
+ case 61:
+ name = "Narsingdi";
+ break;
+ case 62:
+ name = "Nator";
+ break;
+ case 63:
+ name = "Netrakona";
+ break;
+ case 64:
+ name = "Nilphamari";
+ break;
+ case 65:
+ name = "Pabna";
+ break;
+ case 66:
+ name = "Panchagar";
+ break;
+ case 67:
+ name = "Parbattya Chattagram";
+ break;
+ case 68:
+ name = "Pirojpur";
+ break;
+ case 69:
+ name = "Rajbari";
+ break;
+ case 70:
+ name = "Rajshahi";
+ break;
+ case 71:
+ name = "Rangpur";
+ break;
+ case 72:
+ name = "Satkhira";
+ break;
+ case 73:
+ name = "Shariyatpur";
+ break;
+ case 74:
+ name = "Sherpur";
+ break;
+ case 75:
+ name = "Sirajganj";
+ break;
+ case 76:
+ name = "Sunamganj";
+ break;
+ case 77:
+ name = "Sylhet";
+ break;
+ case 78:
+ name = "Tangail";
+ break;
+ case 79:
+ name = "Thakurgaon";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Antwerpen";
+ break;
+ case 2:
+ name = "Brabant";
+ break;
+ case 3:
+ name = "Hainaut";
+ break;
+ case 4:
+ name = "Liege";
+ break;
+ case 5:
+ name = "Limburg";
+ break;
+ case 6:
+ name = "Luxembourg";
+ break;
+ case 7:
+ name = "Namur";
+ break;
+ case 8:
+ name = "Oost-Vlaanderen";
+ break;
+ case 9:
+ name = "West-Vlaanderen";
+ break;
+ case 10:
+ name = "Brabant Wallon";
+ break;
+ case 11:
+ name = "Brussels Hoofdstedelijk Gewest";
+ break;
+ case 12:
+ name = "Vlaams-Brabant";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BF") == 0) {
+ switch (region_code2) {
+ case 15:
+ name = "Bam";
+ break;
+ case 19:
+ name = "Boulkiemde";
+ break;
+ case 20:
+ name = "Ganzourgou";
+ break;
+ case 21:
+ name = "Gnagna";
+ break;
+ case 28:
+ name = "Kouritenga";
+ break;
+ case 33:
+ name = "Oudalan";
+ break;
+ case 34:
+ name = "Passore";
+ break;
+ case 36:
+ name = "Sanguie";
+ break;
+ case 40:
+ name = "Soum";
+ break;
+ case 42:
+ name = "Tapoa";
+ break;
+ case 44:
+ name = "Zoundweogo";
+ break;
+ case 45:
+ name = "Bale";
+ break;
+ case 46:
+ name = "Banwa";
+ break;
+ case 47:
+ name = "Bazega";
+ break;
+ case 48:
+ name = "Bougouriba";
+ break;
+ case 49:
+ name = "Boulgou";
+ break;
+ case 50:
+ name = "Gourma";
+ break;
+ case 51:
+ name = "Houet";
+ break;
+ case 52:
+ name = "Ioba";
+ break;
+ case 53:
+ name = "Kadiogo";
+ break;
+ case 54:
+ name = "Kenedougou";
+ break;
+ case 55:
+ name = "Komoe";
+ break;
+ case 56:
+ name = "Komondjari";
+ break;
+ case 57:
+ name = "Kompienga";
+ break;
+ case 58:
+ name = "Kossi";
+ break;
+ case 59:
+ name = "Koulpelogo";
+ break;
+ case 60:
+ name = "Kourweogo";
+ break;
+ case 61:
+ name = "Leraba";
+ break;
+ case 62:
+ name = "Loroum";
+ break;
+ case 63:
+ name = "Mouhoun";
+ break;
+ case 64:
+ name = "Namentenga";
+ break;
+ case 65:
+ name = "Naouri";
+ break;
+ case 66:
+ name = "Nayala";
+ break;
+ case 67:
+ name = "Noumbiel";
+ break;
+ case 68:
+ name = "Oubritenga";
+ break;
+ case 69:
+ name = "Poni";
+ break;
+ case 70:
+ name = "Sanmatenga";
+ break;
+ case 71:
+ name = "Seno";
+ break;
+ case 72:
+ name = "Sissili";
+ break;
+ case 73:
+ name = "Sourou";
+ break;
+ case 74:
+ name = "Tuy";
+ break;
+ case 75:
+ name = "Yagha";
+ break;
+ case 76:
+ name = "Yatenga";
+ break;
+ case 77:
+ name = "Ziro";
+ break;
+ case 78:
+ name = "Zondoma";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BG") == 0) {
+ switch (region_code2) {
+ case 33:
+ name = "Mikhaylovgrad";
+ break;
+ case 38:
+ name = "Blagoevgrad";
+ break;
+ case 39:
+ name = "Burgas";
+ break;
+ case 40:
+ name = "Dobrich";
+ break;
+ case 41:
+ name = "Gabrovo";
+ break;
+ case 42:
+ name = "Grad Sofiya";
+ break;
+ case 43:
+ name = "Khaskovo";
+ break;
+ case 44:
+ name = "Kurdzhali";
+ break;
+ case 45:
+ name = "Kyustendil";
+ break;
+ case 46:
+ name = "Lovech";
+ break;
+ case 47:
+ name = "Montana";
+ break;
+ case 48:
+ name = "Pazardzhik";
+ break;
+ case 49:
+ name = "Pernik";
+ break;
+ case 50:
+ name = "Pleven";
+ break;
+ case 51:
+ name = "Plovdiv";
+ break;
+ case 52:
+ name = "Razgrad";
+ break;
+ case 53:
+ name = "Ruse";
+ break;
+ case 54:
+ name = "Shumen";
+ break;
+ case 55:
+ name = "Silistra";
+ break;
+ case 56:
+ name = "Sliven";
+ break;
+ case 57:
+ name = "Smolyan";
+ break;
+ case 58:
+ name = "Sofiya";
+ break;
+ case 59:
+ name = "Stara Zagora";
+ break;
+ case 60:
+ name = "Turgovishte";
+ break;
+ case 61:
+ name = "Varna";
+ break;
+ case 62:
+ name = "Veliko Turnovo";
+ break;
+ case 63:
+ name = "Vidin";
+ break;
+ case 64:
+ name = "Vratsa";
+ break;
+ case 65:
+ name = "Yambol";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BH") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Al Hadd";
+ break;
+ case 2:
+ name = "Al Manamah";
+ break;
+ case 3:
+ name = "Al Muharraq";
+ break;
+ case 5:
+ name = "Jidd Hafs";
+ break;
+ case 6:
+ name = "Sitrah";
+ break;
+ case 8:
+ name = "Al Mintaqah al Gharbiyah";
+ break;
+ case 9:
+ name = "Mintaqat Juzur Hawar";
+ break;
+ case 10:
+ name = "Al Mintaqah ash Shamaliyah";
+ break;
+ case 11:
+ name = "Al Mintaqah al Wusta";
+ break;
+ case 12:
+ name = "Madinat";
+ break;
+ case 13:
+ name = "Ar Rifa";
+ break;
+ case 14:
+ name = "Madinat Hamad";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BI") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Bujumbura";
+ break;
+ case 9:
+ name = "Bubanza";
+ break;
+ case 10:
+ name = "Bururi";
+ break;
+ case 11:
+ name = "Cankuzo";
+ break;
+ case 12:
+ name = "Cibitoke";
+ break;
+ case 13:
+ name = "Gitega";
+ break;
+ case 14:
+ name = "Karuzi";
+ break;
+ case 15:
+ name = "Kayanza";
+ break;
+ case 16:
+ name = "Kirundo";
+ break;
+ case 17:
+ name = "Makamba";
+ break;
+ case 18:
+ name = "Muyinga";
+ break;
+ case 19:
+ name = "Ngozi";
+ break;
+ case 20:
+ name = "Rutana";
+ break;
+ case 21:
+ name = "Ruyigi";
+ break;
+ case 22:
+ name = "Muramvya";
+ break;
+ case 23:
+ name = "Mwaro";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BJ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Atakora";
+ break;
+ case 2:
+ name = "Atlantique";
+ break;
+ case 3:
+ name = "Borgou";
+ break;
+ case 4:
+ name = "Mono";
+ break;
+ case 5:
+ name = "Oueme";
+ break;
+ case 6:
+ name = "Zou";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Devonshire";
+ break;
+ case 2:
+ name = "Hamilton";
+ break;
+ case 3:
+ name = "Hamilton";
+ break;
+ case 4:
+ name = "Paget";
+ break;
+ case 5:
+ name = "Pembroke";
+ break;
+ case 6:
+ name = "Saint George";
+ break;
+ case 7:
+ name = "Saint George's";
+ break;
+ case 8:
+ name = "Sandys";
+ break;
+ case 9:
+ name = "Smiths";
+ break;
+ case 10:
+ name = "Southampton";
+ break;
+ case 11:
+ name = "Warwick";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BN") == 0) {
+ switch (region_code2) {
+ case 7:
+ name = "Alibori";
+ break;
+ case 8:
+ name = "Belait";
+ break;
+ case 9:
+ name = "Brunei and Muara";
+ break;
+ case 10:
+ name = "Temburong";
+ break;
+ case 11:
+ name = "Collines";
+ break;
+ case 12:
+ name = "Kouffo";
+ break;
+ case 13:
+ name = "Donga";
+ break;
+ case 14:
+ name = "Littoral";
+ break;
+ case 15:
+ name = "Tutong";
+ break;
+ case 16:
+ name = "Oueme";
+ break;
+ case 17:
+ name = "Plateau";
+ break;
+ case 18:
+ name = "Zou";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BO") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Chuquisaca";
+ break;
+ case 2:
+ name = "Cochabamba";
+ break;
+ case 3:
+ name = "El Beni";
+ break;
+ case 4:
+ name = "La Paz";
+ break;
+ case 5:
+ name = "Oruro";
+ break;
+ case 6:
+ name = "Pando";
+ break;
+ case 7:
+ name = "Potosi";
+ break;
+ case 8:
+ name = "Santa Cruz";
+ break;
+ case 9:
+ name = "Tarija";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Acre";
+ break;
+ case 2:
+ name = "Alagoas";
+ break;
+ case 3:
+ name = "Amapa";
+ break;
+ case 4:
+ name = "Amazonas";
+ break;
+ case 5:
+ name = "Bahia";
+ break;
+ case 6:
+ name = "Ceara";
+ break;
+ case 7:
+ name = "Distrito Federal";
+ break;
+ case 8:
+ name = "Espirito Santo";
+ break;
+ case 11:
+ name = "Mato Grosso do Sul";
+ break;
+ case 13:
+ name = "Maranhao";
+ break;
+ case 14:
+ name = "Mato Grosso";
+ break;
+ case 15:
+ name = "Minas Gerais";
+ break;
+ case 16:
+ name = "Para";
+ break;
+ case 17:
+ name = "Paraiba";
+ break;
+ case 18:
+ name = "Parana";
+ break;
+ case 20:
+ name = "Piaui";
+ break;
+ case 21:
+ name = "Rio de Janeiro";
+ break;
+ case 22:
+ name = "Rio Grande do Norte";
+ break;
+ case 23:
+ name = "Rio Grande do Sul";
+ break;
+ case 24:
+ name = "Rondonia";
+ break;
+ case 25:
+ name = "Roraima";
+ break;
+ case 26:
+ name = "Santa Catarina";
+ break;
+ case 27:
+ name = "Sao Paulo";
+ break;
+ case 28:
+ name = "Sergipe";
+ break;
+ case 29:
+ name = "Goias";
+ break;
+ case 30:
+ name = "Pernambuco";
+ break;
+ case 31:
+ name = "Tocantins";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BS") == 0) {
+ switch (region_code2) {
+ case 5:
+ name = "Bimini";
+ break;
+ case 6:
+ name = "Cat Island";
+ break;
+ case 10:
+ name = "Exuma";
+ break;
+ case 13:
+ name = "Inagua";
+ break;
+ case 15:
+ name = "Long Island";
+ break;
+ case 16:
+ name = "Mayaguana";
+ break;
+ case 18:
+ name = "Ragged Island";
+ break;
+ case 22:
+ name = "Harbour Island";
+ break;
+ case 23:
+ name = "New Providence";
+ break;
+ case 24:
+ name = "Acklins and Crooked Islands";
+ break;
+ case 25:
+ name = "Freeport";
+ break;
+ case 26:
+ name = "Fresh Creek";
+ break;
+ case 27:
+ name = "Governor's Harbour";
+ break;
+ case 28:
+ name = "Green Turtle Cay";
+ break;
+ case 29:
+ name = "High Rock";
+ break;
+ case 30:
+ name = "Kemps Bay";
+ break;
+ case 31:
+ name = "Marsh Harbour";
+ break;
+ case 32:
+ name = "Nichollstown and Berry Islands";
+ break;
+ case 33:
+ name = "Rock Sound";
+ break;
+ case 34:
+ name = "Sandy Point";
+ break;
+ case 35:
+ name = "San Salvador and Rum Cay";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BT") == 0) {
+ switch (region_code2) {
+ case 5:
+ name = "Bumthang";
+ break;
+ case 6:
+ name = "Chhukha";
+ break;
+ case 7:
+ name = "Chirang";
+ break;
+ case 8:
+ name = "Daga";
+ break;
+ case 9:
+ name = "Geylegphug";
+ break;
+ case 10:
+ name = "Ha";
+ break;
+ case 11:
+ name = "Lhuntshi";
+ break;
+ case 12:
+ name = "Mongar";
+ break;
+ case 13:
+ name = "Paro";
+ break;
+ case 14:
+ name = "Pemagatsel";
+ break;
+ case 15:
+ name = "Punakha";
+ break;
+ case 16:
+ name = "Samchi";
+ break;
+ case 17:
+ name = "Samdrup";
+ break;
+ case 18:
+ name = "Shemgang";
+ break;
+ case 19:
+ name = "Tashigang";
+ break;
+ case 20:
+ name = "Thimphu";
+ break;
+ case 21:
+ name = "Tongsa";
+ break;
+ case 22:
+ name = "Wangdi Phodrang";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BW") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Central";
+ break;
+ case 2:
+ name = "Chobe";
+ break;
+ case 3:
+ name = "Ghanzi";
+ break;
+ case 4:
+ name = "Kgalagadi";
+ break;
+ case 5:
+ name = "Kgatleng";
+ break;
+ case 6:
+ name = "Kweneng";
+ break;
+ case 7:
+ name = "Ngamiland";
+ break;
+ case 8:
+ name = "North-East";
+ break;
+ case 9:
+ name = "South-East";
+ break;
+ case 10:
+ name = "Southern";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BY") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Brestskaya Voblasts'";
+ break;
+ case 2:
+ name = "Homyel'skaya Voblasts'";
+ break;
+ case 3:
+ name = "Hrodzyenskaya Voblasts'";
+ break;
+ case 4:
+ name = "Minsk";
+ break;
+ case 5:
+ name = "Minskaya Voblasts'";
+ break;
+ case 6:
+ name = "Mahilyowskaya Voblasts'";
+ break;
+ case 7:
+ name = "Vitsyebskaya Voblasts'";
+ break;
+ }
+ }
+ if (strcmp(country_code,"BZ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Belize";
+ break;
+ case 2:
+ name = "Cayo";
+ break;
+ case 3:
+ name = "Corozal";
+ break;
+ case 4:
+ name = "Orange Walk";
+ break;
+ case 5:
+ name = "Stann Creek";
+ break;
+ case 6:
+ name = "Toledo";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CF") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bamingui-Bangoran";
+ break;
+ case 2:
+ name = "Basse-Kotto";
+ break;
+ case 3:
+ name = "Haute-Kotto";
+ break;
+ case 4:
+ name = "Mambere-Kadei";
+ break;
+ case 5:
+ name = "Haut-Mbomou";
+ break;
+ case 6:
+ name = "Kemo";
+ break;
+ case 7:
+ name = "Lobaye";
+ break;
+ case 8:
+ name = "Mbomou";
+ break;
+ case 9:
+ name = "Nana-Mambere";
+ break;
+ case 11:
+ name = "Ouaka";
+ break;
+ case 12:
+ name = "Ouham";
+ break;
+ case 13:
+ name = "Ouham-Pende";
+ break;
+ case 14:
+ name = "Vakaga";
+ break;
+ case 15:
+ name = "Nana-Grebizi";
+ break;
+ case 16:
+ name = "Sangha-Mbaere";
+ break;
+ case 17:
+ name = "Ombella-Mpoko";
+ break;
+ case 18:
+ name = "Bangui";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CG") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bouenza";
+ break;
+ case 3:
+ name = "Cuvette";
+ break;
+ case 4:
+ name = "Kouilou";
+ break;
+ case 5:
+ name = "Lekoumou";
+ break;
+ case 6:
+ name = "Likouala";
+ break;
+ case 7:
+ name = "Niari";
+ break;
+ case 8:
+ name = "Plateaux";
+ break;
+ case 10:
+ name = "Sangha";
+ break;
+ case 11:
+ name = "Pool";
+ break;
+ case 12:
+ name = "Brazzaville";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CH") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Aargau";
+ break;
+ case 2:
+ name = "Ausser-Rhoden";
+ break;
+ case 3:
+ name = "Basel-Landschaft";
+ break;
+ case 4:
+ name = "Basel-Stadt";
+ break;
+ case 5:
+ name = "Bern";
+ break;
+ case 6:
+ name = "Fribourg";
+ break;
+ case 7:
+ name = "Geneve";
+ break;
+ case 8:
+ name = "Glarus";
+ break;
+ case 9:
+ name = "Graubunden";
+ break;
+ case 10:
+ name = "Inner-Rhoden";
+ break;
+ case 11:
+ name = "Luzern";
+ break;
+ case 12:
+ name = "Neuchatel";
+ break;
+ case 13:
+ name = "Nidwalden";
+ break;
+ case 14:
+ name = "Obwalden";
+ break;
+ case 15:
+ name = "Sankt Gallen";
+ break;
+ case 16:
+ name = "Schaffhausen";
+ break;
+ case 17:
+ name = "Schwyz";
+ break;
+ case 18:
+ name = "Solothurn";
+ break;
+ case 19:
+ name = "Thurgau";
+ break;
+ case 20:
+ name = "Ticino";
+ break;
+ case 21:
+ name = "Uri";
+ break;
+ case 22:
+ name = "Valais";
+ break;
+ case 23:
+ name = "Vaud";
+ break;
+ case 24:
+ name = "Zug";
+ break;
+ case 25:
+ name = "Zurich";
+ break;
+ case 26:
+ name = "Jura";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CI") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Abengourou";
+ break;
+ case 3:
+ name = "Dabakala";
+ break;
+ case 5:
+ name = "Adzope";
+ break;
+ case 6:
+ name = "Agboville";
+ break;
+ case 7:
+ name = "Biankouma";
+ break;
+ case 11:
+ name = "Bouna";
+ break;
+ case 12:
+ name = "Boundiali";
+ break;
+ case 14:
+ name = "Danane";
+ break;
+ case 16:
+ name = "Divo";
+ break;
+ case 17:
+ name = "Ferkessedougou";
+ break;
+ case 18:
+ name = "Gagnoa";
+ break;
+ case 20:
+ name = "Katiola";
+ break;
+ case 21:
+ name = "Korhogo";
+ break;
+ case 23:
+ name = "Odienne";
+ break;
+ case 25:
+ name = "Seguela";
+ break;
+ case 26:
+ name = "Touba";
+ break;
+ case 27:
+ name = "Bongouanou";
+ break;
+ case 28:
+ name = "Issia";
+ break;
+ case 29:
+ name = "Lakota";
+ break;
+ case 30:
+ name = "Mankono";
+ break;
+ case 31:
+ name = "Oume";
+ break;
+ case 32:
+ name = "Soubre";
+ break;
+ case 33:
+ name = "Tingrela";
+ break;
+ case 34:
+ name = "Zuenoula";
+ break;
+ case 36:
+ name = "Bangolo";
+ break;
+ case 37:
+ name = "Beoumi";
+ break;
+ case 38:
+ name = "Bondoukou";
+ break;
+ case 39:
+ name = "Bouafle";
+ break;
+ case 40:
+ name = "Bouake";
+ break;
+ case 41:
+ name = "Daloa";
+ break;
+ case 42:
+ name = "Daoukro";
+ break;
+ case 44:
+ name = "Duekoue";
+ break;
+ case 45:
+ name = "Grand-Lahou";
+ break;
+ case 47:
+ name = "Man";
+ break;
+ case 48:
+ name = "Mbahiakro";
+ break;
+ case 49:
+ name = "Sakassou";
+ break;
+ case 50:
+ name = "San Pedro";
+ break;
+ case 51:
+ name = "Sassandra";
+ break;
+ case 52:
+ name = "Sinfra";
+ break;
+ case 53:
+ name = "Tabou";
+ break;
+ case 54:
+ name = "Tanda";
+ break;
+ case 55:
+ name = "Tiassale";
+ break;
+ case 56:
+ name = "Toumodi";
+ break;
+ case 57:
+ name = "Vavoua";
+ break;
+ case 61:
+ name = "Abidjan";
+ break;
+ case 62:
+ name = "Aboisso";
+ break;
+ case 63:
+ name = "Adiake";
+ break;
+ case 64:
+ name = "Alepe";
+ break;
+ case 65:
+ name = "Bocanda";
+ break;
+ case 66:
+ name = "Dabou";
+ break;
+ case 67:
+ name = "Dimbokro";
+ break;
+ case 68:
+ name = "Grand-Bassam";
+ break;
+ case 69:
+ name = "Guiglo";
+ break;
+ case 70:
+ name = "Jacqueville";
+ break;
+ case 71:
+ name = "Tiebissou";
+ break;
+ case 72:
+ name = "Toulepleu";
+ break;
+ case 73:
+ name = "Yamoussoukro";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CL") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Valparaiso";
+ break;
+ case 2:
+ name = "Aisen del General Carlos Ibanez del Campo";
+ break;
+ case 3:
+ name = "Antofagasta";
+ break;
+ case 4:
+ name = "Araucania";
+ break;
+ case 5:
+ name = "Atacama";
+ break;
+ case 6:
+ name = "Bio-Bio";
+ break;
+ case 7:
+ name = "Coquimbo";
+ break;
+ case 8:
+ name = "Libertador General Bernardo O'Higgins";
+ break;
+ case 9:
+ name = "Los Lagos";
+ break;
+ case 10:
+ name = "Magallanes y de la Antartica Chilena";
+ break;
+ case 11:
+ name = "Maule";
+ break;
+ case 12:
+ name = "Region Metropolitana";
+ break;
+ case 13:
+ name = "Tarapaca";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CM") == 0) {
+ switch (region_code2) {
+ case 4:
+ name = "Est";
+ break;
+ case 5:
+ name = "Littoral";
+ break;
+ case 7:
+ name = "Nord-Ouest";
+ break;
+ case 8:
+ name = "Ouest";
+ break;
+ case 9:
+ name = "Sud-Ouest";
+ break;
+ case 10:
+ name = "Adamaoua";
+ break;
+ case 11:
+ name = "Centre";
+ break;
+ case 12:
+ name = "Extreme-Nord";
+ break;
+ case 13:
+ name = "Nord";
+ break;
+ case 14:
+ name = "Sud";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CN") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Anhui";
+ break;
+ case 2:
+ name = "Zhejiang";
+ break;
+ case 3:
+ name = "Jiangxi";
+ break;
+ case 4:
+ name = "Jiangsu";
+ break;
+ case 5:
+ name = "Jilin";
+ break;
+ case 6:
+ name = "Qinghai";
+ break;
+ case 7:
+ name = "Fujian";
+ break;
+ case 8:
+ name = "Heilongjiang";
+ break;
+ case 9:
+ name = "Henan";
+ break;
+ case 10:
+ name = "Hebei";
+ break;
+ case 11:
+ name = "Hunan";
+ break;
+ case 12:
+ name = "Hubei";
+ break;
+ case 13:
+ name = "Xinjiang";
+ break;
+ case 14:
+ name = "Xizang";
+ break;
+ case 15:
+ name = "Gansu";
+ break;
+ case 16:
+ name = "Guangxi";
+ break;
+ case 18:
+ name = "Guizhou";
+ break;
+ case 19:
+ name = "Liaoning";
+ break;
+ case 20:
+ name = "Nei Mongol";
+ break;
+ case 21:
+ name = "Ningxia";
+ break;
+ case 22:
+ name = "Beijing";
+ break;
+ case 23:
+ name = "Shanghai";
+ break;
+ case 24:
+ name = "Shanxi";
+ break;
+ case 25:
+ name = "Shandong";
+ break;
+ case 26:
+ name = "Shaanxi";
+ break;
+ case 28:
+ name = "Tianjin";
+ break;
+ case 29:
+ name = "Yunnan";
+ break;
+ case 30:
+ name = "Guangdong";
+ break;
+ case 31:
+ name = "Hainan";
+ break;
+ case 32:
+ name = "Sichuan";
+ break;
+ case 33:
+ name = "Chongqing";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CO") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Amazonas";
+ break;
+ case 2:
+ name = "Antioquia";
+ break;
+ case 3:
+ name = "Arauca";
+ break;
+ case 4:
+ name = "Atlantico";
+ break;
+ case 8:
+ name = "Caqueta";
+ break;
+ case 9:
+ name = "Cauca";
+ break;
+ case 10:
+ name = "Cesar";
+ break;
+ case 11:
+ name = "Choco";
+ break;
+ case 12:
+ name = "Cordoba";
+ break;
+ case 14:
+ name = "Guaviare";
+ break;
+ case 15:
+ name = "Guainia";
+ break;
+ case 16:
+ name = "Huila";
+ break;
+ case 17:
+ name = "La Guajira";
+ break;
+ case 19:
+ name = "Meta";
+ break;
+ case 20:
+ name = "Narino";
+ break;
+ case 21:
+ name = "Norte de Santander";
+ break;
+ case 22:
+ name = "Putumayo";
+ break;
+ case 23:
+ name = "Quindio";
+ break;
+ case 24:
+ name = "Risaralda";
+ break;
+ case 25:
+ name = "San Andres y Providencia";
+ break;
+ case 26:
+ name = "Santander";
+ break;
+ case 27:
+ name = "Sucre";
+ break;
+ case 28:
+ name = "Tolima";
+ break;
+ case 29:
+ name = "Valle del Cauca";
+ break;
+ case 30:
+ name = "Vaupes";
+ break;
+ case 31:
+ name = "Vichada";
+ break;
+ case 32:
+ name = "Casanare";
+ break;
+ case 33:
+ name = "Cundinamarca";
+ break;
+ case 34:
+ name = "Distrito Especial";
+ break;
+ case 35:
+ name = "Bolivar";
+ break;
+ case 36:
+ name = "Boyaca";
+ break;
+ case 37:
+ name = "Caldas";
+ break;
+ case 38:
+ name = "Magdalena";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Alajuela";
+ break;
+ case 2:
+ name = "Cartago";
+ break;
+ case 3:
+ name = "Guanacaste";
+ break;
+ case 4:
+ name = "Heredia";
+ break;
+ case 6:
+ name = "Limon";
+ break;
+ case 7:
+ name = "Puntarenas";
+ break;
+ case 8:
+ name = "San Jose";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CU") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Pinar del Rio";
+ break;
+ case 2:
+ name = "Ciudad de la Habana";
+ break;
+ case 3:
+ name = "Matanzas";
+ break;
+ case 4:
+ name = "Isla de la Juventud";
+ break;
+ case 5:
+ name = "Camaguey";
+ break;
+ case 7:
+ name = "Ciego de Avila";
+ break;
+ case 8:
+ name = "Cienfuegos";
+ break;
+ case 9:
+ name = "Granma";
+ break;
+ case 10:
+ name = "Guantanamo";
+ break;
+ case 11:
+ name = "La Habana";
+ break;
+ case 12:
+ name = "Holguin";
+ break;
+ case 13:
+ name = "Las Tunas";
+ break;
+ case 14:
+ name = "Sancti Spiritus";
+ break;
+ case 15:
+ name = "Santiago de Cuba";
+ break;
+ case 16:
+ name = "Villa Clara";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CV") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Boa Vista";
+ break;
+ case 2:
+ name = "Brava";
+ break;
+ case 4:
+ name = "Maio";
+ break;
+ case 5:
+ name = "Paul";
+ break;
+ case 7:
+ name = "Ribeira Grande";
+ break;
+ case 8:
+ name = "Sal";
+ break;
+ case 10:
+ name = "Sao Nicolau";
+ break;
+ case 11:
+ name = "Sao Vicente";
+ break;
+ case 13:
+ name = "Mosteiros";
+ break;
+ case 14:
+ name = "Praia";
+ break;
+ case 15:
+ name = "Santa Catarina";
+ break;
+ case 16:
+ name = "Santa Cruz";
+ break;
+ case 17:
+ name = "Sao Domingos";
+ break;
+ case 18:
+ name = "Sao Filipe";
+ break;
+ case 19:
+ name = "Sao Miguel";
+ break;
+ case 20:
+ name = "Tarrafal";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CY") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Famagusta";
+ break;
+ case 2:
+ name = "Kyrenia";
+ break;
+ case 3:
+ name = "Larnaca";
+ break;
+ case 4:
+ name = "Nicosia";
+ break;
+ case 5:
+ name = "Limassol";
+ break;
+ case 6:
+ name = "Paphos";
+ break;
+ }
+ }
+ if (strcmp(country_code,"CZ") == 0) {
+ switch (region_code2) {
+ case 3:
+ name = "Blansko";
+ break;
+ case 4:
+ name = "Breclav";
+ break;
+ case 20:
+ name = "Hradec Kralove";
+ break;
+ case 21:
+ name = "Jablonec nad Nisou";
+ break;
+ case 23:
+ name = "Jiein";
+ break;
+ case 24:
+ name = "Jihlava";
+ break;
+ case 30:
+ name = "Kolin";
+ break;
+ case 33:
+ name = "Liberec";
+ break;
+ case 36:
+ name = "Melnik";
+ break;
+ case 37:
+ name = "Mlada Boleslav";
+ break;
+ case 39:
+ name = "Nachod";
+ break;
+ case 41:
+ name = "Nymburk";
+ break;
+ case 45:
+ name = "Pardubice";
+ break;
+ case 52:
+ name = "Hlavni Mesto Praha";
+ break;
+ case 61:
+ name = "Semily";
+ break;
+ case 70:
+ name = "Trutnov";
+ break;
+ case 78:
+ name = "Jihomoravsky Kraj";
+ break;
+ case 79:
+ name = "Jihocesky Kraj";
+ break;
+ case 80:
+ name = "Vysocina";
+ break;
+ case 81:
+ name = "Karlovarsky Kraj";
+ break;
+ case 82:
+ name = "Kralovehradecky Kraj";
+ break;
+ case 83:
+ name = "Liberecky Kraj";
+ break;
+ case 84:
+ name = "Olomoucky Kraj";
+ break;
+ case 85:
+ name = "Moravskoslezsky Kraj";
+ break;
+ case 86:
+ name = "Pardubicky Kraj";
+ break;
+ case 87:
+ name = "Plzensky Kraj";
+ break;
+ case 88:
+ name = "Stredocesky Kraj";
+ break;
+ case 89:
+ name = "Ustecky Kraj";
+ break;
+ case 90:
+ name = "Zlinsky Kraj";
+ break;
+ }
+ }
+ if (strcmp(country_code,"DE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Baden-Wrttemberg";
+ break;
+ case 2:
+ name = "Bayern";
+ break;
+ case 3:
+ name = "Bremen";
+ break;
+ case 4:
+ name = "Hamburg";
+ break;
+ case 5:
+ name = "Hessen";
+ break;
+ case 6:
+ name = "Niedersachsen";
+ break;
+ case 7:
+ name = "Nordrhein-Westfalen";
+ break;
+ case 8:
+ name = "Rheinland-Pfalz";
+ break;
+ case 9:
+ name = "Saarland";
+ break;
+ case 10:
+ name = "Schleswig-Holstein";
+ break;
+ case 11:
+ name = "Brandenburg";
+ break;
+ case 12:
+ name = "Mecklenburg-Vorpommern";
+ break;
+ case 13:
+ name = "Sachsen";
+ break;
+ case 14:
+ name = "Sachsen-Anhalt";
+ break;
+ case 15:
+ name = "Thuringen";
+ break;
+ case 16:
+ name = "Berlin";
+ break;
+ }
+ }
+ if (strcmp(country_code,"DJ") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Dikhil";
+ break;
+ case 3:
+ name = "Djibouti";
+ break;
+ case 4:
+ name = "Obock";
+ break;
+ case 5:
+ name = "Tadjoura";
+ break;
+ }
+ }
+ if (strcmp(country_code,"DK") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Arhus";
+ break;
+ case 2:
+ name = "Bornholm";
+ break;
+ case 3:
+ name = "Frederiksborg";
+ break;
+ case 4:
+ name = "Fyn";
+ break;
+ case 5:
+ name = "Kobenhavn";
+ break;
+ case 6:
+ name = "Staden Kobenhavn";
+ break;
+ case 7:
+ name = "Nordjylland";
+ break;
+ case 8:
+ name = "Ribe";
+ break;
+ case 9:
+ name = "Ringkobing";
+ break;
+ case 10:
+ name = "Roskilde";
+ break;
+ case 11:
+ name = "Sonderjylland";
+ break;
+ case 12:
+ name = "Storstrom";
+ break;
+ case 13:
+ name = "Vejle";
+ break;
+ case 14:
+ name = "Vestsjalland";
+ break;
+ case 15:
+ name = "Viborg";
+ break;
+ }
+ }
+ if (strcmp(country_code,"DM") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Saint Andrew";
+ break;
+ case 3:
+ name = "Saint David";
+ break;
+ case 4:
+ name = "Saint George";
+ break;
+ case 5:
+ name = "Saint John";
+ break;
+ case 6:
+ name = "Saint Joseph";
+ break;
+ case 7:
+ name = "Saint Luke";
+ break;
+ case 8:
+ name = "Saint Mark";
+ break;
+ case 9:
+ name = "Saint Patrick";
+ break;
+ case 10:
+ name = "Saint Paul";
+ break;
+ case 11:
+ name = "Saint Peter";
+ break;
+ }
+ }
+ if (strcmp(country_code,"DO") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Azua";
+ break;
+ case 2:
+ name = "Baoruco";
+ break;
+ case 3:
+ name = "Barahona";
+ break;
+ case 4:
+ name = "Dajabon";
+ break;
+ case 5:
+ name = "Distrito Nacional";
+ break;
+ case 6:
+ name = "Duarte";
+ break;
+ case 8:
+ name = "Espaillat";
+ break;
+ case 9:
+ name = "Independencia";
+ break;
+ case 10:
+ name = "La Altagracia";
+ break;
+ case 11:
+ name = "Elias Pina";
+ break;
+ case 12:
+ name = "La Romana";
+ break;
+ case 14:
+ name = "Maria Trinidad Sanchez";
+ break;
+ case 15:
+ name = "Monte Cristi";
+ break;
+ case 16:
+ name = "Pedernales";
+ break;
+ case 17:
+ name = "Peravia";
+ break;
+ case 18:
+ name = "Puerto Plata";
+ break;
+ case 19:
+ name = "Salcedo";
+ break;
+ case 20:
+ name = "Samana";
+ break;
+ case 21:
+ name = "Sanchez Ramirez";
+ break;
+ case 23:
+ name = "San Juan";
+ break;
+ case 24:
+ name = "San Pedro De Macoris";
+ break;
+ case 25:
+ name = "Santiago";
+ break;
+ case 26:
+ name = "Santiago Rodriguez";
+ break;
+ case 27:
+ name = "Valverde";
+ break;
+ case 28:
+ name = "El Seibo";
+ break;
+ case 29:
+ name = "Hato Mayor";
+ break;
+ case 30:
+ name = "La Vega";
+ break;
+ case 31:
+ name = "Monsenor Nouel";
+ break;
+ case 32:
+ name = "Monte Plata";
+ break;
+ case 33:
+ name = "San Cristobal";
+ break;
+ }
+ }
+ if (strcmp(country_code,"DZ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Alger";
+ break;
+ case 3:
+ name = "Batna";
+ break;
+ case 4:
+ name = "Constantine";
+ break;
+ case 6:
+ name = "Medea";
+ break;
+ case 7:
+ name = "Mostaganem";
+ break;
+ case 9:
+ name = "Oran";
+ break;
+ case 10:
+ name = "Saida";
+ break;
+ case 12:
+ name = "Setif";
+ break;
+ case 13:
+ name = "Tiaret";
+ break;
+ case 14:
+ name = "Tizi Ouzou";
+ break;
+ case 15:
+ name = "Tlemcen";
+ break;
+ case 18:
+ name = "Bejaia";
+ break;
+ case 19:
+ name = "Biskra";
+ break;
+ case 20:
+ name = "Blida";
+ break;
+ case 21:
+ name = "Bouira";
+ break;
+ case 22:
+ name = "Djelfa";
+ break;
+ case 23:
+ name = "Guelma";
+ break;
+ case 24:
+ name = "Jijel";
+ break;
+ case 25:
+ name = "Laghouat";
+ break;
+ case 26:
+ name = "Mascara";
+ break;
+ case 27:
+ name = "M'sila";
+ break;
+ case 29:
+ name = "Oum el Bouaghi";
+ break;
+ case 30:
+ name = "Sidi Bel Abbes";
+ break;
+ case 31:
+ name = "Skikda";
+ break;
+ case 33:
+ name = "Tebessa";
+ break;
+ case 34:
+ name = "Adrar";
+ break;
+ case 35:
+ name = "Ain Defla";
+ break;
+ case 36:
+ name = "Ain Temouchent";
+ break;
+ case 37:
+ name = "Annaba";
+ break;
+ case 38:
+ name = "Bechar";
+ break;
+ case 39:
+ name = "Bordj Bou Arreridj";
+ break;
+ case 40:
+ name = "Boumerdes";
+ break;
+ case 41:
+ name = "Chlef";
+ break;
+ case 42:
+ name = "El Bayadh";
+ break;
+ case 43:
+ name = "El Oued";
+ break;
+ case 44:
+ name = "El Tarf";
+ break;
+ case 45:
+ name = "Ghardaia";
+ break;
+ case 46:
+ name = "Illizi";
+ break;
+ case 47:
+ name = "Khenchela";
+ break;
+ case 48:
+ name = "Mila";
+ break;
+ case 49:
+ name = "Naama";
+ break;
+ case 50:
+ name = "Ouargla";
+ break;
+ case 51:
+ name = "Relizane";
+ break;
+ case 52:
+ name = "Souk Ahras";
+ break;
+ case 53:
+ name = "Tamanghasset";
+ break;
+ case 54:
+ name = "Tindouf";
+ break;
+ case 55:
+ name = "Tipaza";
+ break;
+ case 56:
+ name = "Tissemsilt";
+ break;
+ }
+ }
+ if (strcmp(country_code,"EC") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Galapagos";
+ break;
+ case 2:
+ name = "Azuay";
+ break;
+ case 3:
+ name = "Bolivar";
+ break;
+ case 4:
+ name = "Canar";
+ break;
+ case 5:
+ name = "Carchi";
+ break;
+ case 6:
+ name = "Chimborazo";
+ break;
+ case 7:
+ name = "Cotopaxi";
+ break;
+ case 8:
+ name = "El Oro";
+ break;
+ case 9:
+ name = "Esmeraldas";
+ break;
+ case 10:
+ name = "Guayas";
+ break;
+ case 11:
+ name = "Imbabura";
+ break;
+ case 12:
+ name = "Loja";
+ break;
+ case 13:
+ name = "Los Rios";
+ break;
+ case 14:
+ name = "Manabi";
+ break;
+ case 15:
+ name = "Morona-Santiago";
+ break;
+ case 17:
+ name = "Pastaza";
+ break;
+ case 18:
+ name = "Pichincha";
+ break;
+ case 19:
+ name = "Tungurahua";
+ break;
+ case 20:
+ name = "Zamora-Chinchipe";
+ break;
+ case 22:
+ name = "Sucumbios";
+ break;
+ case 23:
+ name = "Napo";
+ break;
+ case 24:
+ name = "Orellana";
+ break;
+ }
+ }
+ if (strcmp(country_code,"EE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Harjumaa";
+ break;
+ case 2:
+ name = "Hiiumaa";
+ break;
+ case 3:
+ name = "Ida-Virumaa";
+ break;
+ case 4:
+ name = "Jarvamaa";
+ break;
+ case 5:
+ name = "Jogevamaa";
+ break;
+ case 6:
+ name = "Kohtla-Jarve";
+ break;
+ case 7:
+ name = "Laanemaa";
+ break;
+ case 8:
+ name = "Laane-Virumaa";
+ break;
+ case 9:
+ name = "Narva";
+ break;
+ case 10:
+ name = "Parnu";
+ break;
+ case 11:
+ name = "Parnumaa";
+ break;
+ case 12:
+ name = "Polvamaa";
+ break;
+ case 13:
+ name = "Raplamaa";
+ break;
+ case 14:
+ name = "Saaremaa";
+ break;
+ case 15:
+ name = "Sillamae";
+ break;
+ case 16:
+ name = "Tallinn";
+ break;
+ case 17:
+ name = "Tartu";
+ break;
+ case 18:
+ name = "Tartumaa";
+ break;
+ case 19:
+ name = "Valgamaa";
+ break;
+ case 20:
+ name = "Viljandimaa";
+ break;
+ case 21:
+ name = "Vorumaa";
+ break;
+ }
+ }
+ if (strcmp(country_code,"EG") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Ad Daqahliyah";
+ break;
+ case 2:
+ name = "Al Bahr al Ahmar";
+ break;
+ case 3:
+ name = "Al Buhayrah";
+ break;
+ case 4:
+ name = "Al Fayyum";
+ break;
+ case 5:
+ name = "Al Gharbiyah";
+ break;
+ case 6:
+ name = "Al Iskandariyah";
+ break;
+ case 7:
+ name = "Al Isma'iliyah";
+ break;
+ case 8:
+ name = "Al Jizah";
+ break;
+ case 9:
+ name = "Al Minufiyah";
+ break;
+ case 10:
+ name = "Al Minya";
+ break;
+ case 11:
+ name = "Al Qahirah";
+ break;
+ case 12:
+ name = "Al Qalyubiyah";
+ break;
+ case 13:
+ name = "Al Wadi al Jadid";
+ break;
+ case 14:
+ name = "Ash Sharqiyah";
+ break;
+ case 15:
+ name = "As Suways";
+ break;
+ case 16:
+ name = "Aswan";
+ break;
+ case 17:
+ name = "Asyut";
+ break;
+ case 18:
+ name = "Bani Suwayf";
+ break;
+ case 19:
+ name = "Bur Sa'id";
+ break;
+ case 20:
+ name = "Dumyat";
+ break;
+ case 21:
+ name = "Kafr ash Shaykh";
+ break;
+ case 22:
+ name = "Matruh";
+ break;
+ case 23:
+ name = "Qina";
+ break;
+ case 24:
+ name = "Suhaj";
+ break;
+ case 26:
+ name = "Janub Sina'";
+ break;
+ case 27:
+ name = "Shamal Sina'";
+ break;
+ }
+ }
+ if (strcmp(country_code,"ES") == 0) {
+ switch (region_code2) {
+ case 7:
+ name = "Islas Baleares";
+ break;
+ case 27:
+ name = "La Rioja";
+ break;
+ case 29:
+ name = "Madrid";
+ break;
+ case 31:
+ name = "Murcia";
+ break;
+ case 32:
+ name = "Navarra";
+ break;
+ case 34:
+ name = "Asturias";
+ break;
+ case 39:
+ name = "Cantabria";
+ break;
+ case 51:
+ name = "Andalucia";
+ break;
+ case 52:
+ name = "Aragon";
+ break;
+ case 53:
+ name = "Canarias";
+ break;
+ case 54:
+ name = "Castilla-La Mancha";
+ break;
+ case 55:
+ name = "Castilla y Leon";
+ break;
+ case 56:
+ name = "Cataluna";
+ break;
+ case 57:
+ name = "Extremadura";
+ break;
+ case 58:
+ name = "Galicia";
+ break;
+ case 59:
+ name = "Pais Vasco";
+ break;
+ case 60:
+ name = "Comunidad Valenciana";
+ break;
+ }
+ }
+ if (strcmp(country_code,"ET") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Amhara";
+ break;
+ case 7:
+ name = "Somali";
+ break;
+ case 8:
+ name = "Gambella";
+ break;
+ case 10:
+ name = "Addis Abeba";
+ break;
+ case 11:
+ name = "Southern";
+ break;
+ case 12:
+ name = "Tigray";
+ break;
+ case 13:
+ name = "Benishangul";
+ break;
+ case 14:
+ name = "Afar";
+ break;
+ case 44:
+ name = "Adis Abeba";
+ break;
+ case 45:
+ name = "Afar";
+ break;
+ case 46:
+ name = "Amara";
+ break;
+ case 47:
+ name = "Binshangul Gumuz";
+ break;
+ case 48:
+ name = "Dire Dawa";
+ break;
+ case 49:
+ name = "Gambela Hizboch";
+ break;
+ case 50:
+ name = "Hareri Hizb";
+ break;
+ case 51:
+ name = "Oromiya";
+ break;
+ case 52:
+ name = "Sumale";
+ break;
+ case 53:
+ name = "Tigray";
+ break;
+ case 54:
+ name = "YeDebub Biheroch Bihereseboch na Hizboch";
+ break;
+ }
+ }
+ if (strcmp(country_code,"FI") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "land";
+ break;
+ case 6:
+ name = "Lapland";
+ break;
+ case 8:
+ name = "Oulu";
+ break;
+ case 13:
+ name = "Southern Finland";
+ break;
+ case 14:
+ name = "Eastern Finland";
+ break;
+ case 15:
+ name = "Western Finland";
+ break;
+ }
+ }
+ if (strcmp(country_code,"FJ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Central";
+ break;
+ case 2:
+ name = "Eastern";
+ break;
+ case 3:
+ name = "Northern";
+ break;
+ case 4:
+ name = "Rotuma";
+ break;
+ case 5:
+ name = "Western";
+ break;
+ }
+ }
+ if (strcmp(country_code,"FM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Kosrae";
+ break;
+ case 2:
+ name = "Pohnpei";
+ break;
+ case 3:
+ name = "Chuuk";
+ break;
+ case 4:
+ name = "Yap";
+ break;
+ }
+ }
+ if (strcmp(country_code,"FR") == 0) {
+ switch (region_code2) {
+ case 97:
+ name = "Aquitaine";
+ break;
+ case 98:
+ name = "Auvergne";
+ break;
+ case 99:
+ name = "Basse-Normandie";
+ break;
+ case 101:
+ name = "Bourgogne";
+ break;
+ case 102:
+ name = "Bretagne";
+ break;
+ case 103:
+ name = "Centre";
+ break;
+ case 104:
+ name = "Champagne-Ardenne";
+ break;
+ case 105:
+ name = "Corse";
+ break;
+ case 106:
+ name = "Franche-Comte";
+ break;
+ case 107:
+ name = "Haute-Normandie";
+ break;
+ case 108:
+ name = "Ile-de-France";
+ break;
+ case 109:
+ name = "Languedoc-Roussillon";
+ break;
+ case 111:
+ name = "Limousin";
+ break;
+ case 112:
+ name = "Lorraine";
+ break;
+ case 113:
+ name = "Midi-Pyrenees";
+ break;
+ case 114:
+ name = "Nord-Pas-de-Calais";
+ break;
+ case 115:
+ name = "Pays de la Loire";
+ break;
+ case 116:
+ name = "Picardie";
+ break;
+ case 117:
+ name = "Poitou-Charentes";
+ break;
+ case 118:
+ name = "Provence-Alpes-Cote d'Azur";
+ break;
+ case 119:
+ name = "Rhone-Alpes";
+ break;
+ case 121:
+ name = "Alsace";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GA") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Estuaire";
+ break;
+ case 2:
+ name = "Haut-Ogooue";
+ break;
+ case 3:
+ name = "Moyen-Ogooue";
+ break;
+ case 4:
+ name = "Ngounie";
+ break;
+ case 5:
+ name = "Nyanga";
+ break;
+ case 6:
+ name = "Ogooue-Ivindo";
+ break;
+ case 7:
+ name = "Ogooue-Lolo";
+ break;
+ case 8:
+ name = "Ogooue-Maritime";
+ break;
+ case 9:
+ name = "Woleu-Ntem";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GB") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Avon";
+ break;
+ case 3:
+ name = "Berkshire";
+ break;
+ case 7:
+ name = "Cleveland";
+ break;
+ case 17:
+ name = "Greater London";
+ break;
+ case 18:
+ name = "Greater Manchester";
+ break;
+ case 20:
+ name = "Hereford and Worcester";
+ break;
+ case 22:
+ name = "Humberside";
+ break;
+ case 28:
+ name = "Merseyside";
+ break;
+ case 37:
+ name = "South Yorkshire";
+ break;
+ case 41:
+ name = "Tyne and Wear";
+ break;
+ case 43:
+ name = "West Midlands";
+ break;
+ case 45:
+ name = "West Yorkshire";
+ break;
+ case 79:
+ name = "Central";
+ break;
+ case 82:
+ name = "Grampian";
+ break;
+ case 84:
+ name = "Lothian";
+ break;
+ case 87:
+ name = "Strathclyde";
+ break;
+ case 88:
+ name = "Tayside";
+ break;
+ case 90:
+ name = "Clwyd";
+ break;
+ case 91:
+ name = "Dyfed";
+ break;
+ case 92:
+ name = "Gwent";
+ break;
+ case 94:
+ name = "Mid Glamorgan";
+ break;
+ case 96:
+ name = "South Glamorgan";
+ break;
+ case 97:
+ name = "West Glamorgan";
+ break;
+ case 101:
+ name = "Barking and Dagenham";
+ break;
+ case 102:
+ name = "Barnet";
+ break;
+ case 103:
+ name = "Barnsley";
+ break;
+ case 104:
+ name = "Bath and North East Somerset";
+ break;
+ case 105:
+ name = "Bedfordshire";
+ break;
+ case 106:
+ name = "Bexley";
+ break;
+ case 107:
+ name = "Birmingham";
+ break;
+ case 108:
+ name = "Blackburn with Darwen";
+ break;
+ case 109:
+ name = "Blackpool";
+ break;
+ case 111:
+ name = "Bolton";
+ break;
+ case 112:
+ name = "Bournemouth";
+ break;
+ case 113:
+ name = "Bracknell Forest";
+ break;
+ case 114:
+ name = "Bradford";
+ break;
+ case 115:
+ name = "Brent";
+ break;
+ case 116:
+ name = "Brighton and Hove";
+ break;
+ case 117:
+ name = "Bristol";
+ break;
+ case 118:
+ name = "Bromley";
+ break;
+ case 119:
+ name = "Buckinghamshire";
+ break;
+ case 121:
+ name = "Bury";
+ break;
+ case 122:
+ name = "Calderdale";
+ break;
+ case 123:
+ name = "Cambridgeshire";
+ break;
+ case 124:
+ name = "Camden";
+ break;
+ case 125:
+ name = "Cheshire";
+ break;
+ case 126:
+ name = "Cornwall";
+ break;
+ case 127:
+ name = "Coventry";
+ break;
+ case 128:
+ name = "Croydon";
+ break;
+ case 129:
+ name = "Cumbria";
+ break;
+ case 131:
+ name = "Darlington";
+ break;
+ case 132:
+ name = "Derby";
+ break;
+ case 133:
+ name = "Derbyshire";
+ break;
+ case 134:
+ name = "Devon";
+ break;
+ case 135:
+ name = "Doncaster";
+ break;
+ case 136:
+ name = "Dorset";
+ break;
+ case 137:
+ name = "Dudley";
+ break;
+ case 138:
+ name = "Durham";
+ break;
+ case 139:
+ name = "Ealing";
+ break;
+ case 141:
+ name = "East Riding of Yorkshire";
+ break;
+ case 142:
+ name = "East Sussex";
+ break;
+ case 143:
+ name = "Enfield";
+ break;
+ case 144:
+ name = "Essex";
+ break;
+ case 145:
+ name = "Gateshead";
+ break;
+ case 146:
+ name = "Gloucestershire";
+ break;
+ case 147:
+ name = "Greenwich";
+ break;
+ case 148:
+ name = "Hackney";
+ break;
+ case 149:
+ name = "Halton";
+ break;
+ case 151:
+ name = "Hammersmith and Fulham";
+ break;
+ case 152:
+ name = "Hampshire";
+ break;
+ case 153:
+ name = "Haringey";
+ break;
+ case 154:
+ name = "Harrow";
+ break;
+ case 155:
+ name = "Hartlepool";
+ break;
+ case 156:
+ name = "Havering";
+ break;
+ case 157:
+ name = "Herefordshire";
+ break;
+ case 158:
+ name = "Hertford";
+ break;
+ case 159:
+ name = "Hillingdon";
+ break;
+ case 161:
+ name = "Hounslow";
+ break;
+ case 162:
+ name = "Isle of Wight";
+ break;
+ case 163:
+ name = "Islington";
+ break;
+ case 164:
+ name = "Kensington and Chelsea";
+ break;
+ case 165:
+ name = "Kent";
+ break;
+ case 166:
+ name = "Kingston upon Hull";
+ break;
+ case 167:
+ name = "Kingston upon Thames";
+ break;
+ case 168:
+ name = "Kirklees";
+ break;
+ case 169:
+ name = "Knowsley";
+ break;
+ case 171:
+ name = "Lambeth";
+ break;
+ case 172:
+ name = "Lancashire";
+ break;
+ case 173:
+ name = "Leeds";
+ break;
+ case 174:
+ name = "Leicester";
+ break;
+ case 175:
+ name = "Leicestershire";
+ break;
+ case 176:
+ name = "Lewisham";
+ break;
+ case 177:
+ name = "Lincolnshire";
+ break;
+ case 178:
+ name = "Liverpool";
+ break;
+ case 179:
+ name = "London";
+ break;
+ case 181:
+ name = "Luton";
+ break;
+ case 182:
+ name = "Manchester";
+ break;
+ case 183:
+ name = "Medway";
+ break;
+ case 184:
+ name = "Merton";
+ break;
+ case 185:
+ name = "Middlesbrough";
+ break;
+ case 186:
+ name = "Milton Keynes";
+ break;
+ case 187:
+ name = "Newcastle upon Tyne";
+ break;
+ case 188:
+ name = "Newham";
+ break;
+ case 189:
+ name = "Norfolk";
+ break;
+ case 191:
+ name = "Northamptonshire";
+ break;
+ case 192:
+ name = "North East Lincolnshire";
+ break;
+ case 193:
+ name = "North Lincolnshire";
+ break;
+ case 194:
+ name = "North Somerset";
+ break;
+ case 195:
+ name = "North Tyneside";
+ break;
+ case 196:
+ name = "Northumberland";
+ break;
+ case 197:
+ name = "North Yorkshire";
+ break;
+ case 198:
+ name = "Nottingham";
+ break;
+ case 199:
+ name = "Nottinghamshire";
+ break;
+ case 201:
+ name = "Oldham";
+ break;
+ case 202:
+ name = "Oxfordshire";
+ break;
+ case 203:
+ name = "Peterborough";
+ break;
+ case 204:
+ name = "Plymouth";
+ break;
+ case 205:
+ name = "Poole";
+ break;
+ case 206:
+ name = "Portsmouth";
+ break;
+ case 207:
+ name = "Reading";
+ break;
+ case 208:
+ name = "Redbridge";
+ break;
+ case 209:
+ name = "Redcar and Cleveland";
+ break;
+ case 211:
+ name = "Richmond upon Thames";
+ break;
+ case 212:
+ name = "Rochdale";
+ break;
+ case 213:
+ name = "Rotherham";
+ break;
+ case 214:
+ name = "Rutland";
+ break;
+ case 215:
+ name = "Salford";
+ break;
+ case 216:
+ name = "Shropshire";
+ break;
+ case 217:
+ name = "Sandwell";
+ break;
+ case 218:
+ name = "Sefton";
+ break;
+ case 219:
+ name = "Sheffield";
+ break;
+ case 221:
+ name = "Slough";
+ break;
+ case 222:
+ name = "Solihull";
+ break;
+ case 223:
+ name = "Somerset";
+ break;
+ case 224:
+ name = "Southampton";
+ break;
+ case 225:
+ name = "Southend-on-Sea";
+ break;
+ case 226:
+ name = "South Gloucestershire";
+ break;
+ case 227:
+ name = "South Tyneside";
+ break;
+ case 228:
+ name = "Southwark";
+ break;
+ case 229:
+ name = "Staffordshire";
+ break;
+ case 231:
+ name = "St. Helens";
+ break;
+ case 232:
+ name = "Stockport";
+ break;
+ case 233:
+ name = "Stockton-on-Tees";
+ break;
+ case 234:
+ name = "Stoke-on-Trent";
+ break;
+ case 235:
+ name = "Suffolk";
+ break;
+ case 236:
+ name = "Sunderland";
+ break;
+ case 237:
+ name = "Surrey";
+ break;
+ case 238:
+ name = "Sutton";
+ break;
+ case 239:
+ name = "Swindon";
+ break;
+ case 241:
+ name = "Tameside";
+ break;
+ case 242:
+ name = "Telford and Wrekin";
+ break;
+ case 243:
+ name = "Thurrock";
+ break;
+ case 244:
+ name = "Torbay";
+ break;
+ case 245:
+ name = "Tower Hamlets";
+ break;
+ case 246:
+ name = "Trafford";
+ break;
+ case 247:
+ name = "Wakefield";
+ break;
+ case 248:
+ name = "Walsall";
+ break;
+ case 249:
+ name = "Waltham Forest";
+ break;
+ case 251:
+ name = "Wandsworth";
+ break;
+ case 252:
+ name = "Warrington";
+ break;
+ case 253:
+ name = "Warwickshire";
+ break;
+ case 254:
+ name = "West Berkshire";
+ break;
+ case 255:
+ name = "Westminster";
+ break;
+ case 256:
+ name = "West Sussex";
+ break;
+ case 257:
+ name = "Wigan";
+ break;
+ case 258:
+ name = "Wiltshire";
+ break;
+ case 259:
+ name = "Windsor and Maidenhead";
+ break;
+ case 261:
+ name = "Wirral";
+ break;
+ case 262:
+ name = "Wokingham";
+ break;
+ case 263:
+ name = "Wolverhampton";
+ break;
+ case 264:
+ name = "Worcestershire";
+ break;
+ case 265:
+ name = "York";
+ break;
+ case 266:
+ name = "Antrim";
+ break;
+ case 267:
+ name = "Ards";
+ break;
+ case 268:
+ name = "Armagh";
+ break;
+ case 269:
+ name = "Ballymena";
+ break;
+ case 271:
+ name = "Ballymoney";
+ break;
+ case 272:
+ name = "Banbridge";
+ break;
+ case 273:
+ name = "Belfast";
+ break;
+ case 274:
+ name = "Carrickfergus";
+ break;
+ case 275:
+ name = "Castlereagh";
+ break;
+ case 276:
+ name = "Coleraine";
+ break;
+ case 277:
+ name = "Cookstown";
+ break;
+ case 278:
+ name = "Craigavon";
+ break;
+ case 279:
+ name = "Down";
+ break;
+ case 281:
+ name = "Dungannon";
+ break;
+ case 282:
+ name = "Fermanagh";
+ break;
+ case 283:
+ name = "Larne";
+ break;
+ case 284:
+ name = "Limavady";
+ break;
+ case 285:
+ name = "Lisburn";
+ break;
+ case 286:
+ name = "Derry";
+ break;
+ case 287:
+ name = "Magherafelt";
+ break;
+ case 288:
+ name = "Moyle";
+ break;
+ case 289:
+ name = "Newry and Mourne";
+ break;
+ case 291:
+ name = "Newtownabbey";
+ break;
+ case 292:
+ name = "North Down";
+ break;
+ case 293:
+ name = "Omagh";
+ break;
+ case 294:
+ name = "Strabane";
+ break;
+ case 295:
+ name = "Aberdeen City";
+ break;
+ case 296:
+ name = "Aberdeenshire";
+ break;
+ case 297:
+ name = "Angus";
+ break;
+ case 298:
+ name = "Argyll and Bute";
+ break;
+ case 299:
+ name = "Scottish Borders";
+ break;
+ case 301:
+ name = "Clackmannanshire";
+ break;
+ case 302:
+ name = "Dumfries and Galloway";
+ break;
+ case 303:
+ name = "Dundee City";
+ break;
+ case 304:
+ name = "East Ayrshire";
+ break;
+ case 305:
+ name = "East Dunbartonshire";
+ break;
+ case 306:
+ name = "East Lothian";
+ break;
+ case 307:
+ name = "East Renfrewshire";
+ break;
+ case 308:
+ name = "Edinburgh";
+ break;
+ case 309:
+ name = "Falkirk";
+ break;
+ case 311:
+ name = "Fife";
+ break;
+ case 312:
+ name = "Glasgow City";
+ break;
+ case 313:
+ name = "Highland";
+ break;
+ case 314:
+ name = "Inverclyde";
+ break;
+ case 315:
+ name = "Midlothian";
+ break;
+ case 316:
+ name = "Moray";
+ break;
+ case 317:
+ name = "North Ayrshire";
+ break;
+ case 318:
+ name = "North Lanarkshire";
+ break;
+ case 319:
+ name = "Orkney";
+ break;
+ case 321:
+ name = "Perth and Kinross";
+ break;
+ case 322:
+ name = "Renfrewshire";
+ break;
+ case 323:
+ name = "Shetland Islands";
+ break;
+ case 324:
+ name = "South Ayrshire";
+ break;
+ case 325:
+ name = "South Lanarkshire";
+ break;
+ case 326:
+ name = "Stirling";
+ break;
+ case 327:
+ name = "West Dunbartonshire";
+ break;
+ case 328:
+ name = "Eilean Siar";
+ break;
+ case 329:
+ name = "West Lothian";
+ break;
+ case 331:
+ name = "Isle of Anglesey";
+ break;
+ case 332:
+ name = "Blaenau Gwent";
+ break;
+ case 333:
+ name = "Bridgend";
+ break;
+ case 334:
+ name = "Caerphilly";
+ break;
+ case 335:
+ name = "Cardiff";
+ break;
+ case 336:
+ name = "Ceredigion";
+ break;
+ case 337:
+ name = "Carmarthenshire";
+ break;
+ case 338:
+ name = "Conwy";
+ break;
+ case 339:
+ name = "Denbighshire";
+ break;
+ case 341:
+ name = "Flintshire";
+ break;
+ case 342:
+ name = "Gwynedd";
+ break;
+ case 343:
+ name = "Merthyr Tydfil";
+ break;
+ case 344:
+ name = "Monmouthshire";
+ break;
+ case 345:
+ name = "Neath Port Talbot";
+ break;
+ case 346:
+ name = "Newport";
+ break;
+ case 347:
+ name = "Pembrokeshire";
+ break;
+ case 348:
+ name = "Powys";
+ break;
+ case 349:
+ name = "Rhondda Cynon Taff";
+ break;
+ case 351:
+ name = "Swansea";
+ break;
+ case 352:
+ name = "Torfaen";
+ break;
+ case 353:
+ name = "Vale of Glamorgan";
+ break;
+ case 354:
+ name = "Wrexham";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GD") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Saint Andrew";
+ break;
+ case 2:
+ name = "Saint David";
+ break;
+ case 3:
+ name = "Saint George";
+ break;
+ case 4:
+ name = "Saint John";
+ break;
+ case 5:
+ name = "Saint Mark";
+ break;
+ case 6:
+ name = "Saint Patrick";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Abashis Raioni";
+ break;
+ case 2:
+ name = "Abkhazia";
+ break;
+ case 3:
+ name = "Adigenis Raioni";
+ break;
+ case 4:
+ name = "Ajaria";
+ break;
+ case 5:
+ name = "Akhalgoris Raioni";
+ break;
+ case 6:
+ name = "Akhalk'alak'is Raioni";
+ break;
+ case 7:
+ name = "Akhalts'ikhis Raioni";
+ break;
+ case 8:
+ name = "Akhmetis Raioni";
+ break;
+ case 9:
+ name = "Ambrolauris Raioni";
+ break;
+ case 10:
+ name = "Aspindzis Raioni";
+ break;
+ case 11:
+ name = "Baghdat'is Raioni";
+ break;
+ case 12:
+ name = "Bolnisis Raioni";
+ break;
+ case 13:
+ name = "Borjomis Raioni";
+ break;
+ case 14:
+ name = "Chiat'ura";
+ break;
+ case 15:
+ name = "Ch'khorotsqus Raioni";
+ break;
+ case 16:
+ name = "Ch'okhatauris Raioni";
+ break;
+ case 17:
+ name = "Dedop'listsqaros Raioni";
+ break;
+ case 18:
+ name = "Dmanisis Raioni";
+ break;
+ case 19:
+ name = "Dushet'is Raioni";
+ break;
+ case 20:
+ name = "Gardabanis Raioni";
+ break;
+ case 21:
+ name = "Gori";
+ break;
+ case 22:
+ name = "Goris Raioni";
+ break;
+ case 23:
+ name = "Gurjaanis Raioni";
+ break;
+ case 24:
+ name = "Javis Raioni";
+ break;
+ case 25:
+ name = "K'arelis Raioni";
+ break;
+ case 26:
+ name = "Kaspis Raioni";
+ break;
+ case 27:
+ name = "Kharagaulis Raioni";
+ break;
+ case 28:
+ name = "Khashuris Raioni";
+ break;
+ case 29:
+ name = "Khobis Raioni";
+ break;
+ case 30:
+ name = "Khonis Raioni";
+ break;
+ case 31:
+ name = "K'ut'aisi";
+ break;
+ case 32:
+ name = "Lagodekhis Raioni";
+ break;
+ case 33:
+ name = "Lanch'khut'is Raioni";
+ break;
+ case 34:
+ name = "Lentekhis Raioni";
+ break;
+ case 35:
+ name = "Marneulis Raioni";
+ break;
+ case 36:
+ name = "Martvilis Raioni";
+ break;
+ case 37:
+ name = "Mestiis Raioni";
+ break;
+ case 38:
+ name = "Mts'khet'is Raioni";
+ break;
+ case 39:
+ name = "Ninotsmindis Raioni";
+ break;
+ case 40:
+ name = "Onis Raioni";
+ break;
+ case 41:
+ name = "Ozurget'is Raioni";
+ break;
+ case 42:
+ name = "P'ot'i";
+ break;
+ case 43:
+ name = "Qazbegis Raioni";
+ break;
+ case 44:
+ name = "Qvarlis Raioni";
+ break;
+ case 45:
+ name = "Rust'avi";
+ break;
+ case 46:
+ name = "Sach'kheris Raioni";
+ break;
+ case 47:
+ name = "Sagarejos Raioni";
+ break;
+ case 48:
+ name = "Samtrediis Raioni";
+ break;
+ case 49:
+ name = "Senakis Raioni";
+ break;
+ case 50:
+ name = "Sighnaghis Raioni";
+ break;
+ case 51:
+ name = "T'bilisi";
+ break;
+ case 52:
+ name = "T'elavis Raioni";
+ break;
+ case 53:
+ name = "T'erjolis Raioni";
+ break;
+ case 54:
+ name = "T'et'ritsqaros Raioni";
+ break;
+ case 55:
+ name = "T'ianet'is Raioni";
+ break;
+ case 56:
+ name = "Tqibuli";
+ break;
+ case 57:
+ name = "Ts'ageris Raioni";
+ break;
+ case 58:
+ name = "Tsalenjikhis Raioni";
+ break;
+ case 59:
+ name = "Tsalkis Raioni";
+ break;
+ case 60:
+ name = "Tsqaltubo";
+ break;
+ case 61:
+ name = "Vanis Raioni";
+ break;
+ case 62:
+ name = "Zestap'onis Raioni";
+ break;
+ case 63:
+ name = "Zugdidi";
+ break;
+ case 64:
+ name = "Zugdidis Raioni";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GH") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Greater Accra";
+ break;
+ case 2:
+ name = "Ashanti";
+ break;
+ case 3:
+ name = "Brong-Ahafo";
+ break;
+ case 4:
+ name = "Central";
+ break;
+ case 5:
+ name = "Eastern";
+ break;
+ case 6:
+ name = "Northern";
+ break;
+ case 8:
+ name = "Volta";
+ break;
+ case 9:
+ name = "Western";
+ break;
+ case 10:
+ name = "Upper East";
+ break;
+ case 11:
+ name = "Upper West";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GL") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Nordgronland";
+ break;
+ case 2:
+ name = "Ostgronland";
+ break;
+ case 3:
+ name = "Vestgronland";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Banjul";
+ break;
+ case 2:
+ name = "Lower River";
+ break;
+ case 3:
+ name = "MacCarthy Island";
+ break;
+ case 4:
+ name = "Upper River";
+ break;
+ case 5:
+ name = "Western";
+ break;
+ case 7:
+ name = "North Bank";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GN") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Beyla";
+ break;
+ case 2:
+ name = "Boffa";
+ break;
+ case 3:
+ name = "Boke";
+ break;
+ case 4:
+ name = "Conakry";
+ break;
+ case 5:
+ name = "Dabola";
+ break;
+ case 6:
+ name = "Dalaba";
+ break;
+ case 7:
+ name = "Dinguiraye";
+ break;
+ case 9:
+ name = "Faranah";
+ break;
+ case 10:
+ name = "Forecariah";
+ break;
+ case 11:
+ name = "Fria";
+ break;
+ case 12:
+ name = "Gaoual";
+ break;
+ case 13:
+ name = "Gueckedou";
+ break;
+ case 15:
+ name = "Kerouane";
+ break;
+ case 16:
+ name = "Kindia";
+ break;
+ case 17:
+ name = "Kissidougou";
+ break;
+ case 18:
+ name = "Koundara";
+ break;
+ case 19:
+ name = "Kouroussa";
+ break;
+ case 21:
+ name = "Macenta";
+ break;
+ case 22:
+ name = "Mali";
+ break;
+ case 23:
+ name = "Mamou";
+ break;
+ case 25:
+ name = "Pita";
+ break;
+ case 27:
+ name = "Telimele";
+ break;
+ case 28:
+ name = "Tougue";
+ break;
+ case 29:
+ name = "Yomou";
+ break;
+ case 30:
+ name = "Coyah";
+ break;
+ case 31:
+ name = "Dubreka";
+ break;
+ case 32:
+ name = "Kankan";
+ break;
+ case 33:
+ name = "Koubia";
+ break;
+ case 34:
+ name = "Labe";
+ break;
+ case 35:
+ name = "Lelouma";
+ break;
+ case 36:
+ name = "Lola";
+ break;
+ case 37:
+ name = "Mandiana";
+ break;
+ case 38:
+ name = "Nzerekore";
+ break;
+ case 39:
+ name = "Siguiri";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GQ") == 0) {
+ switch (region_code2) {
+ case 3:
+ name = "Annobon";
+ break;
+ case 4:
+ name = "Bioko Norte";
+ break;
+ case 5:
+ name = "Bioko Sur";
+ break;
+ case 6:
+ name = "Centro Sur";
+ break;
+ case 7:
+ name = "Kie-Ntem";
+ break;
+ case 8:
+ name = "Litoral";
+ break;
+ case 9:
+ name = "Wele-Nzas";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Evros";
+ break;
+ case 2:
+ name = "Rodhopi";
+ break;
+ case 3:
+ name = "Xanthi";
+ break;
+ case 4:
+ name = "Drama";
+ break;
+ case 5:
+ name = "Serrai";
+ break;
+ case 6:
+ name = "Kilkis";
+ break;
+ case 7:
+ name = "Pella";
+ break;
+ case 8:
+ name = "Florina";
+ break;
+ case 9:
+ name = "Kastoria";
+ break;
+ case 10:
+ name = "Grevena";
+ break;
+ case 11:
+ name = "Kozani";
+ break;
+ case 12:
+ name = "Imathia";
+ break;
+ case 13:
+ name = "Thessaloniki";
+ break;
+ case 14:
+ name = "Kavala";
+ break;
+ case 15:
+ name = "Khalkidhiki";
+ break;
+ case 16:
+ name = "Pieria";
+ break;
+ case 17:
+ name = "Ioannina";
+ break;
+ case 18:
+ name = "Thesprotia";
+ break;
+ case 19:
+ name = "Preveza";
+ break;
+ case 20:
+ name = "Arta";
+ break;
+ case 21:
+ name = "Larisa";
+ break;
+ case 22:
+ name = "Trikala";
+ break;
+ case 23:
+ name = "Kardhitsa";
+ break;
+ case 24:
+ name = "Magnisia";
+ break;
+ case 25:
+ name = "Kerkira";
+ break;
+ case 26:
+ name = "Levkas";
+ break;
+ case 27:
+ name = "Kefallinia";
+ break;
+ case 28:
+ name = "Zakinthos";
+ break;
+ case 29:
+ name = "Fthiotis";
+ break;
+ case 30:
+ name = "Evritania";
+ break;
+ case 31:
+ name = "Aitolia kai Akarnania";
+ break;
+ case 32:
+ name = "Fokis";
+ break;
+ case 33:
+ name = "Voiotia";
+ break;
+ case 34:
+ name = "Evvoia";
+ break;
+ case 35:
+ name = "Attiki";
+ break;
+ case 36:
+ name = "Argolis";
+ break;
+ case 37:
+ name = "Korinthia";
+ break;
+ case 38:
+ name = "Akhaia";
+ break;
+ case 39:
+ name = "Ilia";
+ break;
+ case 40:
+ name = "Messinia";
+ break;
+ case 41:
+ name = "Arkadhia";
+ break;
+ case 42:
+ name = "Lakonia";
+ break;
+ case 43:
+ name = "Khania";
+ break;
+ case 44:
+ name = "Rethimni";
+ break;
+ case 45:
+ name = "Iraklion";
+ break;
+ case 46:
+ name = "Lasithi";
+ break;
+ case 47:
+ name = "Dhodhekanisos";
+ break;
+ case 48:
+ name = "Samos";
+ break;
+ case 49:
+ name = "Kikladhes";
+ break;
+ case 50:
+ name = "Khios";
+ break;
+ case 51:
+ name = "Lesvos";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GT") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Alta Verapaz";
+ break;
+ case 2:
+ name = "Baja Verapaz";
+ break;
+ case 3:
+ name = "Chimaltenango";
+ break;
+ case 4:
+ name = "Chiquimula";
+ break;
+ case 5:
+ name = "El Progreso";
+ break;
+ case 6:
+ name = "Escuintla";
+ break;
+ case 7:
+ name = "Guatemala";
+ break;
+ case 8:
+ name = "Huehuetenango";
+ break;
+ case 9:
+ name = "Izabal";
+ break;
+ case 10:
+ name = "Jalapa";
+ break;
+ case 11:
+ name = "Jutiapa";
+ break;
+ case 12:
+ name = "Peten";
+ break;
+ case 13:
+ name = "Quetzaltenango";
+ break;
+ case 14:
+ name = "Quiche";
+ break;
+ case 15:
+ name = "Retalhuleu";
+ break;
+ case 16:
+ name = "Sacatepequez";
+ break;
+ case 17:
+ name = "San Marcos";
+ break;
+ case 18:
+ name = "Santa Rosa";
+ break;
+ case 19:
+ name = "Solola";
+ break;
+ case 20:
+ name = "Suchitepequez";
+ break;
+ case 21:
+ name = "Totonicapan";
+ break;
+ case 22:
+ name = "Zacapa";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GW") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bafata";
+ break;
+ case 2:
+ name = "Quinara";
+ break;
+ case 4:
+ name = "Oio";
+ break;
+ case 5:
+ name = "Bolama";
+ break;
+ case 6:
+ name = "Cacheu";
+ break;
+ case 7:
+ name = "Tombali";
+ break;
+ case 10:
+ name = "Gabu";
+ break;
+ case 11:
+ name = "Bissau";
+ break;
+ case 12:
+ name = "Biombo";
+ break;
+ }
+ }
+ if (strcmp(country_code,"GY") == 0) {
+ switch (region_code2) {
+ case 10:
+ name = "Barima-Waini";
+ break;
+ case 11:
+ name = "Cuyuni-Mazaruni";
+ break;
+ case 12:
+ name = "Demerara-Mahaica";
+ break;
+ case 13:
+ name = "East Berbice-Corentyne";
+ break;
+ case 14:
+ name = "Essequibo Islands-West Demerara";
+ break;
+ case 15:
+ name = "Mahaica-Berbice";
+ break;
+ case 16:
+ name = "Pomeroon-Supenaam";
+ break;
+ case 17:
+ name = "Potaro-Siparuni";
+ break;
+ case 18:
+ name = "Upper Demerara-Berbice";
+ break;
+ case 19:
+ name = "Upper Takutu-Upper Essequibo";
+ break;
+ }
+ }
+ if (strcmp(country_code,"HN") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Atlantida";
+ break;
+ case 2:
+ name = "Choluteca";
+ break;
+ case 3:
+ name = "Colon";
+ break;
+ case 4:
+ name = "Comayagua";
+ break;
+ case 5:
+ name = "Copan";
+ break;
+ case 6:
+ name = "Cortes";
+ break;
+ case 7:
+ name = "El Paraiso";
+ break;
+ case 8:
+ name = "Francisco Morazan";
+ break;
+ case 9:
+ name = "Gracias a Dios";
+ break;
+ case 10:
+ name = "Intibuca";
+ break;
+ case 11:
+ name = "Islas de la Bahia";
+ break;
+ case 12:
+ name = "La Paz";
+ break;
+ case 13:
+ name = "Lempira";
+ break;
+ case 14:
+ name = "Ocotepeque";
+ break;
+ case 15:
+ name = "Olancho";
+ break;
+ case 16:
+ name = "Santa Barbara";
+ break;
+ case 17:
+ name = "Valle";
+ break;
+ case 18:
+ name = "Yoro";
+ break;
+ }
+ }
+ if (strcmp(country_code,"HR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bjelovarsko-Bilogorska";
+ break;
+ case 2:
+ name = "Brodsko-Posavska";
+ break;
+ case 3:
+ name = "Dubrovacko-Neretvanska";
+ break;
+ case 4:
+ name = "Istarska";
+ break;
+ case 5:
+ name = "Karlovacka";
+ break;
+ case 6:
+ name = "Koprivnicko-Krizevacka";
+ break;
+ case 7:
+ name = "Krapinsko-Zagorska";
+ break;
+ case 8:
+ name = "Licko-Senjska";
+ break;
+ case 9:
+ name = "Medimurska";
+ break;
+ case 10:
+ name = "Osjecko-Baranjska";
+ break;
+ case 11:
+ name = "Pozesko-Slavonska";
+ break;
+ case 12:
+ name = "Primorsko-Goranska";
+ break;
+ case 13:
+ name = "Sibensko-Kninska";
+ break;
+ case 14:
+ name = "Sisacko-Moslavacka";
+ break;
+ case 15:
+ name = "Splitsko-Dalmatinska";
+ break;
+ case 16:
+ name = "Varazdinska";
+ break;
+ case 17:
+ name = "Viroviticko-Podravska";
+ break;
+ case 18:
+ name = "Vukovarsko-Srijemska";
+ break;
+ case 19:
+ name = "Zadarska";
+ break;
+ case 20:
+ name = "Zagrebacka";
+ break;
+ case 21:
+ name = "Grad Zagreb";
+ break;
+ }
+ }
+ if (strcmp(country_code,"HT") == 0) {
+ switch (region_code2) {
+ case 3:
+ name = "Nord-Ouest";
+ break;
+ case 6:
+ name = "Artibonite";
+ break;
+ case 7:
+ name = "Centre";
+ break;
+ case 8:
+ name = "Grand' Anse";
+ break;
+ case 9:
+ name = "Nord";
+ break;
+ case 10:
+ name = "Nord-Est";
+ break;
+ case 11:
+ name = "Ouest";
+ break;
+ case 12:
+ name = "Sud";
+ break;
+ case 13:
+ name = "Sud-Est";
+ break;
+ }
+ }
+ if (strcmp(country_code,"HU") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bacs-Kiskun";
+ break;
+ case 2:
+ name = "Baranya";
+ break;
+ case 3:
+ name = "Bekes";
+ break;
+ case 4:
+ name = "Borsod-Abauj-Zemplen";
+ break;
+ case 5:
+ name = "Budapest";
+ break;
+ case 6:
+ name = "Csongrad";
+ break;
+ case 7:
+ name = "Debrecen";
+ break;
+ case 8:
+ name = "Fejer";
+ break;
+ case 9:
+ name = "Gyor-Moson-Sopron";
+ break;
+ case 10:
+ name = "Hajdu-Bihar";
+ break;
+ case 11:
+ name = "Heves";
+ break;
+ case 12:
+ name = "Komarom-Esztergom";
+ break;
+ case 13:
+ name = "Miskolc";
+ break;
+ case 14:
+ name = "Nograd";
+ break;
+ case 15:
+ name = "Pecs";
+ break;
+ case 16:
+ name = "Pest";
+ break;
+ case 17:
+ name = "Somogy";
+ break;
+ case 18:
+ name = "Szabolcs-Szatmar-Bereg";
+ break;
+ case 19:
+ name = "Szeged";
+ break;
+ case 20:
+ name = "Jasz-Nagykun-Szolnok";
+ break;
+ case 21:
+ name = "Tolna";
+ break;
+ case 22:
+ name = "Vas";
+ break;
+ case 23:
+ name = "Veszprem";
+ break;
+ case 24:
+ name = "Zala";
+ break;
+ case 25:
+ name = "Gyor";
+ break;
+ case 26:
+ name = "Bekescsaba";
+ break;
+ case 27:
+ name = "Dunaujvaros";
+ break;
+ case 28:
+ name = "Eger";
+ break;
+ case 29:
+ name = "Hodmezovasarhely";
+ break;
+ case 30:
+ name = "Kaposvar";
+ break;
+ case 31:
+ name = "Kecskemet";
+ break;
+ case 32:
+ name = "Nagykanizsa";
+ break;
+ case 33:
+ name = "Nyiregyhaza";
+ break;
+ case 34:
+ name = "Sopron";
+ break;
+ case 35:
+ name = "Szekesfehervar";
+ break;
+ case 36:
+ name = "Szolnok";
+ break;
+ case 37:
+ name = "Szombathely";
+ break;
+ case 38:
+ name = "Tatabanya";
+ break;
+ case 39:
+ name = "Veszprem";
+ break;
+ case 40:
+ name = "Zalaegerszeg";
+ break;
+ }
+ }
+ if (strcmp(country_code,"ID") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Aceh";
+ break;
+ case 2:
+ name = "Bali";
+ break;
+ case 3:
+ name = "Bengkulu";
+ break;
+ case 4:
+ name = "Jakarta Raya";
+ break;
+ case 5:
+ name = "Jambi";
+ break;
+ case 7:
+ name = "Jawa Tengah";
+ break;
+ case 8:
+ name = "Jawa Timur";
+ break;
+ case 9:
+ name = "Papua";
+ break;
+ case 10:
+ name = "Yogyakarta";
+ break;
+ case 11:
+ name = "Kalimantan Barat";
+ break;
+ case 12:
+ name = "Kalimantan Selatan";
+ break;
+ case 13:
+ name = "Kalimantan Tengah";
+ break;
+ case 14:
+ name = "Kalimantan Timur";
+ break;
+ case 15:
+ name = "Lampung";
+ break;
+ case 17:
+ name = "Nusa Tenggara Barat";
+ break;
+ case 18:
+ name = "Nusa Tenggara Timur";
+ break;
+ case 19:
+ name = "Riau";
+ break;
+ case 20:
+ name = "Sulawesi Selatan";
+ break;
+ case 21:
+ name = "Sulawesi Tengah";
+ break;
+ case 22:
+ name = "Sulawesi Tenggara";
+ break;
+ case 24:
+ name = "Sumatera Barat";
+ break;
+ case 26:
+ name = "Sumatera Utara";
+ break;
+ case 28:
+ name = "Maluku";
+ break;
+ case 29:
+ name = "Maluku Utara";
+ break;
+ case 30:
+ name = "Jawa Barat";
+ break;
+ case 31:
+ name = "Sulawesi Utara";
+ break;
+ case 32:
+ name = "Sumatera Selatan";
+ break;
+ case 33:
+ name = "Banten";
+ break;
+ case 34:
+ name = "Gorontalo";
+ break;
+ case 35:
+ name = "Kepulauan Bangka Belitung";
+ break;
+ }
+ }
+ if (strcmp(country_code,"IE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Carlow";
+ break;
+ case 2:
+ name = "Cavan";
+ break;
+ case 3:
+ name = "Clare";
+ break;
+ case 4:
+ name = "Cork";
+ break;
+ case 6:
+ name = "Donegal";
+ break;
+ case 7:
+ name = "Dublin";
+ break;
+ case 10:
+ name = "Galway";
+ break;
+ case 11:
+ name = "Kerry";
+ break;
+ case 12:
+ name = "Kildare";
+ break;
+ case 13:
+ name = "Kilkenny";
+ break;
+ case 14:
+ name = "Leitrim";
+ break;
+ case 15:
+ name = "Laois";
+ break;
+ case 16:
+ name = "Limerick";
+ break;
+ case 18:
+ name = "Longford";
+ break;
+ case 19:
+ name = "Louth";
+ break;
+ case 20:
+ name = "Mayo";
+ break;
+ case 21:
+ name = "Meath";
+ break;
+ case 22:
+ name = "Monaghan";
+ break;
+ case 23:
+ name = "Offaly";
+ break;
+ case 24:
+ name = "Roscommon";
+ break;
+ case 25:
+ name = "Sligo";
+ break;
+ case 26:
+ name = "Tipperary";
+ break;
+ case 27:
+ name = "Waterford";
+ break;
+ case 29:
+ name = "Westmeath";
+ break;
+ case 30:
+ name = "Wexford";
+ break;
+ case 31:
+ name = "Wicklow";
+ break;
+ }
+ }
+ if (strcmp(country_code,"IL") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "HaDarom";
+ break;
+ case 2:
+ name = "HaMerkaz";
+ break;
+ case 3:
+ name = "HaZafon";
+ break;
+ case 4:
+ name = "Hefa";
+ break;
+ case 5:
+ name = "Tel Aviv";
+ break;
+ case 6:
+ name = "Yerushalayim";
+ break;
+ }
+ }
+ if (strcmp(country_code,"IN") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Andaman and Nicobar Islands";
+ break;
+ case 2:
+ name = "Andhra Pradesh";
+ break;
+ case 3:
+ name = "Assam";
+ break;
+ case 5:
+ name = "Chandigarh";
+ break;
+ case 6:
+ name = "Dadra and Nagar Haveli";
+ break;
+ case 7:
+ name = "Delhi";
+ break;
+ case 9:
+ name = "Gujarat";
+ break;
+ case 10:
+ name = "Haryana";
+ break;
+ case 11:
+ name = "Himachal Pradesh";
+ break;
+ case 12:
+ name = "Jammu and Kashmir";
+ break;
+ case 13:
+ name = "Kerala";
+ break;
+ case 14:
+ name = "Lakshadweep";
+ break;
+ case 16:
+ name = "Maharashtra";
+ break;
+ case 17:
+ name = "Manipur";
+ break;
+ case 18:
+ name = "Meghalaya";
+ break;
+ case 19:
+ name = "Karnataka";
+ break;
+ case 20:
+ name = "Nagaland";
+ break;
+ case 21:
+ name = "Orissa";
+ break;
+ case 22:
+ name = "Pondicherry";
+ break;
+ case 23:
+ name = "Punjab";
+ break;
+ case 24:
+ name = "Rajasthan";
+ break;
+ case 25:
+ name = "Tamil Nadu";
+ break;
+ case 26:
+ name = "Tripura";
+ break;
+ case 28:
+ name = "West Bengal";
+ break;
+ case 29:
+ name = "Sikkim";
+ break;
+ case 30:
+ name = "Arunachal Pradesh";
+ break;
+ case 31:
+ name = "Mizoram";
+ break;
+ case 32:
+ name = "Daman and Diu";
+ break;
+ case 33:
+ name = "Goa";
+ break;
+ case 34:
+ name = "Bihar";
+ break;
+ case 35:
+ name = "Madhya Pradesh";
+ break;
+ case 36:
+ name = "Uttar Pradesh";
+ break;
+ case 37:
+ name = "Chhattisgarh";
+ break;
+ case 38:
+ name = "Jharkhand";
+ break;
+ case 39:
+ name = "Uttaranchal";
+ break;
+ }
+ }
+ if (strcmp(country_code,"IQ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Al Anbar";
+ break;
+ case 2:
+ name = "Al Basrah";
+ break;
+ case 3:
+ name = "Al Muthanna";
+ break;
+ case 4:
+ name = "Al Qadisiyah";
+ break;
+ case 5:
+ name = "As Sulaymaniyah";
+ break;
+ case 6:
+ name = "Babil";
+ break;
+ case 7:
+ name = "Baghdad";
+ break;
+ case 8:
+ name = "Dahuk";
+ break;
+ case 9:
+ name = "Dhi Qar";
+ break;
+ case 10:
+ name = "Diyala";
+ break;
+ case 11:
+ name = "Arbil";
+ break;
+ case 12:
+ name = "Karbala'";
+ break;
+ case 13:
+ name = "At Ta'mim";
+ break;
+ case 14:
+ name = "Maysan";
+ break;
+ case 15:
+ name = "Ninawa";
+ break;
+ case 16:
+ name = "Wasit";
+ break;
+ case 17:
+ name = "An Najaf";
+ break;
+ case 18:
+ name = "Salah ad Din";
+ break;
+ }
+ }
+ if (strcmp(country_code,"IR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Azarbayjan-e Bakhtari";
+ break;
+ case 2:
+ name = "Azarbayjan-e Khavari";
+ break;
+ case 3:
+ name = "Chahar Mahall va Bakhtiari";
+ break;
+ case 4:
+ name = "Sistan va Baluchestan";
+ break;
+ case 5:
+ name = "Kohkiluyeh va Buyer Ahmadi";
+ break;
+ case 7:
+ name = "Fars";
+ break;
+ case 8:
+ name = "Gilan";
+ break;
+ case 9:
+ name = "Hamadan";
+ break;
+ case 10:
+ name = "Ilam";
+ break;
+ case 11:
+ name = "Hormozgan";
+ break;
+ case 13:
+ name = "Bakhtaran";
+ break;
+ case 15:
+ name = "Khuzestan";
+ break;
+ case 16:
+ name = "Kordestan";
+ break;
+ case 22:
+ name = "Bushehr";
+ break;
+ case 23:
+ name = "Lorestan";
+ break;
+ case 25:
+ name = "Semnan";
+ break;
+ case 26:
+ name = "Tehran";
+ break;
+ case 28:
+ name = "Esfahan";
+ break;
+ case 29:
+ name = "Kerman";
+ break;
+ case 30:
+ name = "Khorasan";
+ break;
+ case 31:
+ name = "Yazd";
+ break;
+ case 32:
+ name = "Ardabil";
+ break;
+ case 34:
+ name = "Markazi";
+ break;
+ case 35:
+ name = "Mazandaran";
+ break;
+ case 36:
+ name = "Zanjan";
+ break;
+ case 37:
+ name = "Golestan";
+ break;
+ case 38:
+ name = "Qazvin";
+ break;
+ case 39:
+ name = "Qom";
+ break;
+ }
+ }
+ if (strcmp(country_code,"IS") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Akranes";
+ break;
+ case 2:
+ name = "Akureyri";
+ break;
+ case 3:
+ name = "Arnessysla";
+ break;
+ case 4:
+ name = "Austur-Bardastrandarsysla";
+ break;
+ case 5:
+ name = "Austur-Hunavatnssysla";
+ break;
+ case 6:
+ name = "Austur-Skaftafellssysla";
+ break;
+ case 7:
+ name = "Borgarfjardarsysla";
+ break;
+ case 8:
+ name = "Dalasysla";
+ break;
+ case 9:
+ name = "Eyjafjardarsysla";
+ break;
+ case 10:
+ name = "Gullbringusysla";
+ break;
+ case 11:
+ name = "Hafnarfjordur";
+ break;
+ case 12:
+ name = "Husavik";
+ break;
+ case 13:
+ name = "Isafjordur";
+ break;
+ case 14:
+ name = "Keflavik";
+ break;
+ case 15:
+ name = "Kjosarsysla";
+ break;
+ case 16:
+ name = "Kopavogur";
+ break;
+ case 17:
+ name = "Myrasysla";
+ break;
+ case 18:
+ name = "Neskaupstadur";
+ break;
+ case 19:
+ name = "Nordur-Isafjardarsysla";
+ break;
+ case 20:
+ name = "Nordur-Mulasysla";
+ break;
+ case 21:
+ name = "Nordur-Tingeyjarsysla";
+ break;
+ case 22:
+ name = "Olafsfjordur";
+ break;
+ case 23:
+ name = "Rangarvallasysla";
+ break;
+ case 24:
+ name = "Reykjavik";
+ break;
+ case 25:
+ name = "Saudarkrokur";
+ break;
+ case 26:
+ name = "Seydisfjordur";
+ break;
+ case 27:
+ name = "Siglufjordur";
+ break;
+ case 28:
+ name = "Skagafjardarsysla";
+ break;
+ case 29:
+ name = "Snafellsnes- og Hnappadalssysla";
+ break;
+ case 30:
+ name = "Strandasysla";
+ break;
+ case 31:
+ name = "Sudur-Mulasysla";
+ break;
+ case 32:
+ name = "Sudur-Tingeyjarsysla";
+ break;
+ case 33:
+ name = "Vestmannaeyjar";
+ break;
+ case 34:
+ name = "Vestur-Bardastrandarsysla";
+ break;
+ case 35:
+ name = "Vestur-Hunavatnssysla";
+ break;
+ case 36:
+ name = "Vestur-Isafjardarsysla";
+ break;
+ case 37:
+ name = "Vestur-Skaftafellssysla";
+ break;
+ }
+ }
+ if (strcmp(country_code,"IT") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Abruzzi";
+ break;
+ case 2:
+ name = "Basilicata";
+ break;
+ case 3:
+ name = "Calabria";
+ break;
+ case 4:
+ name = "Campania";
+ break;
+ case 5:
+ name = "Emilia-Romagna";
+ break;
+ case 6:
+ name = "Friuli-Venezia Giulia";
+ break;
+ case 7:
+ name = "Lazio";
+ break;
+ case 8:
+ name = "Liguria";
+ break;
+ case 9:
+ name = "Lombardia";
+ break;
+ case 10:
+ name = "Marche";
+ break;
+ case 11:
+ name = "Molise";
+ break;
+ case 12:
+ name = "Piemonte";
+ break;
+ case 13:
+ name = "Puglia";
+ break;
+ case 14:
+ name = "Sardegna";
+ break;
+ case 15:
+ name = "Sicilia";
+ break;
+ case 16:
+ name = "Toscana";
+ break;
+ case 17:
+ name = "Trentino-Alto Adige";
+ break;
+ case 18:
+ name = "Umbria";
+ break;
+ case 19:
+ name = "Valle d'Aosta";
+ break;
+ case 20:
+ name = "Veneto";
+ break;
+ }
+ }
+ if (strcmp(country_code,"JM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Clarendon";
+ break;
+ case 2:
+ name = "Hanover";
+ break;
+ case 4:
+ name = "Manchester";
+ break;
+ case 7:
+ name = "Portland";
+ break;
+ case 8:
+ name = "Saint Andrew";
+ break;
+ case 9:
+ name = "Saint Ann";
+ break;
+ case 10:
+ name = "Saint Catherine";
+ break;
+ case 11:
+ name = "Saint Elizabeth";
+ break;
+ case 12:
+ name = "Saint James";
+ break;
+ case 13:
+ name = "Saint Mary";
+ break;
+ case 14:
+ name = "Saint Thomas";
+ break;
+ case 15:
+ name = "Trelawny";
+ break;
+ case 16:
+ name = "Westmoreland";
+ break;
+ case 17:
+ name = "Kingston";
+ break;
+ }
+ }
+ if (strcmp(country_code,"JO") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Al Balqa'";
+ break;
+ case 7:
+ name = "Ma";
+ break;
+ case 9:
+ name = "Al Karak";
+ break;
+ case 10:
+ name = "Al Mafraq";
+ break;
+ case 12:
+ name = "At Tafilah";
+ break;
+ case 13:
+ name = "Az Zarqa";
+ break;
+ case 14:
+ name = "Irbid";
+ break;
+ case 16:
+ name = "Amman";
+ break;
+ }
+ }
+ if (strcmp(country_code,"JP") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Aichi";
+ break;
+ case 2:
+ name = "Akita";
+ break;
+ case 3:
+ name = "Aomori";
+ break;
+ case 4:
+ name = "Chiba";
+ break;
+ case 5:
+ name = "Ehime";
+ break;
+ case 6:
+ name = "Fukui";
+ break;
+ case 7:
+ name = "Fukuoka";
+ break;
+ case 8:
+ name = "Fukushima";
+ break;
+ case 9:
+ name = "Gifu";
+ break;
+ case 10:
+ name = "Gumma";
+ break;
+ case 11:
+ name = "Hiroshima";
+ break;
+ case 12:
+ name = "Hokkaido";
+ break;
+ case 13:
+ name = "Hyogo";
+ break;
+ case 14:
+ name = "Ibaraki";
+ break;
+ case 15:
+ name = "Ishikawa";
+ break;
+ case 16:
+ name = "Iwate";
+ break;
+ case 17:
+ name = "Kagawa";
+ break;
+ case 18:
+ name = "Kagoshima";
+ break;
+ case 19:
+ name = "Kanagawa";
+ break;
+ case 20:
+ name = "Kochi";
+ break;
+ case 21:
+ name = "Kumamoto";
+ break;
+ case 22:
+ name = "Kyoto";
+ break;
+ case 23:
+ name = "Mie";
+ break;
+ case 24:
+ name = "Miyagi";
+ break;
+ case 25:
+ name = "Miyazaki";
+ break;
+ case 26:
+ name = "Nagano";
+ break;
+ case 27:
+ name = "Nagasaki";
+ break;
+ case 28:
+ name = "Nara";
+ break;
+ case 29:
+ name = "Niigata";
+ break;
+ case 30:
+ name = "Oita";
+ break;
+ case 31:
+ name = "Okayama";
+ break;
+ case 32:
+ name = "Osaka";
+ break;
+ case 33:
+ name = "Saga";
+ break;
+ case 34:
+ name = "Saitama";
+ break;
+ case 35:
+ name = "Shiga";
+ break;
+ case 36:
+ name = "Shimane";
+ break;
+ case 37:
+ name = "Shizuoka";
+ break;
+ case 38:
+ name = "Tochigi";
+ break;
+ case 39:
+ name = "Tokushima";
+ break;
+ case 40:
+ name = "Tokyo";
+ break;
+ case 41:
+ name = "Tottori";
+ break;
+ case 42:
+ name = "Toyama";
+ break;
+ case 43:
+ name = "Wakayama";
+ break;
+ case 44:
+ name = "Yamagata";
+ break;
+ case 45:
+ name = "Yamaguchi";
+ break;
+ case 46:
+ name = "Yamanashi";
+ break;
+ case 47:
+ name = "Okinawa";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Central";
+ break;
+ case 2:
+ name = "Coast";
+ break;
+ case 3:
+ name = "Eastern";
+ break;
+ case 5:
+ name = "Nairobi Area";
+ break;
+ case 6:
+ name = "North-Eastern";
+ break;
+ case 7:
+ name = "Nyanza";
+ break;
+ case 8:
+ name = "Rift Valley";
+ break;
+ case 9:
+ name = "Western";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KG") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bishkek";
+ break;
+ case 2:
+ name = "Chuy";
+ break;
+ case 3:
+ name = "Jalal-Abad";
+ break;
+ case 4:
+ name = "Naryn";
+ break;
+ case 6:
+ name = "Talas";
+ break;
+ case 7:
+ name = "Ysyk-Kol";
+ break;
+ case 8:
+ name = "Osh";
+ break;
+ case 9:
+ name = "Batken";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KH") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Kampong Cham";
+ break;
+ case 3:
+ name = "Kampong Chhnang";
+ break;
+ case 4:
+ name = "Kampong Spoe";
+ break;
+ case 5:
+ name = "Kampong Thum";
+ break;
+ case 6:
+ name = "Kampot";
+ break;
+ case 7:
+ name = "Kandal";
+ break;
+ case 8:
+ name = "Kaoh Kong";
+ break;
+ case 9:
+ name = "Kracheh";
+ break;
+ case 10:
+ name = "Mondol Kiri";
+ break;
+ case 11:
+ name = "Phnum Penh";
+ break;
+ case 12:
+ name = "Pouthisat";
+ break;
+ case 13:
+ name = "Preah Vihear";
+ break;
+ case 14:
+ name = "Prey Veng";
+ break;
+ case 15:
+ name = "Rotanokiri";
+ break;
+ case 16:
+ name = "Siemreab-Otdar Meanchey";
+ break;
+ case 17:
+ name = "Stoeng Treng";
+ break;
+ case 18:
+ name = "Svay Rieng";
+ break;
+ case 19:
+ name = "Takev";
+ break;
+ case 29:
+ name = "Batdambang";
+ break;
+ case 30:
+ name = "Pailin";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KI") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Gilbert Islands";
+ break;
+ case 2:
+ name = "Line Islands";
+ break;
+ case 3:
+ name = "Phoenix Islands";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Anjouan";
+ break;
+ case 2:
+ name = "Grande Comore";
+ break;
+ case 3:
+ name = "Moheli";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KN") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Christ Church Nichola Town";
+ break;
+ case 2:
+ name = "Saint Anne Sandy Point";
+ break;
+ case 3:
+ name = "Saint George Basseterre";
+ break;
+ case 4:
+ name = "Saint George Gingerland";
+ break;
+ case 5:
+ name = "Saint James Windward";
+ break;
+ case 6:
+ name = "Saint John Capisterre";
+ break;
+ case 7:
+ name = "Saint John Figtree";
+ break;
+ case 8:
+ name = "Saint Mary Cayon";
+ break;
+ case 9:
+ name = "Saint Paul Capisterre";
+ break;
+ case 10:
+ name = "Saint Paul Charlestown";
+ break;
+ case 11:
+ name = "Saint Peter Basseterre";
+ break;
+ case 12:
+ name = "Saint Thomas Lowland";
+ break;
+ case 13:
+ name = "Saint Thomas Middle Island";
+ break;
+ case 15:
+ name = "Trinity Palmetto Point";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KP") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Chagang-do";
+ break;
+ case 3:
+ name = "Hamgyong-namdo";
+ break;
+ case 6:
+ name = "Hwanghae-namdo";
+ break;
+ case 7:
+ name = "Hwanghae-bukto";
+ break;
+ case 8:
+ name = "Kaesong-si";
+ break;
+ case 9:
+ name = "Kangwon-do";
+ break;
+ case 11:
+ name = "P'yongan-bukto";
+ break;
+ case 12:
+ name = "P'yongyang-si";
+ break;
+ case 13:
+ name = "Yanggang-do";
+ break;
+ case 14:
+ name = "Namp'o-si";
+ break;
+ case 15:
+ name = "P'yongan-namdo";
+ break;
+ case 17:
+ name = "Hamgyong-bukto";
+ break;
+ case 18:
+ name = "Najin Sonbong-si";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Cheju-do";
+ break;
+ case 3:
+ name = "Cholla-bukto";
+ break;
+ case 5:
+ name = "Ch'ungch'ong-bukto";
+ break;
+ case 6:
+ name = "Kangwon-do";
+ break;
+ case 10:
+ name = "Pusan-jikhalsi";
+ break;
+ case 11:
+ name = "Seoul-t'ukpyolsi";
+ break;
+ case 12:
+ name = "Inch'on-jikhalsi";
+ break;
+ case 13:
+ name = "Kyonggi-do";
+ break;
+ case 14:
+ name = "Kyongsang-bukto";
+ break;
+ case 15:
+ name = "Taegu-jikhalsi";
+ break;
+ case 16:
+ name = "Cholla-namdo";
+ break;
+ case 17:
+ name = "Ch'ungch'ong-namdo";
+ break;
+ case 18:
+ name = "Kwangju-jikhalsi";
+ break;
+ case 19:
+ name = "Taejon-jikhalsi";
+ break;
+ case 20:
+ name = "Kyongsang-namdo";
+ break;
+ case 21:
+ name = "Ulsan-gwangyoksi";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KW") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Al Ahmadi";
+ break;
+ case 2:
+ name = "Al Kuwayt";
+ break;
+ case 3:
+ name = "Hawalli";
+ break;
+ case 5:
+ name = "Al Jahra";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KY") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Creek";
+ break;
+ case 2:
+ name = "Eastern";
+ break;
+ case 3:
+ name = "Midland";
+ break;
+ case 4:
+ name = "South Town";
+ break;
+ case 5:
+ name = "Spot Bay";
+ break;
+ case 6:
+ name = "Stake Bay";
+ break;
+ case 7:
+ name = "West End";
+ break;
+ case 8:
+ name = "Western";
+ break;
+ }
+ }
+ if (strcmp(country_code,"KZ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Almaty";
+ break;
+ case 2:
+ name = "Almaty City";
+ break;
+ case 3:
+ name = "Aqmola";
+ break;
+ case 4:
+ name = "Aqtbe";
+ break;
+ case 5:
+ name = "Astana";
+ break;
+ case 6:
+ name = "Atyrau";
+ break;
+ case 7:
+ name = "West Kazakhstan";
+ break;
+ case 8:
+ name = "Bayqonyr";
+ break;
+ case 9:
+ name = "Mangghystau";
+ break;
+ case 10:
+ name = "South Kazakhstan";
+ break;
+ case 11:
+ name = "Pavlodar";
+ break;
+ case 12:
+ name = "Qaraghandy";
+ break;
+ case 13:
+ name = "Qostanay";
+ break;
+ case 14:
+ name = "Qyzylorda";
+ break;
+ case 15:
+ name = "East Kazakhstan";
+ break;
+ case 16:
+ name = "North Kazakhstan";
+ break;
+ case 17:
+ name = "Zhambyl";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LA") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Attapu";
+ break;
+ case 2:
+ name = "Champasak";
+ break;
+ case 3:
+ name = "Houaphan";
+ break;
+ case 4:
+ name = "Khammouan";
+ break;
+ case 5:
+ name = "Louang Namtha";
+ break;
+ case 7:
+ name = "Oudomxai";
+ break;
+ case 8:
+ name = "Phongsali";
+ break;
+ case 9:
+ name = "Saravan";
+ break;
+ case 10:
+ name = "Savannakhet";
+ break;
+ case 11:
+ name = "Vientiane";
+ break;
+ case 13:
+ name = "Xaignabouri";
+ break;
+ case 14:
+ name = "Xiangkhoang";
+ break;
+ case 17:
+ name = "Louangphrabang";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LB") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Beqaa";
+ break;
+ case 3:
+ name = "Liban-Nord";
+ break;
+ case 4:
+ name = "Beyrouth";
+ break;
+ case 5:
+ name = "Mont-Liban";
+ break;
+ case 6:
+ name = "Liban-Sud";
+ break;
+ case 7:
+ name = "Nabatiye";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LC") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Anse-la-Raye";
+ break;
+ case 2:
+ name = "Dauphin";
+ break;
+ case 3:
+ name = "Castries";
+ break;
+ case 4:
+ name = "Choiseul";
+ break;
+ case 5:
+ name = "Dennery";
+ break;
+ case 6:
+ name = "Gros-Islet";
+ break;
+ case 7:
+ name = "Laborie";
+ break;
+ case 8:
+ name = "Micoud";
+ break;
+ case 9:
+ name = "Soufriere";
+ break;
+ case 10:
+ name = "Vieux-Fort";
+ break;
+ case 11:
+ name = "Praslin";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LI") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Balzers";
+ break;
+ case 2:
+ name = "Eschen";
+ break;
+ case 3:
+ name = "Gamprin";
+ break;
+ case 4:
+ name = "Mauren";
+ break;
+ case 5:
+ name = "Planken";
+ break;
+ case 6:
+ name = "Ruggell";
+ break;
+ case 7:
+ name = "Schaan";
+ break;
+ case 8:
+ name = "Schellenberg";
+ break;
+ case 9:
+ name = "Triesen";
+ break;
+ case 10:
+ name = "Triesenberg";
+ break;
+ case 11:
+ name = "Vaduz";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LK") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Amparai";
+ break;
+ case 2:
+ name = "Anuradhapura";
+ break;
+ case 3:
+ name = "Badulla";
+ break;
+ case 4:
+ name = "Batticaloa";
+ break;
+ case 6:
+ name = "Galle";
+ break;
+ case 7:
+ name = "Hambantota";
+ break;
+ case 9:
+ name = "Kalutara";
+ break;
+ case 10:
+ name = "Kandy";
+ break;
+ case 11:
+ name = "Kegalla";
+ break;
+ case 12:
+ name = "Kurunegala";
+ break;
+ case 14:
+ name = "Matale";
+ break;
+ case 15:
+ name = "Matara";
+ break;
+ case 16:
+ name = "Moneragala";
+ break;
+ case 17:
+ name = "Nuwara Eliya";
+ break;
+ case 18:
+ name = "Polonnaruwa";
+ break;
+ case 19:
+ name = "Puttalam";
+ break;
+ case 20:
+ name = "Ratnapura";
+ break;
+ case 21:
+ name = "Trincomalee";
+ break;
+ case 23:
+ name = "Colombo";
+ break;
+ case 24:
+ name = "Gampaha";
+ break;
+ case 25:
+ name = "Jaffna";
+ break;
+ case 26:
+ name = "Mannar";
+ break;
+ case 27:
+ name = "Mullaittivu";
+ break;
+ case 28:
+ name = "Vavuniya";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bong";
+ break;
+ case 2:
+ name = "Grand Jide";
+ break;
+ case 4:
+ name = "Grand Cape Mount";
+ break;
+ case 5:
+ name = "Lofa";
+ break;
+ case 6:
+ name = "Maryland";
+ break;
+ case 7:
+ name = "Monrovia";
+ break;
+ case 9:
+ name = "Nimba";
+ break;
+ case 10:
+ name = "Sino";
+ break;
+ case 11:
+ name = "Grand Bassa";
+ break;
+ case 14:
+ name = "Montserrado";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LS") == 0) {
+ switch (region_code2) {
+ case 10:
+ name = "Berea";
+ break;
+ case 11:
+ name = "Butha-Buthe";
+ break;
+ case 12:
+ name = "Leribe";
+ break;
+ case 13:
+ name = "Mafeteng";
+ break;
+ case 14:
+ name = "Maseru";
+ break;
+ case 15:
+ name = "Mohales Hoek";
+ break;
+ case 16:
+ name = "Mokhotlong";
+ break;
+ case 17:
+ name = "Qachas Nek";
+ break;
+ case 18:
+ name = "Quthing";
+ break;
+ case 19:
+ name = "Thaba-Tseka";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LT") == 0) {
+ switch (region_code2) {
+ case 56:
+ name = "Alytaus Apskritis";
+ break;
+ case 57:
+ name = "Kauno Apskritis";
+ break;
+ case 58:
+ name = "Klaipedos Apskritis";
+ break;
+ case 59:
+ name = "Marijampoles Apskritis";
+ break;
+ case 60:
+ name = "Panevezio Apskritis";
+ break;
+ case 61:
+ name = "Siauliu Apskritis";
+ break;
+ case 62:
+ name = "Taurages Apskritis";
+ break;
+ case 63:
+ name = "Telsiu Apskritis";
+ break;
+ case 64:
+ name = "Utenos Apskritis";
+ break;
+ case 65:
+ name = "Vilniaus Apskritis";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LU") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Diekirch";
+ break;
+ case 2:
+ name = "Grevenmacher";
+ break;
+ case 3:
+ name = "Luxembourg";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LV") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Aizkraukles";
+ break;
+ case 2:
+ name = "Aluksnes";
+ break;
+ case 3:
+ name = "Balvu";
+ break;
+ case 4:
+ name = "Bauskas";
+ break;
+ case 5:
+ name = "Csu";
+ break;
+ case 6:
+ name = "Daugavpils";
+ break;
+ case 7:
+ name = "Daugavpils";
+ break;
+ case 8:
+ name = "Dobeles";
+ break;
+ case 9:
+ name = "Gulbenes";
+ break;
+ case 10:
+ name = "Jkabpils";
+ break;
+ case 11:
+ name = "Jelgava";
+ break;
+ case 12:
+ name = "Jelgavas";
+ break;
+ case 13:
+ name = "Jurmala";
+ break;
+ case 14:
+ name = "Krslavas";
+ break;
+ case 15:
+ name = "Kuldigas";
+ break;
+ case 16:
+ name = "Liepja";
+ break;
+ case 17:
+ name = "Liepjas";
+ break;
+ case 18:
+ name = "Limbazu";
+ break;
+ case 19:
+ name = "Ludzas";
+ break;
+ case 20:
+ name = "Madonas";
+ break;
+ case 21:
+ name = "Ogres";
+ break;
+ case 22:
+ name = "Preilu";
+ break;
+ case 23:
+ name = "Rzekne";
+ break;
+ case 24:
+ name = "Rzeknes";
+ break;
+ case 25:
+ name = "Riga";
+ break;
+ case 26:
+ name = "Rigas";
+ break;
+ case 27:
+ name = "Saldus";
+ break;
+ case 28:
+ name = "Talsu";
+ break;
+ case 29:
+ name = "Tukuma";
+ break;
+ case 30:
+ name = "Valkas";
+ break;
+ case 31:
+ name = "Valmieras";
+ break;
+ case 32:
+ name = "Ventspils";
+ break;
+ case 33:
+ name = "Ventspils";
+ break;
+ }
+ }
+ if (strcmp(country_code,"LY") == 0) {
+ switch (region_code2) {
+ case 3:
+ name = "Al";
+ break;
+ case 5:
+ name = "Al Jufrah";
+ break;
+ case 8:
+ name = "Al Kufrah";
+ break;
+ case 13:
+ name = "Ash Shati'";
+ break;
+ case 30:
+ name = "Murzuq";
+ break;
+ case 34:
+ name = "Sabha";
+ break;
+ case 41:
+ name = "Tarhunah";
+ break;
+ case 42:
+ name = "Tubruq";
+ break;
+ case 45:
+ name = "Zlitan";
+ break;
+ case 47:
+ name = "Ajdabiya";
+ break;
+ case 48:
+ name = "Al Fatih";
+ break;
+ case 49:
+ name = "Al Jabal al Akhdar";
+ break;
+ case 50:
+ name = "Al Khums";
+ break;
+ case 51:
+ name = "An Nuqat al Khams";
+ break;
+ case 52:
+ name = "Awbari";
+ break;
+ case 53:
+ name = "Az Zawiyah";
+ break;
+ case 54:
+ name = "Banghazi";
+ break;
+ case 55:
+ name = "Darnah";
+ break;
+ case 56:
+ name = "Ghadamis";
+ break;
+ case 57:
+ name = "Gharyan";
+ break;
+ case 58:
+ name = "Misratah";
+ break;
+ case 59:
+ name = "Sawfajjin";
+ break;
+ case 60:
+ name = "Surt";
+ break;
+ case 61:
+ name = "Tarabulus";
+ break;
+ case 62:
+ name = "Yafran";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MA") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Agadir";
+ break;
+ case 2:
+ name = "Al Hoceima";
+ break;
+ case 3:
+ name = "Azilal";
+ break;
+ case 4:
+ name = "Ben Slimane";
+ break;
+ case 5:
+ name = "Beni Mellal";
+ break;
+ case 6:
+ name = "Boulemane";
+ break;
+ case 7:
+ name = "Casablanca";
+ break;
+ case 8:
+ name = "Chaouen";
+ break;
+ case 9:
+ name = "El Jadida";
+ break;
+ case 10:
+ name = "El Kelaa des Srarhna";
+ break;
+ case 11:
+ name = "Er Rachidia";
+ break;
+ case 12:
+ name = "Essaouira";
+ break;
+ case 13:
+ name = "Fes";
+ break;
+ case 14:
+ name = "Figuig";
+ break;
+ case 15:
+ name = "Kenitra";
+ break;
+ case 16:
+ name = "Khemisset";
+ break;
+ case 17:
+ name = "Khenifra";
+ break;
+ case 18:
+ name = "Khouribga";
+ break;
+ case 19:
+ name = "Marrakech";
+ break;
+ case 20:
+ name = "Meknes";
+ break;
+ case 21:
+ name = "Nador";
+ break;
+ case 22:
+ name = "Ouarzazate";
+ break;
+ case 23:
+ name = "Oujda";
+ break;
+ case 24:
+ name = "Rabat-Sale";
+ break;
+ case 25:
+ name = "Safi";
+ break;
+ case 26:
+ name = "Settat";
+ break;
+ case 27:
+ name = "Tanger";
+ break;
+ case 29:
+ name = "Tata";
+ break;
+ case 30:
+ name = "Taza";
+ break;
+ case 32:
+ name = "Tiznit";
+ break;
+ case 33:
+ name = "Guelmim";
+ break;
+ case 34:
+ name = "Ifrane";
+ break;
+ case 35:
+ name = "Laayoune";
+ break;
+ case 36:
+ name = "Tan-Tan";
+ break;
+ case 37:
+ name = "Taounate";
+ break;
+ case 38:
+ name = "Sidi Kacem";
+ break;
+ case 39:
+ name = "Taroudannt";
+ break;
+ case 40:
+ name = "Tetouan";
+ break;
+ case 41:
+ name = "Larache";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MC") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "La Condamine";
+ break;
+ case 2:
+ name = "Monaco";
+ break;
+ case 3:
+ name = "Monte-Carlo";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MD") == 0) {
+ switch (region_code2) {
+ case 46:
+ name = "Balti";
+ break;
+ case 47:
+ name = "Cahul";
+ break;
+ case 48:
+ name = "Chisinau";
+ break;
+ case 49:
+ name = "Stinga Nistrului";
+ break;
+ case 50:
+ name = "Edinet";
+ break;
+ case 51:
+ name = "Gagauzia";
+ break;
+ case 52:
+ name = "Lapusna";
+ break;
+ case 53:
+ name = "Orhei";
+ break;
+ case 54:
+ name = "Soroca";
+ break;
+ case 55:
+ name = "Tighina";
+ break;
+ case 56:
+ name = "Ungheni";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MG") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Antsiranana";
+ break;
+ case 2:
+ name = "Fianarantsoa";
+ break;
+ case 3:
+ name = "Mahajanga";
+ break;
+ case 4:
+ name = "Toamasina";
+ break;
+ case 5:
+ name = "Antananarivo";
+ break;
+ case 6:
+ name = "Toliara";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MK") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Aracinovo";
+ break;
+ case 2:
+ name = "Bac";
+ break;
+ case 3:
+ name = "Belcista";
+ break;
+ case 4:
+ name = "Berovo";
+ break;
+ case 5:
+ name = "Bistrica";
+ break;
+ case 6:
+ name = "Bitola";
+ break;
+ case 7:
+ name = "Blatec";
+ break;
+ case 8:
+ name = "Bogdanci";
+ break;
+ case 9:
+ name = "Bogomila";
+ break;
+ case 10:
+ name = "Bogovinje";
+ break;
+ case 11:
+ name = "Bosilovo";
+ break;
+ case 12:
+ name = "Brvenica";
+ break;
+ case 13:
+ name = "Cair";
+ break;
+ case 14:
+ name = "Capari";
+ break;
+ case 15:
+ name = "Caska";
+ break;
+ case 16:
+ name = "Cegrane";
+ break;
+ case 17:
+ name = "Centar";
+ break;
+ case 18:
+ name = "Centar Zupa";
+ break;
+ case 19:
+ name = "Cesinovo";
+ break;
+ case 20:
+ name = "Cucer-Sandevo";
+ break;
+ case 21:
+ name = "Debar";
+ break;
+ case 22:
+ name = "Delcevo";
+ break;
+ case 23:
+ name = "Delogozdi";
+ break;
+ case 24:
+ name = "Demir Hisar";
+ break;
+ case 25:
+ name = "Demir Kapija";
+ break;
+ case 26:
+ name = "Dobrusevo";
+ break;
+ case 27:
+ name = "Dolna Banjica";
+ break;
+ case 28:
+ name = "Dolneni";
+ break;
+ case 29:
+ name = "Dorce Petrov";
+ break;
+ case 30:
+ name = "Drugovo";
+ break;
+ case 31:
+ name = "Dzepciste";
+ break;
+ case 32:
+ name = "Gazi Baba";
+ break;
+ case 33:
+ name = "Gevgelija";
+ break;
+ case 34:
+ name = "Gostivar";
+ break;
+ case 35:
+ name = "Gradsko";
+ break;
+ case 36:
+ name = "Ilinden";
+ break;
+ case 37:
+ name = "Izvor";
+ break;
+ case 38:
+ name = "Jegunovce";
+ break;
+ case 39:
+ name = "Kamenjane";
+ break;
+ case 40:
+ name = "Karbinci";
+ break;
+ case 41:
+ name = "Karpos";
+ break;
+ case 42:
+ name = "Kavadarci";
+ break;
+ case 43:
+ name = "Kicevo";
+ break;
+ case 44:
+ name = "Kisela Voda";
+ break;
+ case 45:
+ name = "Klecevce";
+ break;
+ case 46:
+ name = "Kocani";
+ break;
+ case 47:
+ name = "Konce";
+ break;
+ case 48:
+ name = "Kondovo";
+ break;
+ case 49:
+ name = "Konopiste";
+ break;
+ case 50:
+ name = "Kosel";
+ break;
+ case 51:
+ name = "Kratovo";
+ break;
+ case 52:
+ name = "Kriva Palanka";
+ break;
+ case 53:
+ name = "Krivogastani";
+ break;
+ case 54:
+ name = "Krusevo";
+ break;
+ case 55:
+ name = "Kuklis";
+ break;
+ case 56:
+ name = "Kukurecani";
+ break;
+ case 57:
+ name = "Kumanovo";
+ break;
+ case 58:
+ name = "Labunista";
+ break;
+ case 59:
+ name = "Lipkovo";
+ break;
+ case 60:
+ name = "Lozovo";
+ break;
+ case 61:
+ name = "Lukovo";
+ break;
+ case 62:
+ name = "Makedonska Kamenica";
+ break;
+ case 63:
+ name = "Makedonski Brod";
+ break;
+ case 64:
+ name = "Mavrovi Anovi";
+ break;
+ case 65:
+ name = "Meseista";
+ break;
+ case 66:
+ name = "Miravci";
+ break;
+ case 67:
+ name = "Mogila";
+ break;
+ case 68:
+ name = "Murtino";
+ break;
+ case 69:
+ name = "Negotino";
+ break;
+ case 70:
+ name = "Negotino-Polosko";
+ break;
+ case 71:
+ name = "Novaci";
+ break;
+ case 72:
+ name = "Novo Selo";
+ break;
+ case 73:
+ name = "Oblesevo";
+ break;
+ case 74:
+ name = "Ohrid";
+ break;
+ case 75:
+ name = "Orasac";
+ break;
+ case 76:
+ name = "Orizari";
+ break;
+ case 77:
+ name = "Oslomej";
+ break;
+ case 78:
+ name = "Pehcevo";
+ break;
+ case 79:
+ name = "Petrovec";
+ break;
+ case 80:
+ name = "Plasnica";
+ break;
+ case 81:
+ name = "Podares";
+ break;
+ case 82:
+ name = "Prilep";
+ break;
+ case 83:
+ name = "Probistip";
+ break;
+ case 84:
+ name = "Radovis";
+ break;
+ case 85:
+ name = "Rankovce";
+ break;
+ case 86:
+ name = "Resen";
+ break;
+ case 87:
+ name = "Rosoman";
+ break;
+ case 88:
+ name = "Rostusa";
+ break;
+ case 89:
+ name = "Samokov";
+ break;
+ case 90:
+ name = "Saraj";
+ break;
+ case 91:
+ name = "Sipkovica";
+ break;
+ case 92:
+ name = "Sopiste";
+ break;
+ case 93:
+ name = "Sopotnica";
+ break;
+ case 94:
+ name = "Srbinovo";
+ break;
+ case 95:
+ name = "Staravina";
+ break;
+ case 96:
+ name = "Star Dojran";
+ break;
+ case 97:
+ name = "Staro Nagoricane";
+ break;
+ case 98:
+ name = "Stip";
+ break;
+ case 99:
+ name = "Struga";
+ break;
+ case 101:
+ name = "Strumica";
+ break;
+ case 102:
+ name = "Studenicani";
+ break;
+ case 103:
+ name = "Suto Orizari";
+ break;
+ case 104:
+ name = "Sveti Nikole";
+ break;
+ case 105:
+ name = "Tearce";
+ break;
+ case 106:
+ name = "Tetovo";
+ break;
+ case 107:
+ name = "Topolcani";
+ break;
+ case 108:
+ name = "Valandovo";
+ break;
+ case 109:
+ name = "Vasilevo";
+ break;
+ case 111:
+ name = "Veles";
+ break;
+ case 112:
+ name = "Velesta";
+ break;
+ case 113:
+ name = "Vevcani";
+ break;
+ case 114:
+ name = "Vinica";
+ break;
+ case 115:
+ name = "Vitoliste";
+ break;
+ case 116:
+ name = "Vranestica";
+ break;
+ case 117:
+ name = "Vrapciste";
+ break;
+ case 118:
+ name = "Vratnica";
+ break;
+ case 119:
+ name = "Vrutok";
+ break;
+ case 121:
+ name = "Zajas";
+ break;
+ case 122:
+ name = "Zelenikovo";
+ break;
+ case 123:
+ name = "Zelino";
+ break;
+ case 124:
+ name = "Zitose";
+ break;
+ case 125:
+ name = "Zletovo";
+ break;
+ case 126:
+ name = "Zrnovci";
+ break;
+ }
+ }
+ if (strcmp(country_code,"ML") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bamako";
+ break;
+ case 3:
+ name = "Kayes";
+ break;
+ case 4:
+ name = "Mopti";
+ break;
+ case 5:
+ name = "Segou";
+ break;
+ case 6:
+ name = "Sikasso";
+ break;
+ case 7:
+ name = "Koulikoro";
+ break;
+ case 8:
+ name = "Tombouctou";
+ break;
+ case 9:
+ name = "Gao";
+ break;
+ case 10:
+ name = "Kidal";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Rakhine State";
+ break;
+ case 2:
+ name = "Chin State";
+ break;
+ case 3:
+ name = "Irrawaddy";
+ break;
+ case 4:
+ name = "Kachin State";
+ break;
+ case 5:
+ name = "Karan State";
+ break;
+ case 6:
+ name = "Kayah State";
+ break;
+ case 7:
+ name = "Magwe";
+ break;
+ case 8:
+ name = "Mandalay";
+ break;
+ case 9:
+ name = "Pegu";
+ break;
+ case 10:
+ name = "Sagaing";
+ break;
+ case 11:
+ name = "Shan State";
+ break;
+ case 12:
+ name = "Tenasserim";
+ break;
+ case 13:
+ name = "Mon State";
+ break;
+ case 14:
+ name = "Rangoon";
+ break;
+ case 17:
+ name = "Yangon";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MN") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Arhangay";
+ break;
+ case 2:
+ name = "Bayanhongor";
+ break;
+ case 3:
+ name = "Bayan-Olgiy";
+ break;
+ case 5:
+ name = "Darhan";
+ break;
+ case 6:
+ name = "Dornod";
+ break;
+ case 7:
+ name = "Dornogovi";
+ break;
+ case 8:
+ name = "Dundgovi";
+ break;
+ case 9:
+ name = "Dzavhan";
+ break;
+ case 10:
+ name = "Govi-Altay";
+ break;
+ case 11:
+ name = "Hentiy";
+ break;
+ case 12:
+ name = "Hovd";
+ break;
+ case 13:
+ name = "Hovsgol";
+ break;
+ case 14:
+ name = "Omnogovi";
+ break;
+ case 15:
+ name = "Ovorhangay";
+ break;
+ case 16:
+ name = "Selenge";
+ break;
+ case 17:
+ name = "Suhbaatar";
+ break;
+ case 18:
+ name = "Tov";
+ break;
+ case 19:
+ name = "Uvs";
+ break;
+ case 20:
+ name = "Ulaanbaatar";
+ break;
+ case 21:
+ name = "Bulgan";
+ break;
+ case 22:
+ name = "Erdenet";
+ break;
+ case 23:
+ name = "Darhan Uul";
+ break;
+ case 24:
+ name = "Govi-Sumber";
+ break;
+ case 25:
+ name = "Orhon";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MO") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Ilhas";
+ break;
+ case 2:
+ name = "Macau";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Hodh Ech Chargui";
+ break;
+ case 2:
+ name = "Hodh El Gharbi";
+ break;
+ case 3:
+ name = "Assaba";
+ break;
+ case 4:
+ name = "Gorgol";
+ break;
+ case 5:
+ name = "Brakna";
+ break;
+ case 6:
+ name = "Trarza";
+ break;
+ case 7:
+ name = "Adrar";
+ break;
+ case 8:
+ name = "Dakhlet Nouadhibou";
+ break;
+ case 9:
+ name = "Tagant";
+ break;
+ case 10:
+ name = "Guidimaka";
+ break;
+ case 11:
+ name = "Tiris Zemmour";
+ break;
+ case 12:
+ name = "Inchiri";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MS") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Saint Anthony";
+ break;
+ case 2:
+ name = "Saint Georges";
+ break;
+ case 3:
+ name = "Saint Peter";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MU") == 0) {
+ switch (region_code2) {
+ case 12:
+ name = "Black River";
+ break;
+ case 13:
+ name = "Flacq";
+ break;
+ case 14:
+ name = "Grand Port";
+ break;
+ case 15:
+ name = "Moka";
+ break;
+ case 16:
+ name = "Pamplemousses";
+ break;
+ case 17:
+ name = "Plaines Wilhems";
+ break;
+ case 18:
+ name = "Port Louis";
+ break;
+ case 19:
+ name = "Riviere du Rempart";
+ break;
+ case 20:
+ name = "Savanne";
+ break;
+ case 21:
+ name = "Agalega Islands";
+ break;
+ case 22:
+ name = "Cargados Carajos";
+ break;
+ case 23:
+ name = "Rodrigues";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MV") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Seenu";
+ break;
+ case 2:
+ name = "Aliff";
+ break;
+ case 3:
+ name = "Laviyani";
+ break;
+ case 4:
+ name = "Waavu";
+ break;
+ case 5:
+ name = "Laamu";
+ break;
+ case 7:
+ name = "Haa Aliff";
+ break;
+ case 8:
+ name = "Thaa";
+ break;
+ case 12:
+ name = "Meemu";
+ break;
+ case 13:
+ name = "Raa";
+ break;
+ case 14:
+ name = "Faafu";
+ break;
+ case 17:
+ name = "Daalu";
+ break;
+ case 20:
+ name = "Baa";
+ break;
+ case 23:
+ name = "Haa Daalu";
+ break;
+ case 24:
+ name = "Shaviyani";
+ break;
+ case 25:
+ name = "Noonu";
+ break;
+ case 26:
+ name = "Kaafu";
+ break;
+ case 27:
+ name = "Gaafu Aliff";
+ break;
+ case 28:
+ name = "Gaafu Daalu";
+ break;
+ case 29:
+ name = "Naviyani";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MW") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Chikwawa";
+ break;
+ case 3:
+ name = "Chiradzulu";
+ break;
+ case 4:
+ name = "Chitipa";
+ break;
+ case 5:
+ name = "Thyolo";
+ break;
+ case 6:
+ name = "Dedza";
+ break;
+ case 7:
+ name = "Dowa";
+ break;
+ case 8:
+ name = "Karonga";
+ break;
+ case 9:
+ name = "Kasungu";
+ break;
+ case 11:
+ name = "Lilongwe";
+ break;
+ case 12:
+ name = "Mangochi";
+ break;
+ case 13:
+ name = "Mchinji";
+ break;
+ case 15:
+ name = "Mzimba";
+ break;
+ case 16:
+ name = "Ntcheu";
+ break;
+ case 17:
+ name = "Nkhata Bay";
+ break;
+ case 18:
+ name = "Nkhotakota";
+ break;
+ case 19:
+ name = "Nsanje";
+ break;
+ case 20:
+ name = "Ntchisi";
+ break;
+ case 21:
+ name = "Rumphi";
+ break;
+ case 22:
+ name = "Salima";
+ break;
+ case 23:
+ name = "Zomba";
+ break;
+ case 24:
+ name = "Blantyre";
+ break;
+ case 25:
+ name = "Mwanza";
+ break;
+ case 26:
+ name = "Balaka";
+ break;
+ case 27:
+ name = "Likoma";
+ break;
+ case 28:
+ name = "Machinga";
+ break;
+ case 29:
+ name = "Mulanje";
+ break;
+ case 30:
+ name = "Phalombe";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MX") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Aguascalientes";
+ break;
+ case 2:
+ name = "Baja California";
+ break;
+ case 3:
+ name = "Baja California Sur";
+ break;
+ case 4:
+ name = "Campeche";
+ break;
+ case 5:
+ name = "Chiapas";
+ break;
+ case 6:
+ name = "Chihuahua";
+ break;
+ case 7:
+ name = "Coahuila de Zaragoza";
+ break;
+ case 8:
+ name = "Colima";
+ break;
+ case 9:
+ name = "Distrito Federal";
+ break;
+ case 10:
+ name = "Durango";
+ break;
+ case 11:
+ name = "Guanajuato";
+ break;
+ case 12:
+ name = "Guerrero";
+ break;
+ case 13:
+ name = "Hidalgo";
+ break;
+ case 14:
+ name = "Jalisco";
+ break;
+ case 15:
+ name = "Mexico";
+ break;
+ case 16:
+ name = "Michoacan de Ocampo";
+ break;
+ case 17:
+ name = "Morelos";
+ break;
+ case 18:
+ name = "Nayarit";
+ break;
+ case 19:
+ name = "Nuevo Leon";
+ break;
+ case 20:
+ name = "Oaxaca";
+ break;
+ case 21:
+ name = "Puebla";
+ break;
+ case 22:
+ name = "Queretaro de Arteaga";
+ break;
+ case 23:
+ name = "Quintana Roo";
+ break;
+ case 24:
+ name = "San Luis Potosi";
+ break;
+ case 25:
+ name = "Sinaloa";
+ break;
+ case 26:
+ name = "Sonora";
+ break;
+ case 27:
+ name = "Tabasco";
+ break;
+ case 28:
+ name = "Tamaulipas";
+ break;
+ case 29:
+ name = "Tlaxcala";
+ break;
+ case 30:
+ name = "Veracruz-Llave";
+ break;
+ case 31:
+ name = "Yucatan";
+ break;
+ case 32:
+ name = "Zacatecas";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MY") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Johor";
+ break;
+ case 2:
+ name = "Kedah";
+ break;
+ case 3:
+ name = "Kelantan";
+ break;
+ case 4:
+ name = "Melaka";
+ break;
+ case 5:
+ name = "Negeri Sembilan";
+ break;
+ case 6:
+ name = "Pahang";
+ break;
+ case 7:
+ name = "Perak";
+ break;
+ case 8:
+ name = "Perlis";
+ break;
+ case 9:
+ name = "Pulau Pinang";
+ break;
+ case 11:
+ name = "Sarawak";
+ break;
+ case 12:
+ name = "Selangor";
+ break;
+ case 13:
+ name = "Terengganu";
+ break;
+ case 14:
+ name = "Wilayah Persekutuan";
+ break;
+ case 15:
+ name = "Labuan";
+ break;
+ case 16:
+ name = "Sabah";
+ break;
+ }
+ }
+ if (strcmp(country_code,"MZ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Cabo Delgado";
+ break;
+ case 2:
+ name = "Gaza";
+ break;
+ case 3:
+ name = "Inhambane";
+ break;
+ case 4:
+ name = "Maputo";
+ break;
+ case 5:
+ name = "Sofala";
+ break;
+ case 6:
+ name = "Nampula";
+ break;
+ case 7:
+ name = "Niassa";
+ break;
+ case 8:
+ name = "Tete";
+ break;
+ case 9:
+ name = "Zambezia";
+ break;
+ case 10:
+ name = "Manica";
+ break;
+ }
+ }
+ if (strcmp(country_code,"NA") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bethanien";
+ break;
+ case 2:
+ name = "Caprivi Oos";
+ break;
+ case 3:
+ name = "Boesmanland";
+ break;
+ case 4:
+ name = "Gobabis";
+ break;
+ case 5:
+ name = "Grootfontein";
+ break;
+ case 6:
+ name = "Kaokoland";
+ break;
+ case 7:
+ name = "Karibib";
+ break;
+ case 8:
+ name = "Keetmanshoop";
+ break;
+ case 9:
+ name = "Luderitz";
+ break;
+ case 10:
+ name = "Maltahohe";
+ break;
+ case 11:
+ name = "Okahandja";
+ break;
+ case 12:
+ name = "Omaruru";
+ break;
+ case 13:
+ name = "Otjiwarongo";
+ break;
+ case 14:
+ name = "Outjo";
+ break;
+ case 15:
+ name = "Owambo";
+ break;
+ case 16:
+ name = "Rehoboth";
+ break;
+ case 17:
+ name = "Swakopmund";
+ break;
+ case 18:
+ name = "Tsumeb";
+ break;
+ case 20:
+ name = "Karasburg";
+ break;
+ case 21:
+ name = "Windhoek";
+ break;
+ case 22:
+ name = "Damaraland";
+ break;
+ case 23:
+ name = "Hereroland Oos";
+ break;
+ case 24:
+ name = "Hereroland Wes";
+ break;
+ case 25:
+ name = "Kavango";
+ break;
+ case 26:
+ name = "Mariental";
+ break;
+ case 27:
+ name = "Namaland";
+ break;
+ case 28:
+ name = "Caprivi";
+ break;
+ case 29:
+ name = "Erongo";
+ break;
+ case 30:
+ name = "Hardap";
+ break;
+ case 31:
+ name = "Karas";
+ break;
+ case 32:
+ name = "Kunene";
+ break;
+ case 33:
+ name = "Ohangwena";
+ break;
+ case 34:
+ name = "Okavango";
+ break;
+ case 35:
+ name = "Omaheke";
+ break;
+ case 36:
+ name = "Omusati";
+ break;
+ case 37:
+ name = "Oshana";
+ break;
+ case 38:
+ name = "Oshikoto";
+ break;
+ case 39:
+ name = "Otjozondjupa";
+ break;
+ }
+ }
+ if (strcmp(country_code,"NE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Agadez";
+ break;
+ case 2:
+ name = "Diffa";
+ break;
+ case 3:
+ name = "Dosso";
+ break;
+ case 4:
+ name = "Maradi";
+ break;
+ case 5:
+ name = "Niamey";
+ break;
+ case 6:
+ name = "Tahoua";
+ break;
+ case 7:
+ name = "Zinder";
+ break;
+ }
+ }
+ if (strcmp(country_code,"NG") == 0) {
+ switch (region_code2) {
+ case 5:
+ name = "Lagos";
+ break;
+ case 11:
+ name = "Abuja Capital Territory";
+ break;
+ case 16:
+ name = "Ogun";
+ break;
+ case 21:
+ name = "Akwa Ibom";
+ break;
+ case 22:
+ name = "Cross River";
+ break;
+ case 23:
+ name = "Kaduna";
+ break;
+ case 24:
+ name = "Katsina";
+ break;
+ case 25:
+ name = "Anambra";
+ break;
+ case 26:
+ name = "Benue";
+ break;
+ case 27:
+ name = "Borno";
+ break;
+ case 28:
+ name = "Imo";
+ break;
+ case 29:
+ name = "Kano";
+ break;
+ case 30:
+ name = "Kwara";
+ break;
+ case 31:
+ name = "Niger";
+ break;
+ case 32:
+ name = "Oyo";
+ break;
+ case 35:
+ name = "Adamawa";
+ break;
+ case 36:
+ name = "Delta";
+ break;
+ case 37:
+ name = "Edo";
+ break;
+ case 39:
+ name = "Jigawa";
+ break;
+ case 40:
+ name = "Kebbi";
+ break;
+ case 41:
+ name = "Kogi";
+ break;
+ case 42:
+ name = "Osun";
+ break;
+ case 43:
+ name = "Taraba";
+ break;
+ case 44:
+ name = "Yobe";
+ break;
+ case 45:
+ name = "Abia";
+ break;
+ case 46:
+ name = "Bauchi";
+ break;
+ case 47:
+ name = "Enugu";
+ break;
+ case 48:
+ name = "Ondo";
+ break;
+ case 49:
+ name = "Plateau";
+ break;
+ case 50:
+ name = "Rivers";
+ break;
+ case 51:
+ name = "Sokoto";
+ break;
+ case 52:
+ name = "Bayelsa";
+ break;
+ case 53:
+ name = "Ebonyi";
+ break;
+ case 54:
+ name = "Ekiti";
+ break;
+ case 55:
+ name = "Gombe";
+ break;
+ case 56:
+ name = "Nassarawa";
+ break;
+ case 57:
+ name = "Zamfara";
+ break;
+ }
+ }
+ if (strcmp(country_code,"NI") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Boaco";
+ break;
+ case 2:
+ name = "Carazo";
+ break;
+ case 3:
+ name = "Chinandega";
+ break;
+ case 4:
+ name = "Chontales";
+ break;
+ case 5:
+ name = "Esteli";
+ break;
+ case 6:
+ name = "Granada";
+ break;
+ case 7:
+ name = "Jinotega";
+ break;
+ case 8:
+ name = "Leon";
+ break;
+ case 9:
+ name = "Madriz";
+ break;
+ case 10:
+ name = "Managua";
+ break;
+ case 11:
+ name = "Masaya";
+ break;
+ case 12:
+ name = "Matagalpa";
+ break;
+ case 13:
+ name = "Nueva Segovia";
+ break;
+ case 14:
+ name = "Rio San Juan";
+ break;
+ case 15:
+ name = "Rivas";
+ break;
+ case 16:
+ name = "Zelaya";
+ break;
+ }
+ }
+ if (strcmp(country_code,"NL") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Drenthe";
+ break;
+ case 2:
+ name = "Friesland";
+ break;
+ case 3:
+ name = "Gelderland";
+ break;
+ case 4:
+ name = "Groningen";
+ break;
+ case 5:
+ name = "Limburg";
+ break;
+ case 6:
+ name = "Noord-Brabant";
+ break;
+ case 7:
+ name = "Noord-Holland";
+ break;
+ case 8:
+ name = "Overijssel";
+ break;
+ case 9:
+ name = "Utrecht";
+ break;
+ case 10:
+ name = "Zeeland";
+ break;
+ case 11:
+ name = "Zuid-Holland";
+ break;
+ case 12:
+ name = "Dronten";
+ break;
+ case 13:
+ name = "Zuidelijke IJsselmeerpolders";
+ break;
+ case 14:
+ name = "Lelystad";
+ break;
+ case 15:
+ name = "Overijssel";
+ break;
+ case 16:
+ name = "Flevoland";
+ break;
+ }
+ }
+ if (strcmp(country_code,"NO") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Akershus";
+ break;
+ case 2:
+ name = "Aust-Agder";
+ break;
+ case 4:
+ name = "Buskerud";
+ break;
+ case 5:
+ name = "Finnmark";
+ break;
+ case 6:
+ name = "Hedmark";
+ break;
+ case 7:
+ name = "Hordaland";
+ break;
+ case 8:
+ name = "More og Romsdal";
+ break;
+ case 9:
+ name = "Nordland";
+ break;
+ case 10:
+ name = "Nord-Trondelag";
+ break;
+ case 11:
+ name = "Oppland";
+ break;
+ case 12:
+ name = "Oslo";
+ break;
+ case 13:
+ name = "Ostfold";
+ break;
+ case 14:
+ name = "Rogaland";
+ break;
+ case 15:
+ name = "Sogn og Fjordane";
+ break;
+ case 16:
+ name = "Sor-Trondelag";
+ break;
+ case 17:
+ name = "Telemark";
+ break;
+ case 18:
+ name = "Troms";
+ break;
+ case 19:
+ name = "Vest-Agder";
+ break;
+ case 20:
+ name = "Vestfold";
+ break;
+ }
+ }
+ if (strcmp(country_code,"NP") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bagmati";
+ break;
+ case 2:
+ name = "Bheri";
+ break;
+ case 3:
+ name = "Dhawalagiri";
+ break;
+ case 4:
+ name = "Gandaki";
+ break;
+ case 5:
+ name = "Janakpur";
+ break;
+ case 6:
+ name = "Karnali";
+ break;
+ case 7:
+ name = "Kosi";
+ break;
+ case 8:
+ name = "Lumbini";
+ break;
+ case 9:
+ name = "Mahakali";
+ break;
+ case 10:
+ name = "Mechi";
+ break;
+ case 11:
+ name = "Narayani";
+ break;
+ case 12:
+ name = "Rapti";
+ break;
+ case 13:
+ name = "Sagarmatha";
+ break;
+ case 14:
+ name = "Seti";
+ break;
+ }
+ }
+ if (strcmp(country_code,"NR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Aiwo";
+ break;
+ case 2:
+ name = "Anabar";
+ break;
+ case 3:
+ name = "Anetan";
+ break;
+ case 4:
+ name = "Anibare";
+ break;
+ case 5:
+ name = "Baiti";
+ break;
+ case 6:
+ name = "Boe";
+ break;
+ case 7:
+ name = "Buada";
+ break;
+ case 8:
+ name = "Denigomodu";
+ break;
+ case 9:
+ name = "Ewa";
+ break;
+ case 10:
+ name = "Ijuw";
+ break;
+ case 11:
+ name = "Meneng";
+ break;
+ case 12:
+ name = "Nibok";
+ break;
+ case 13:
+ name = "Uaboe";
+ break;
+ case 14:
+ name = "Yaren";
+ break;
+ }
+ }
+ if (strcmp(country_code,"NZ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Akaroa";
+ break;
+ case 3:
+ name = "Amuri";
+ break;
+ case 4:
+ name = "Ashburton";
+ break;
+ case 7:
+ name = "Bay of Islands";
+ break;
+ case 8:
+ name = "Bruce";
+ break;
+ case 9:
+ name = "Buller";
+ break;
+ case 10:
+ name = "Chatham Islands";
+ break;
+ case 11:
+ name = "Cheviot";
+ break;
+ case 12:
+ name = "Clifton";
+ break;
+ case 13:
+ name = "Clutha";
+ break;
+ case 14:
+ name = "Cook";
+ break;
+ case 16:
+ name = "Dannevirke";
+ break;
+ case 17:
+ name = "Egmont";
+ break;
+ case 18:
+ name = "Eketahuna";
+ break;
+ case 19:
+ name = "Ellesmere";
+ break;
+ case 20:
+ name = "Eltham";
+ break;
+ case 21:
+ name = "Eyre";
+ break;
+ case 22:
+ name = "Featherston";
+ break;
+ case 24:
+ name = "Franklin";
+ break;
+ case 26:
+ name = "Golden Bay";
+ break;
+ case 27:
+ name = "Great Barrier Island";
+ break;
+ case 28:
+ name = "Grey";
+ break;
+ case 29:
+ name = "Hauraki Plains";
+ break;
+ case 30:
+ name = "Hawera";
+ break;
+ case 31:
+ name = "Hawke's Bay";
+ break;
+ case 32:
+ name = "Heathcote";
+ break;
+ case 33:
+ name = "Hobson";
+ break;
+ case 34:
+ name = "Hokianga";
+ break;
+ case 35:
+ name = "Horowhenua";
+ break;
+ case 36:
+ name = "Hutt";
+ break;
+ case 37:
+ name = "Inangahua";
+ break;
+ case 38:
+ name = "Inglewood";
+ break;
+ case 39:
+ name = "Kaikoura";
+ break;
+ case 40:
+ name = "Kairanga";
+ break;
+ case 41:
+ name = "Kiwitea";
+ break;
+ case 43:
+ name = "Lake";
+ break;
+ case 45:
+ name = "Mackenzie";
+ break;
+ case 46:
+ name = "Malvern";
+ break;
+ case 47:
+ name = "Manawatu";
+ break;
+ case 48:
+ name = "Mangonui";
+ break;
+ case 49:
+ name = "Maniototo";
+ break;
+ case 50:
+ name = "Marlborough";
+ break;
+ case 51:
+ name = "Masterton";
+ break;
+ case 52:
+ name = "Matamata";
+ break;
+ case 53:
+ name = "Mount Herbert";
+ break;
+ case 54:
+ name = "Ohinemuri";
+ break;
+ case 55:
+ name = "Opotiki";
+ break;
+ case 56:
+ name = "Oroua";
+ break;
+ case 57:
+ name = "Otamatea";
+ break;
+ case 58:
+ name = "Otorohanga";
+ break;
+ case 59:
+ name = "Oxford";
+ break;
+ case 60:
+ name = "Pahiatua";
+ break;
+ case 61:
+ name = "Paparua";
+ break;
+ case 63:
+ name = "Patea";
+ break;
+ case 65:
+ name = "Piako";
+ break;
+ case 66:
+ name = "Pohangina";
+ break;
+ case 67:
+ name = "Raglan";
+ break;
+ case 68:
+ name = "Rangiora";
+ break;
+ case 69:
+ name = "Rangitikei";
+ break;
+ case 70:
+ name = "Rodney";
+ break;
+ case 71:
+ name = "Rotorua";
+ break;
+ case 72:
+ name = "Southland";
+ break;
+ case 73:
+ name = "Stewart Island";
+ break;
+ case 74:
+ name = "Stratford";
+ break;
+ case 76:
+ name = "Taranaki";
+ break;
+ case 77:
+ name = "Taumarunui";
+ break;
+ case 78:
+ name = "Taupo";
+ break;
+ case 79:
+ name = "Tauranga";
+ break;
+ case 81:
+ name = "Tuapeka";
+ break;
+ case 82:
+ name = "Vincent";
+ break;
+ case 83:
+ name = "Waiapu";
+ break;
+ case 84:
+ name = "Waihemo";
+ break;
+ case 85:
+ name = "Waikato";
+ break;
+ case 86:
+ name = "Waikohu";
+ break;
+ case 88:
+ name = "Waimairi";
+ break;
+ case 89:
+ name = "Waimarino";
+ break;
+ case 90:
+ name = "Waimate";
+ break;
+ case 91:
+ name = "Waimate West";
+ break;
+ case 92:
+ name = "Waimea";
+ break;
+ case 93:
+ name = "Waipa";
+ break;
+ case 95:
+ name = "Waipawa";
+ break;
+ case 96:
+ name = "Waipukurau";
+ break;
+ case 97:
+ name = "Wairarapa South";
+ break;
+ case 98:
+ name = "Wairewa";
+ break;
+ case 99:
+ name = "Wairoa";
+ break;
+ case 101:
+ name = "Whangarei";
+ break;
+ case 102:
+ name = "Whangaroa";
+ break;
+ case 103:
+ name = "Woodville";
+ break;
+ case 104:
+ name = "Waitaki";
+ break;
+ case 106:
+ name = "Waitomo";
+ break;
+ case 108:
+ name = "Waitotara";
+ break;
+ case 112:
+ name = "Wanganui";
+ break;
+ case 113:
+ name = "Westland";
+ break;
+ case 114:
+ name = "Whakatane";
+ break;
+ case 134:
+ name = "Hurunui";
+ break;
+ case 135:
+ name = "Silverpeaks";
+ break;
+ case 136:
+ name = "Strathallan";
+ break;
+ case 138:
+ name = "Waiheke";
+ break;
+ case 139:
+ name = "Hikurangi";
+ break;
+ case 141:
+ name = "Manaia";
+ break;
+ case 142:
+ name = "Runanga";
+ break;
+ case 143:
+ name = "Saint Kilda";
+ break;
+ case 144:
+ name = "Thames-Coromandel";
+ break;
+ case 145:
+ name = "Waverley";
+ break;
+ case 146:
+ name = "Wallace";
+ break;
+ }
+ }
+ if (strcmp(country_code,"OM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Ad Dakhiliyah";
+ break;
+ case 2:
+ name = "Al Batinah";
+ break;
+ case 3:
+ name = "Al Wusta";
+ break;
+ case 4:
+ name = "Ash Sharqiyah";
+ break;
+ case 5:
+ name = "Az Zahirah";
+ break;
+ case 6:
+ name = "Masqat";
+ break;
+ case 7:
+ name = "Musandam";
+ break;
+ case 8:
+ name = "Zufar";
+ break;
+ }
+ }
+ if (strcmp(country_code,"PA") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bocas del Toro";
+ break;
+ case 2:
+ name = "Chiriqui";
+ break;
+ case 3:
+ name = "Cocle";
+ break;
+ case 4:
+ name = "Colon";
+ break;
+ case 5:
+ name = "Darien";
+ break;
+ case 6:
+ name = "Herrera";
+ break;
+ case 7:
+ name = "Los Santos";
+ break;
+ case 8:
+ name = "Panama";
+ break;
+ case 9:
+ name = "San Blas";
+ break;
+ case 10:
+ name = "Veraguas";
+ break;
+ }
+ }
+ if (strcmp(country_code,"PE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Amazonas";
+ break;
+ case 2:
+ name = "Ancash";
+ break;
+ case 3:
+ name = "Apurimac";
+ break;
+ case 4:
+ name = "Arequipa";
+ break;
+ case 5:
+ name = "Ayacucho";
+ break;
+ case 6:
+ name = "Cajamarca";
+ break;
+ case 7:
+ name = "Callao";
+ break;
+ case 8:
+ name = "Cusco";
+ break;
+ case 9:
+ name = "Huancavelica";
+ break;
+ case 10:
+ name = "Huanuco";
+ break;
+ case 11:
+ name = "Ica";
+ break;
+ case 12:
+ name = "Junin";
+ break;
+ case 13:
+ name = "La Libertad";
+ break;
+ case 14:
+ name = "Lambayeque";
+ break;
+ case 15:
+ name = "Lima";
+ break;
+ case 16:
+ name = "Loreto";
+ break;
+ case 17:
+ name = "Madre de Dios";
+ break;
+ case 18:
+ name = "Moquegua";
+ break;
+ case 19:
+ name = "Pasco";
+ break;
+ case 20:
+ name = "Piura";
+ break;
+ case 21:
+ name = "Puno";
+ break;
+ case 22:
+ name = "San Martin";
+ break;
+ case 23:
+ name = "Tacna";
+ break;
+ case 24:
+ name = "Tumbes";
+ break;
+ case 25:
+ name = "Ucayali";
+ break;
+ }
+ }
+ if (strcmp(country_code,"PG") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Central";
+ break;
+ case 2:
+ name = "Gulf";
+ break;
+ case 3:
+ name = "Milne Bay";
+ break;
+ case 4:
+ name = "Northern";
+ break;
+ case 5:
+ name = "Southern Highlands";
+ break;
+ case 6:
+ name = "Western";
+ break;
+ case 7:
+ name = "North Solomons";
+ break;
+ case 8:
+ name = "Chimbu";
+ break;
+ case 9:
+ name = "Eastern Highlands";
+ break;
+ case 10:
+ name = "East New Britain";
+ break;
+ case 11:
+ name = "East Sepik";
+ break;
+ case 12:
+ name = "Madang";
+ break;
+ case 13:
+ name = "Manus";
+ break;
+ case 14:
+ name = "Morobe";
+ break;
+ case 15:
+ name = "New Ireland";
+ break;
+ case 16:
+ name = "Western Highlands";
+ break;
+ case 17:
+ name = "West New Britain";
+ break;
+ case 18:
+ name = "Sandaun";
+ break;
+ case 19:
+ name = "Enga";
+ break;
+ case 20:
+ name = "National Capital";
+ break;
+ }
+ }
+ if (strcmp(country_code,"PH") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Abra";
+ break;
+ case 2:
+ name = "Agusan del Norte";
+ break;
+ case 3:
+ name = "Agusan del Sur";
+ break;
+ case 4:
+ name = "Aklan";
+ break;
+ case 5:
+ name = "Albay";
+ break;
+ case 6:
+ name = "Antique";
+ break;
+ case 7:
+ name = "Bataan";
+ break;
+ case 8:
+ name = "Batanes";
+ break;
+ case 9:
+ name = "Batangas";
+ break;
+ case 10:
+ name = "Benguet";
+ break;
+ case 11:
+ name = "Bohol";
+ break;
+ case 12:
+ name = "Bukidnon";
+ break;
+ case 13:
+ name = "Bulacan";
+ break;
+ case 14:
+ name = "Cagayan";
+ break;
+ case 15:
+ name = "Camarines Norte";
+ break;
+ case 16:
+ name = "Camarines Sur";
+ break;
+ case 17:
+ name = "Camiguin";
+ break;
+ case 18:
+ name = "Capiz";
+ break;
+ case 19:
+ name = "Catanduanes";
+ break;
+ case 20:
+ name = "Cavite";
+ break;
+ case 21:
+ name = "Cebu";
+ break;
+ case 22:
+ name = "Basilan";
+ break;
+ case 23:
+ name = "Eastern Samar";
+ break;
+ case 24:
+ name = "Davao";
+ break;
+ case 25:
+ name = "Davao del Sur";
+ break;
+ case 26:
+ name = "Davao Oriental";
+ break;
+ case 27:
+ name = "Ifugao";
+ break;
+ case 28:
+ name = "Ilocos Norte";
+ break;
+ case 29:
+ name = "Ilocos Sur";
+ break;
+ case 30:
+ name = "Iloilo";
+ break;
+ case 31:
+ name = "Isabela";
+ break;
+ case 32:
+ name = "Kalinga-Apayao";
+ break;
+ case 33:
+ name = "Laguna";
+ break;
+ case 34:
+ name = "Lanao del Norte";
+ break;
+ case 35:
+ name = "Lanao del Sur";
+ break;
+ case 36:
+ name = "La Union";
+ break;
+ case 37:
+ name = "Leyte";
+ break;
+ case 38:
+ name = "Marinduque";
+ break;
+ case 39:
+ name = "Masbate";
+ break;
+ case 40:
+ name = "Mindoro Occidental";
+ break;
+ case 41:
+ name = "Mindoro Oriental";
+ break;
+ case 42:
+ name = "Misamis Occidental";
+ break;
+ case 43:
+ name = "Misamis Oriental";
+ break;
+ case 44:
+ name = "Mountain";
+ break;
+ case 46:
+ name = "Negros Oriental";
+ break;
+ case 47:
+ name = "Nueva Ecija";
+ break;
+ case 48:
+ name = "Nueva Vizcaya";
+ break;
+ case 49:
+ name = "Palawan";
+ break;
+ case 50:
+ name = "Pampanga";
+ break;
+ case 51:
+ name = "Pangasinan";
+ break;
+ case 53:
+ name = "Rizal";
+ break;
+ case 54:
+ name = "Romblon";
+ break;
+ case 55:
+ name = "Samar";
+ break;
+ case 56:
+ name = "Maguindanao";
+ break;
+ case 57:
+ name = "North Cotabato";
+ break;
+ case 58:
+ name = "Sorsogon";
+ break;
+ case 59:
+ name = "Southern Leyte";
+ break;
+ case 60:
+ name = "Sulu";
+ break;
+ case 61:
+ name = "Surigao del Norte";
+ break;
+ case 62:
+ name = "Surigao del Sur";
+ break;
+ case 63:
+ name = "Tarlac";
+ break;
+ case 64:
+ name = "Zambales";
+ break;
+ case 65:
+ name = "Zamboanga del Norte";
+ break;
+ case 66:
+ name = "Zamboanga del Sur";
+ break;
+ case 67:
+ name = "Northern Samar";
+ break;
+ case 68:
+ name = "Quirino";
+ break;
+ case 69:
+ name = "Siquijor";
+ break;
+ case 70:
+ name = "South Cotabato";
+ break;
+ case 71:
+ name = "Sultan Kudarat";
+ break;
+ case 72:
+ name = "Tawitawi";
+ break;
+ case 101:
+ name = "Angeles";
+ break;
+ case 102:
+ name = "Bacolod";
+ break;
+ case 103:
+ name = "Bago";
+ break;
+ case 104:
+ name = "Baguio";
+ break;
+ case 105:
+ name = "Bais";
+ break;
+ case 106:
+ name = "Basilan City";
+ break;
+ case 107:
+ name = "Batangas City";
+ break;
+ case 108:
+ name = "Butuan";
+ break;
+ case 109:
+ name = "Cabanatuan";
+ break;
+ case 111:
+ name = "Cadiz";
+ break;
+ case 112:
+ name = "Cagayan de Oro";
+ break;
+ case 113:
+ name = "Calbayog";
+ break;
+ case 114:
+ name = "Caloocan";
+ break;
+ case 115:
+ name = "Canlaon";
+ break;
+ case 116:
+ name = "Cavite City";
+ break;
+ case 117:
+ name = "Cebu City";
+ break;
+ case 118:
+ name = "Cotabato";
+ break;
+ case 119:
+ name = "Dagupan";
+ break;
+ case 121:
+ name = "Danao";
+ break;
+ case 122:
+ name = "Dapitan";
+ break;
+ case 123:
+ name = "Davao City";
+ break;
+ case 124:
+ name = "Dipolog";
+ break;
+ case 125:
+ name = "Dumaguete";
+ break;
+ case 126:
+ name = "General Santos";
+ break;
+ case 127:
+ name = "Gingoog";
+ break;
+ case 128:
+ name = "Iligan";
+ break;
+ case 129:
+ name = "Iloilo City";
+ break;
+ case 131:
+ name = "Iriga";
+ break;
+ case 132:
+ name = "La Carlota";
+ break;
+ case 133:
+ name = "Laoag";
+ break;
+ case 134:
+ name = "Lapu-Lapu";
+ break;
+ case 135:
+ name = "Legaspi";
+ break;
+ case 136:
+ name = "Lipa";
+ break;
+ case 137:
+ name = "Lucena";
+ break;
+ case 138:
+ name = "Mandaue";
+ break;
+ case 139:
+ name = "Manila";
+ break;
+ case 141:
+ name = "Marawi";
+ break;
+ case 142:
+ name = "Naga";
+ break;
+ case 143:
+ name = "Olongapo";
+ break;
+ case 144:
+ name = "Ormoc";
+ break;
+ case 145:
+ name = "Oroquieta";
+ break;
+ case 146:
+ name = "Ozamis";
+ break;
+ case 147:
+ name = "Pagadian";
+ break;
+ case 148:
+ name = "Palayan";
+ break;
+ case 149:
+ name = "Pasay";
+ break;
+ case 151:
+ name = "Puerto Princesa";
+ break;
+ case 152:
+ name = "Quezon City";
+ break;
+ case 153:
+ name = "Roxas";
+ break;
+ case 154:
+ name = "San Carlos";
+ break;
+ case 155:
+ name = "San Carlos";
+ break;
+ case 156:
+ name = "San Jose";
+ break;
+ case 157:
+ name = "San Pablo";
+ break;
+ case 158:
+ name = "Silay";
+ break;
+ case 159:
+ name = "Surigao";
+ break;
+ case 161:
+ name = "Tacloban";
+ break;
+ case 162:
+ name = "Tagaytay";
+ break;
+ case 163:
+ name = "Tagbilaran";
+ break;
+ case 164:
+ name = "Tangub";
+ break;
+ case 165:
+ name = "Toledo";
+ break;
+ case 166:
+ name = "Trece Martires";
+ break;
+ case 167:
+ name = "Zamboanga";
+ break;
+ case 168:
+ name = "Aurora";
+ break;
+ case 172:
+ name = "Quezon";
+ break;
+ case 173:
+ name = "Negros Occidental";
+ break;
+ }
+ }
+ if (strcmp(country_code,"PK") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Federally Administered Tribal Areas";
+ break;
+ case 2:
+ name = "Balochistan";
+ break;
+ case 3:
+ name = "North-West Frontier";
+ break;
+ case 4:
+ name = "Punjab";
+ break;
+ case 5:
+ name = "Sindh";
+ break;
+ case 6:
+ name = "Azad Kashmir";
+ break;
+ case 7:
+ name = "Northern Areas";
+ break;
+ case 8:
+ name = "Islamabad";
+ break;
+ }
+ }
+ if (strcmp(country_code,"PL") == 0) {
+ switch (region_code2) {
+ case 23:
+ name = "Biala Podlaska";
+ break;
+ case 24:
+ name = "Bialystok";
+ break;
+ case 25:
+ name = "Bielsko";
+ break;
+ case 26:
+ name = "Bydgoszcz";
+ break;
+ case 27:
+ name = "Chelm";
+ break;
+ case 28:
+ name = "Ciechanow";
+ break;
+ case 29:
+ name = "Czestochowa";
+ break;
+ case 30:
+ name = "Elblag";
+ break;
+ case 31:
+ name = "Gdansk";
+ break;
+ case 32:
+ name = "Gorzow";
+ break;
+ case 33:
+ name = "Jelenia Gora";
+ break;
+ case 34:
+ name = "Kalisz";
+ break;
+ case 35:
+ name = "Katowice";
+ break;
+ case 36:
+ name = "Kielce";
+ break;
+ case 37:
+ name = "Konin";
+ break;
+ case 38:
+ name = "Koszalin";
+ break;
+ case 39:
+ name = "Krakow";
+ break;
+ case 40:
+ name = "Krosno";
+ break;
+ case 41:
+ name = "Legnica";
+ break;
+ case 42:
+ name = "Leszno";
+ break;
+ case 43:
+ name = "Lodz";
+ break;
+ case 44:
+ name = "Lomza";
+ break;
+ case 45:
+ name = "Lublin";
+ break;
+ case 46:
+ name = "Nowy Sacz";
+ break;
+ case 47:
+ name = "Olsztyn";
+ break;
+ case 48:
+ name = "Opole";
+ break;
+ case 49:
+ name = "Ostroleka";
+ break;
+ case 50:
+ name = "Pila";
+ break;
+ case 51:
+ name = "Piotrkow";
+ break;
+ case 52:
+ name = "Plock";
+ break;
+ case 53:
+ name = "Poznan";
+ break;
+ case 54:
+ name = "Przemysl";
+ break;
+ case 55:
+ name = "Radom";
+ break;
+ case 56:
+ name = "Rzeszow";
+ break;
+ case 57:
+ name = "Siedlce";
+ break;
+ case 58:
+ name = "Sieradz";
+ break;
+ case 59:
+ name = "Skierniewice";
+ break;
+ case 60:
+ name = "Slupsk";
+ break;
+ case 61:
+ name = "Suwalki";
+ break;
+ case 62:
+ name = "Szczecin";
+ break;
+ case 63:
+ name = "Tarnobrzeg";
+ break;
+ case 64:
+ name = "Tarnow";
+ break;
+ case 65:
+ name = "Torun";
+ break;
+ case 66:
+ name = "Walbrzych";
+ break;
+ case 67:
+ name = "Warszawa";
+ break;
+ case 68:
+ name = "Wloclawek";
+ break;
+ case 69:
+ name = "Wroclaw";
+ break;
+ case 70:
+ name = "Zamosc";
+ break;
+ case 71:
+ name = "Zielona Gora";
+ break;
+ case 72:
+ name = "Dolnoslaskie";
+ break;
+ case 73:
+ name = "Kujawsko-Pomorskie";
+ break;
+ case 74:
+ name = "Lodzkie";
+ break;
+ case 75:
+ name = "Lubelskie";
+ break;
+ case 76:
+ name = "Lubuskie";
+ break;
+ case 77:
+ name = "Malopolskie";
+ break;
+ case 78:
+ name = "Mazowieckie";
+ break;
+ case 79:
+ name = "Opolskie";
+ break;
+ case 80:
+ name = "Podkarpackie";
+ break;
+ case 81:
+ name = "Podlaskie";
+ break;
+ case 82:
+ name = "Pomorskie";
+ break;
+ case 83:
+ name = "Slaskie";
+ break;
+ case 84:
+ name = "Swietokrzyskie";
+ break;
+ case 85:
+ name = "Warminsko-Mazurskie";
+ break;
+ case 86:
+ name = "Wielkopolskie";
+ break;
+ case 87:
+ name = "Zachodniopomorskie";
+ break;
+ }
+ }
+ if (strcmp(country_code,"PT") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Aveiro";
+ break;
+ case 3:
+ name = "Beja";
+ break;
+ case 4:
+ name = "Braga";
+ break;
+ case 5:
+ name = "Braganca";
+ break;
+ case 6:
+ name = "Castelo Branco";
+ break;
+ case 7:
+ name = "Coimbra";
+ break;
+ case 8:
+ name = "Evora";
+ break;
+ case 9:
+ name = "Faro";
+ break;
+ case 10:
+ name = "Madeira";
+ break;
+ case 11:
+ name = "Guarda";
+ break;
+ case 13:
+ name = "Leiria";
+ break;
+ case 14:
+ name = "Lisboa";
+ break;
+ case 16:
+ name = "Portalegre";
+ break;
+ case 17:
+ name = "Porto";
+ break;
+ case 18:
+ name = "Santarem";
+ break;
+ case 19:
+ name = "Setubal";
+ break;
+ case 20:
+ name = "Viana do Castelo";
+ break;
+ case 21:
+ name = "Vila Real";
+ break;
+ case 22:
+ name = "Viseu";
+ break;
+ case 23:
+ name = "Azores";
+ break;
+ }
+ }
+ if (strcmp(country_code,"PY") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Alto Parana";
+ break;
+ case 2:
+ name = "Amambay";
+ break;
+ case 3:
+ name = "Boqueron";
+ break;
+ case 4:
+ name = "Caaguazu";
+ break;
+ case 5:
+ name = "Caazapa";
+ break;
+ case 6:
+ name = "Central";
+ break;
+ case 7:
+ name = "Concepcion";
+ break;
+ case 8:
+ name = "Cordillera";
+ break;
+ case 10:
+ name = "Guaira";
+ break;
+ case 11:
+ name = "Itapua";
+ break;
+ case 12:
+ name = "Misiones";
+ break;
+ case 13:
+ name = "Neembucu";
+ break;
+ case 15:
+ name = "Paraguari";
+ break;
+ case 16:
+ name = "Presidente Hayes";
+ break;
+ case 17:
+ name = "San Pedro";
+ break;
+ case 19:
+ name = "Canindeyu";
+ break;
+ case 20:
+ name = "Chaco";
+ break;
+ case 21:
+ name = "Nueva Asuncion";
+ break;
+ case 23:
+ name = "Alto Paraguay";
+ break;
+ }
+ }
+ if (strcmp(country_code,"QA") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Ad Dawhah";
+ break;
+ case 2:
+ name = "Al Ghuwariyah";
+ break;
+ case 3:
+ name = "Al Jumaliyah";
+ break;
+ case 4:
+ name = "Al Khawr";
+ break;
+ case 6:
+ name = "Ar Rayyan";
+ break;
+ case 8:
+ name = "Madinat ach Shamal";
+ break;
+ case 9:
+ name = "Umm Salal";
+ break;
+ case 10:
+ name = "Al Wakrah";
+ break;
+ case 11:
+ name = "Jariyan al Batnah";
+ break;
+ case 12:
+ name = "Umm Sa'id";
+ break;
+ }
+ }
+ if (strcmp(country_code,"RO") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Alba";
+ break;
+ case 2:
+ name = "Arad";
+ break;
+ case 3:
+ name = "Arges";
+ break;
+ case 4:
+ name = "Bacau";
+ break;
+ case 5:
+ name = "Bihor";
+ break;
+ case 6:
+ name = "Bistrita-Nasaud";
+ break;
+ case 7:
+ name = "Botosani";
+ break;
+ case 8:
+ name = "Braila";
+ break;
+ case 9:
+ name = "Brasov";
+ break;
+ case 10:
+ name = "Bucuresti";
+ break;
+ case 11:
+ name = "Buzau";
+ break;
+ case 12:
+ name = "Caras-Severin";
+ break;
+ case 13:
+ name = "Cluj";
+ break;
+ case 14:
+ name = "Constanta";
+ break;
+ case 15:
+ name = "Covasna";
+ break;
+ case 16:
+ name = "Dambovita";
+ break;
+ case 17:
+ name = "Dolj";
+ break;
+ case 18:
+ name = "Galati";
+ break;
+ case 19:
+ name = "Gorj";
+ break;
+ case 20:
+ name = "Harghita";
+ break;
+ case 21:
+ name = "Hunedoara";
+ break;
+ case 22:
+ name = "Ialomita";
+ break;
+ case 23:
+ name = "Iasi";
+ break;
+ case 25:
+ name = "Maramures";
+ break;
+ case 26:
+ name = "Mehedinti";
+ break;
+ case 27:
+ name = "Mures";
+ break;
+ case 28:
+ name = "Neamt";
+ break;
+ case 29:
+ name = "Olt";
+ break;
+ case 30:
+ name = "Prahova";
+ break;
+ case 31:
+ name = "Salaj";
+ break;
+ case 32:
+ name = "Satu Mare";
+ break;
+ case 33:
+ name = "Sibiu";
+ break;
+ case 34:
+ name = "Suceava";
+ break;
+ case 35:
+ name = "Teleorman";
+ break;
+ case 36:
+ name = "Timis";
+ break;
+ case 37:
+ name = "Tulcea";
+ break;
+ case 38:
+ name = "Vaslui";
+ break;
+ case 39:
+ name = "Valcea";
+ break;
+ case 40:
+ name = "Vrancea";
+ break;
+ case 41:
+ name = "Calarasi";
+ break;
+ case 42:
+ name = "Giurgiu";
+ break;
+ case 43:
+ name = "Ilfov";
+ break;
+ }
+ }
+ if (strcmp(country_code,"RU") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Adygeya";
+ break;
+ case 2:
+ name = "Aginsky Buryatsky AO";
+ break;
+ case 3:
+ name = "Gorno-Altay";
+ break;
+ case 4:
+ name = "Altaisky krai";
+ break;
+ case 5:
+ name = "Amur";
+ break;
+ case 6:
+ name = "Arkhangel'sk";
+ break;
+ case 7:
+ name = "Astrakhan'";
+ break;
+ case 8:
+ name = "Bashkortostan";
+ break;
+ case 9:
+ name = "Belgorod";
+ break;
+ case 10:
+ name = "Bryansk";
+ break;
+ case 11:
+ name = "Buryat";
+ break;
+ case 12:
+ name = "Chechnya";
+ break;
+ case 13:
+ name = "Chelyabinsk";
+ break;
+ case 14:
+ name = "Chita";
+ break;
+ case 15:
+ name = "Chukot";
+ break;
+ case 16:
+ name = "Chuvashia";
+ break;
+ case 17:
+ name = "Dagestan";
+ break;
+ case 18:
+ name = "Evenk";
+ break;
+ case 19:
+ name = "Ingush";
+ break;
+ case 20:
+ name = "Irkutsk";
+ break;
+ case 21:
+ name = "Ivanovo";
+ break;
+ case 22:
+ name = "Kabardin-Balkar";
+ break;
+ case 23:
+ name = "Kaliningrad";
+ break;
+ case 24:
+ name = "Kalmyk";
+ break;
+ case 25:
+ name = "Kaluga";
+ break;
+ case 26:
+ name = "Kamchatka";
+ break;
+ case 27:
+ name = "Karachay-Cherkess";
+ break;
+ case 28:
+ name = "Karelia";
+ break;
+ case 29:
+ name = "Kemerovo";
+ break;
+ case 30:
+ name = "Khabarovsk";
+ break;
+ case 31:
+ name = "Khakass";
+ break;
+ case 32:
+ name = "Khanty-Mansiy";
+ break;
+ case 33:
+ name = "Kirov";
+ break;
+ case 34:
+ name = "Komi";
+ break;
+ case 35:
+ name = "Komi-Permyak";
+ break;
+ case 36:
+ name = "Koryak";
+ break;
+ case 37:
+ name = "Kostroma";
+ break;
+ case 38:
+ name = "Krasnodar";
+ break;
+ case 39:
+ name = "Krasnoyarsk";
+ break;
+ case 40:
+ name = "Kurgan";
+ break;
+ case 41:
+ name = "Kursk";
+ break;
+ case 42:
+ name = "Leningrad";
+ break;
+ case 43:
+ name = "Lipetsk";
+ break;
+ case 44:
+ name = "Magadan";
+ break;
+ case 45:
+ name = "Mariy-El";
+ break;
+ case 46:
+ name = "Mordovia";
+ break;
+ case 47:
+ name = "Moskva";
+ break;
+ case 48:
+ name = "Moscow City";
+ break;
+ case 49:
+ name = "Murmansk";
+ break;
+ case 50:
+ name = "Nenets";
+ break;
+ case 51:
+ name = "Nizhegorod";
+ break;
+ case 52:
+ name = "Novgorod";
+ break;
+ case 53:
+ name = "Novosibirsk";
+ break;
+ case 54:
+ name = "Omsk";
+ break;
+ case 55:
+ name = "Orenburg";
+ break;
+ case 56:
+ name = "Orel";
+ break;
+ case 57:
+ name = "Penza";
+ break;
+ case 58:
+ name = "Perm'";
+ break;
+ case 59:
+ name = "Primor'ye";
+ break;
+ case 60:
+ name = "Pskov";
+ break;
+ case 61:
+ name = "Rostov";
+ break;
+ case 62:
+ name = "Ryazan'";
+ break;
+ case 63:
+ name = "Sakha";
+ break;
+ case 64:
+ name = "Sakhalin";
+ break;
+ case 65:
+ name = "Samara";
+ break;
+ case 66:
+ name = "Saint Petersburg City";
+ break;
+ case 67:
+ name = "Saratov";
+ break;
+ case 68:
+ name = "North Ossetia";
+ break;
+ case 69:
+ name = "Smolensk";
+ break;
+ case 70:
+ name = "Stavropol'";
+ break;
+ case 71:
+ name = "Sverdlovsk";
+ break;
+ case 72:
+ name = "Tambovskaya oblast";
+ break;
+ case 73:
+ name = "Tatarstan";
+ break;
+ case 74:
+ name = "Taymyr";
+ break;
+ case 75:
+ name = "Tomsk";
+ break;
+ case 76:
+ name = "Tula";
+ break;
+ case 77:
+ name = "Tver'";
+ break;
+ case 78:
+ name = "Tyumen'";
+ break;
+ case 79:
+ name = "Tuva";
+ break;
+ case 80:
+ name = "Udmurt";
+ break;
+ case 81:
+ name = "Ul'yanovsk";
+ break;
+ case 82:
+ name = "Ust-Orda Buryat";
+ break;
+ case 83:
+ name = "Vladimir";
+ break;
+ case 84:
+ name = "Volgograd";
+ break;
+ case 85:
+ name = "Vologda";
+ break;
+ case 86:
+ name = "Voronezh";
+ break;
+ case 87:
+ name = "Yamal-Nenets";
+ break;
+ case 88:
+ name = "Yaroslavl'";
+ break;
+ case 89:
+ name = "Yevrey";
+ break;
+ }
+ }
+ if (strcmp(country_code,"RW") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Butare";
+ break;
+ case 2:
+ name = "Byumba";
+ break;
+ case 3:
+ name = "Cyangugu";
+ break;
+ case 4:
+ name = "Gikongoro";
+ break;
+ case 5:
+ name = "Gisenyi";
+ break;
+ case 6:
+ name = "Gitarama";
+ break;
+ case 7:
+ name = "Kibungo";
+ break;
+ case 8:
+ name = "Kibuye";
+ break;
+ case 9:
+ name = "Kigali";
+ break;
+ case 10:
+ name = "Ruhengeri";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SA") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Al Bahah";
+ break;
+ case 3:
+ name = "Al Jawf";
+ break;
+ case 5:
+ name = "Al Madinah";
+ break;
+ case 6:
+ name = "Ash Sharqiyah";
+ break;
+ case 8:
+ name = "Al Qasim";
+ break;
+ case 9:
+ name = "Al Qurayyat";
+ break;
+ case 10:
+ name = "Ar Riyad";
+ break;
+ case 13:
+ name = "Ha'il";
+ break;
+ case 14:
+ name = "Makkah";
+ break;
+ case 15:
+ name = "Al Hudud ash Shamaliyah";
+ break;
+ case 16:
+ name = "Najran";
+ break;
+ case 17:
+ name = "Jizan";
+ break;
+ case 19:
+ name = "Tabuk";
+ break;
+ case 20:
+ name = "Al Jawf";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SB") == 0) {
+ switch (region_code2) {
+ case 3:
+ name = "Malaita";
+ break;
+ case 4:
+ name = "Western";
+ break;
+ case 5:
+ name = "Central";
+ break;
+ case 6:
+ name = "Guadalcanal";
+ break;
+ case 7:
+ name = "Isabel";
+ break;
+ case 8:
+ name = "Makira";
+ break;
+ case 9:
+ name = "Temotu";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SC") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Anse aux Pins";
+ break;
+ case 2:
+ name = "Anse Boileau";
+ break;
+ case 3:
+ name = "Anse Etoile";
+ break;
+ case 4:
+ name = "Anse Louis";
+ break;
+ case 5:
+ name = "Anse Royale";
+ break;
+ case 6:
+ name = "Baie Lazare";
+ break;
+ case 7:
+ name = "Baie Sainte Anne";
+ break;
+ case 8:
+ name = "Beau Vallon";
+ break;
+ case 9:
+ name = "Bel Air";
+ break;
+ case 10:
+ name = "Bel Ombre";
+ break;
+ case 11:
+ name = "Cascade";
+ break;
+ case 12:
+ name = "Glacis";
+ break;
+ case 13:
+ name = "Grand' Anse";
+ break;
+ case 14:
+ name = "Grand' Anse";
+ break;
+ case 15:
+ name = "La Digue";
+ break;
+ case 16:
+ name = "La Riviere Anglaise";
+ break;
+ case 17:
+ name = "Mont Buxton";
+ break;
+ case 18:
+ name = "Mont Fleuri";
+ break;
+ case 19:
+ name = "Plaisance";
+ break;
+ case 20:
+ name = "Pointe La Rue";
+ break;
+ case 21:
+ name = "Port Glaud";
+ break;
+ case 22:
+ name = "Saint Louis";
+ break;
+ case 23:
+ name = "Takamaka";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SD") == 0) {
+ switch (region_code2) {
+ case 27:
+ name = "Al Wusta";
+ break;
+ case 28:
+ name = "Al Istiwa'iyah";
+ break;
+ case 29:
+ name = "Al Khartum";
+ break;
+ case 30:
+ name = "Ash Shamaliyah";
+ break;
+ case 31:
+ name = "Ash Sharqiyah";
+ break;
+ case 32:
+ name = "Bahr al Ghazal";
+ break;
+ case 33:
+ name = "Darfur";
+ break;
+ case 34:
+ name = "Kurdufan";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Alvsborgs Lan";
+ break;
+ case 2:
+ name = "Blekinge Lan";
+ break;
+ case 3:
+ name = "Gavleborgs Lan";
+ break;
+ case 4:
+ name = "Goteborgs och Bohus Lan";
+ break;
+ case 5:
+ name = "Gotlands Lan";
+ break;
+ case 6:
+ name = "Hallands Lan";
+ break;
+ case 7:
+ name = "Jamtlands Lan";
+ break;
+ case 8:
+ name = "Jonkopings Lan";
+ break;
+ case 9:
+ name = "Kalmar Lan";
+ break;
+ case 10:
+ name = "Dalarnas Lan";
+ break;
+ case 11:
+ name = "Kristianstads Lan";
+ break;
+ case 12:
+ name = "Kronobergs Lan";
+ break;
+ case 13:
+ name = "Malmohus Lan";
+ break;
+ case 14:
+ name = "Norrbottens Lan";
+ break;
+ case 15:
+ name = "Orebro Lan";
+ break;
+ case 16:
+ name = "Ostergotlands Lan";
+ break;
+ case 17:
+ name = "Skaraborgs Lan";
+ break;
+ case 18:
+ name = "Sodermanlands Lan";
+ break;
+ case 21:
+ name = "Uppsala Lan";
+ break;
+ case 22:
+ name = "Varmlands Lan";
+ break;
+ case 23:
+ name = "Vasterbottens Lan";
+ break;
+ case 24:
+ name = "Vasternorrlands Lan";
+ break;
+ case 25:
+ name = "Vastmanlands Lan";
+ break;
+ case 26:
+ name = "Stockholms Lan";
+ break;
+ case 27:
+ name = "Skane Lan";
+ break;
+ case 28:
+ name = "Vastra Gotaland";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SH") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Ascension";
+ break;
+ case 2:
+ name = "Saint Helena";
+ break;
+ case 3:
+ name = "Tristan da Cunha";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SI") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Ajdovscina";
+ break;
+ case 2:
+ name = "Beltinci";
+ break;
+ case 3:
+ name = "Bled";
+ break;
+ case 4:
+ name = "Bohinj";
+ break;
+ case 5:
+ name = "Borovnica";
+ break;
+ case 6:
+ name = "Bovec";
+ break;
+ case 7:
+ name = "Brda";
+ break;
+ case 8:
+ name = "Brezice";
+ break;
+ case 9:
+ name = "Brezovica";
+ break;
+ case 11:
+ name = "Celje";
+ break;
+ case 12:
+ name = "Cerklje na Gorenjskem";
+ break;
+ case 13:
+ name = "Cerknica";
+ break;
+ case 14:
+ name = "Cerkno";
+ break;
+ case 15:
+ name = "Crensovci";
+ break;
+ case 16:
+ name = "Crna na Koroskem";
+ break;
+ case 17:
+ name = "Crnomelj";
+ break;
+ case 19:
+ name = "Divaca";
+ break;
+ case 20:
+ name = "Dobrepolje";
+ break;
+ case 22:
+ name = "Dol pri Ljubljani";
+ break;
+ case 24:
+ name = "Dornava";
+ break;
+ case 25:
+ name = "Dravograd";
+ break;
+ case 26:
+ name = "Duplek";
+ break;
+ case 27:
+ name = "Gorenja Vas-Poljane";
+ break;
+ case 28:
+ name = "Gorisnica";
+ break;
+ case 29:
+ name = "Gornja Radgona";
+ break;
+ case 30:
+ name = "Gornji Grad";
+ break;
+ case 31:
+ name = "Gornji Petrovci";
+ break;
+ case 32:
+ name = "Grosuplje";
+ break;
+ case 34:
+ name = "Hrastnik";
+ break;
+ case 35:
+ name = "Hrpelje-Kozina";
+ break;
+ case 36:
+ name = "Idrija";
+ break;
+ case 37:
+ name = "Ig";
+ break;
+ case 38:
+ name = "Ilirska Bistrica";
+ break;
+ case 39:
+ name = "Ivancna Gorica";
+ break;
+ case 40:
+ name = "Izola-Isola";
+ break;
+ case 42:
+ name = "Jursinci";
+ break;
+ case 44:
+ name = "Kanal";
+ break;
+ case 45:
+ name = "Kidricevo";
+ break;
+ case 46:
+ name = "Kobarid";
+ break;
+ case 47:
+ name = "Kobilje";
+ break;
+ case 49:
+ name = "Komen";
+ break;
+ case 50:
+ name = "Koper-Capodistria";
+ break;
+ case 51:
+ name = "Kozje";
+ break;
+ case 52:
+ name = "Kranj";
+ break;
+ case 53:
+ name = "Kranjska Gora";
+ break;
+ case 54:
+ name = "Krsko";
+ break;
+ case 55:
+ name = "Kungota";
+ break;
+ case 57:
+ name = "Lasko";
+ break;
+ case 61:
+ name = "Ljubljana";
+ break;
+ case 62:
+ name = "Ljubno";
+ break;
+ case 64:
+ name = "Logatec";
+ break;
+ case 66:
+ name = "Loski Potok";
+ break;
+ case 68:
+ name = "Lukovica";
+ break;
+ case 71:
+ name = "Medvode";
+ break;
+ case 72:
+ name = "Menges";
+ break;
+ case 73:
+ name = "Metlika";
+ break;
+ case 74:
+ name = "Mezica";
+ break;
+ case 76:
+ name = "Mislinja";
+ break;
+ case 77:
+ name = "Moravce";
+ break;
+ case 78:
+ name = "Moravske Toplice";
+ break;
+ case 79:
+ name = "Mozirje";
+ break;
+ case 80:
+ name = "Murska Sobota";
+ break;
+ case 81:
+ name = "Muta";
+ break;
+ case 82:
+ name = "Naklo";
+ break;
+ case 83:
+ name = "Nazarje";
+ break;
+ case 84:
+ name = "Nova Gorica";
+ break;
+ case 86:
+ name = "Odranci";
+ break;
+ case 87:
+ name = "Ormoz";
+ break;
+ case 88:
+ name = "Osilnica";
+ break;
+ case 89:
+ name = "Pesnica";
+ break;
+ case 91:
+ name = "Pivka";
+ break;
+ case 92:
+ name = "Podcetrtek";
+ break;
+ case 94:
+ name = "Postojna";
+ break;
+ case 97:
+ name = "Puconci";
+ break;
+ case 98:
+ name = "Racam";
+ break;
+ case 99:
+ name = "Radece";
+ break;
+ case 101:
+ name = "Radenci";
+ break;
+ case 102:
+ name = "Radlje ob Dravi";
+ break;
+ case 103:
+ name = "Radovljica";
+ break;
+ case 106:
+ name = "Rogasovci";
+ break;
+ case 107:
+ name = "Rogaska Slatina";
+ break;
+ case 108:
+ name = "Rogatec";
+ break;
+ case 111:
+ name = "Semic";
+ break;
+ case 112:
+ name = "Sencur";
+ break;
+ case 113:
+ name = "Sentilj";
+ break;
+ case 114:
+ name = "Sentjernej";
+ break;
+ case 116:
+ name = "Sevnica";
+ break;
+ case 117:
+ name = "Sezana";
+ break;
+ case 118:
+ name = "Skocjan";
+ break;
+ case 119:
+ name = "Skofja Loka";
+ break;
+ case 121:
+ name = "Skofljica";
+ break;
+ case 122:
+ name = "Slovenj Gradec";
+ break;
+ case 124:
+ name = "Slovenske Konjice";
+ break;
+ case 125:
+ name = "Smarje pri Jelsah";
+ break;
+ case 126:
+ name = "Smartno ob Paki";
+ break;
+ case 127:
+ name = "Sostanj";
+ break;
+ case 128:
+ name = "Starse";
+ break;
+ case 129:
+ name = "Store";
+ break;
+ case 131:
+ name = "Sveti Jurij";
+ break;
+ case 132:
+ name = "Tolmin";
+ break;
+ case 133:
+ name = "Trbovlje";
+ break;
+ case 134:
+ name = "Trebnje";
+ break;
+ case 135:
+ name = "Trzic";
+ break;
+ case 136:
+ name = "Turnisce";
+ break;
+ case 137:
+ name = "Velenje";
+ break;
+ case 138:
+ name = "Velike Lasce";
+ break;
+ case 141:
+ name = "Vipava";
+ break;
+ case 142:
+ name = "Vitanje";
+ break;
+ case 143:
+ name = "Vodice";
+ break;
+ case 145:
+ name = "Vrhnika";
+ break;
+ case 146:
+ name = "Vuzenica";
+ break;
+ case 147:
+ name = "Zagorje ob Savi";
+ break;
+ case 149:
+ name = "Zavrc";
+ break;
+ case 151:
+ name = "Zelezniki";
+ break;
+ case 152:
+ name = "Ziri";
+ break;
+ case 153:
+ name = "Zrece";
+ break;
+ case 164:
+ name = "Dobrova-Horjul-Polhov Gradec";
+ break;
+ case 167:
+ name = "Domzale";
+ break;
+ case 174:
+ name = "Jesenice";
+ break;
+ case 176:
+ name = "Kamnik";
+ break;
+ case 177:
+ name = "Kocevje";
+ break;
+ case 182:
+ name = "Kuzma";
+ break;
+ case 183:
+ name = "Lenart";
+ break;
+ case 185:
+ name = "Litija";
+ break;
+ case 186:
+ name = "Ljutomer";
+ break;
+ case 187:
+ name = "Loska Dolina";
+ break;
+ case 189:
+ name = "Luce";
+ break;
+ case 191:
+ name = "Majsperk";
+ break;
+ case 192:
+ name = "Maribor";
+ break;
+ case 195:
+ name = "Miren-Kostanjevica";
+ break;
+ case 197:
+ name = "Novo Mesto";
+ break;
+ case 199:
+ name = "Piran";
+ break;
+ case 205:
+ name = "Preddvor";
+ break;
+ case 207:
+ name = "Ptuj";
+ break;
+ case 211:
+ name = "Ribnica";
+ break;
+ case 213:
+ name = "Ruse";
+ break;
+ case 217:
+ name = "Sentjur pri Celju";
+ break;
+ case 218:
+ name = "Slovenska Bistrica";
+ break;
+ case 232:
+ name = "Videm";
+ break;
+ case 233:
+ name = "Vojnik";
+ break;
+ case 235:
+ name = "Zalec";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SK") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Banska Bystrica";
+ break;
+ case 2:
+ name = "Bratislava";
+ break;
+ case 3:
+ name = "Kosice";
+ break;
+ case 4:
+ name = "Nitra";
+ break;
+ case 5:
+ name = "Presov";
+ break;
+ case 6:
+ name = "Trencin";
+ break;
+ case 7:
+ name = "Trnava";
+ break;
+ case 8:
+ name = "Zilina";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SL") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Eastern";
+ break;
+ case 2:
+ name = "Northern";
+ break;
+ case 3:
+ name = "Southern";
+ break;
+ case 4:
+ name = "Western Area";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Acquaviva";
+ break;
+ case 2:
+ name = "Chiesanuova";
+ break;
+ case 3:
+ name = "Domagnano";
+ break;
+ case 4:
+ name = "Faetano";
+ break;
+ case 5:
+ name = "Fiorentino";
+ break;
+ case 6:
+ name = "Borgo Maggiore";
+ break;
+ case 7:
+ name = "San Marino";
+ break;
+ case 8:
+ name = "Monte Giardino";
+ break;
+ case 9:
+ name = "Serravalle";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SN") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Dakar";
+ break;
+ case 3:
+ name = "Diourbel";
+ break;
+ case 4:
+ name = "Saint-Louis";
+ break;
+ case 5:
+ name = "Tambacounda";
+ break;
+ case 7:
+ name = "Thies";
+ break;
+ case 8:
+ name = "Louga";
+ break;
+ case 9:
+ name = "Fatick";
+ break;
+ case 10:
+ name = "Kaolack";
+ break;
+ case 11:
+ name = "Kolda";
+ break;
+ case 12:
+ name = "Ziguinchor";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SO") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bakool";
+ break;
+ case 2:
+ name = "Banaadir";
+ break;
+ case 3:
+ name = "Bari";
+ break;
+ case 4:
+ name = "Bay";
+ break;
+ case 5:
+ name = "Galguduud";
+ break;
+ case 6:
+ name = "Gedo";
+ break;
+ case 7:
+ name = "Hiiraan";
+ break;
+ case 8:
+ name = "Jubbada Dhexe";
+ break;
+ case 9:
+ name = "Jubbada Hoose";
+ break;
+ case 10:
+ name = "Mudug";
+ break;
+ case 11:
+ name = "Nugaal";
+ break;
+ case 12:
+ name = "Sanaag";
+ break;
+ case 13:
+ name = "Shabeellaha Dhexe";
+ break;
+ case 14:
+ name = "Shabeellaha Hoose";
+ break;
+ case 15:
+ name = "Togdheer";
+ break;
+ case 16:
+ name = "Woqooyi Galbeed";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SR") == 0) {
+ switch (region_code2) {
+ case 10:
+ name = "Brokopondo";
+ break;
+ case 11:
+ name = "Commewijne";
+ break;
+ case 12:
+ name = "Coronie";
+ break;
+ case 13:
+ name = "Marowijne";
+ break;
+ case 14:
+ name = "Nickerie";
+ break;
+ case 15:
+ name = "Para";
+ break;
+ case 16:
+ name = "Paramaribo";
+ break;
+ case 17:
+ name = "Saramacca";
+ break;
+ case 18:
+ name = "Sipaliwini";
+ break;
+ case 19:
+ name = "Wanica";
+ break;
+ }
+ }
+ if (strcmp(country_code,"ST") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Principe";
+ break;
+ case 2:
+ name = "Sao Tome";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SV") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Ahuachapan";
+ break;
+ case 2:
+ name = "Cabanas";
+ break;
+ case 3:
+ name = "Chalatenango";
+ break;
+ case 4:
+ name = "Cuscatlan";
+ break;
+ case 5:
+ name = "La Libertad";
+ break;
+ case 6:
+ name = "La Paz";
+ break;
+ case 7:
+ name = "La Union";
+ break;
+ case 8:
+ name = "Morazan";
+ break;
+ case 9:
+ name = "San Miguel";
+ break;
+ case 10:
+ name = "San Salvador";
+ break;
+ case 11:
+ name = "Santa Ana";
+ break;
+ case 12:
+ name = "San Vicente";
+ break;
+ case 13:
+ name = "Sonsonate";
+ break;
+ case 14:
+ name = "Usulutan";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SY") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Al Hasakah";
+ break;
+ case 2:
+ name = "Al Ladhiqiyah";
+ break;
+ case 3:
+ name = "Al Qunaytirah";
+ break;
+ case 4:
+ name = "Ar Raqqah";
+ break;
+ case 5:
+ name = "As Suwayda'";
+ break;
+ case 6:
+ name = "Dar";
+ break;
+ case 7:
+ name = "Dayr az Zawr";
+ break;
+ case 8:
+ name = "Rif Dimashq";
+ break;
+ case 9:
+ name = "Halab";
+ break;
+ case 10:
+ name = "Hamah";
+ break;
+ case 11:
+ name = "Hims";
+ break;
+ case 12:
+ name = "Idlib";
+ break;
+ case 13:
+ name = "Dimashq";
+ break;
+ case 14:
+ name = "Tartus";
+ break;
+ }
+ }
+ if (strcmp(country_code,"SZ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Hhohho";
+ break;
+ case 2:
+ name = "Lubombo";
+ break;
+ case 3:
+ name = "Manzini";
+ break;
+ case 4:
+ name = "Shiselweni";
+ break;
+ case 5:
+ name = "Praslin";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TD") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Batha";
+ break;
+ case 2:
+ name = "Biltine";
+ break;
+ case 3:
+ name = "Borkou-Ennedi-Tibesti";
+ break;
+ case 4:
+ name = "Chari-Baguirmi";
+ break;
+ case 5:
+ name = "Guera";
+ break;
+ case 6:
+ name = "Kanem";
+ break;
+ case 7:
+ name = "Lac";
+ break;
+ case 8:
+ name = "Logone Occidental";
+ break;
+ case 9:
+ name = "Logone Oriental";
+ break;
+ case 10:
+ name = "Mayo-Kebbi";
+ break;
+ case 11:
+ name = "Moyen-Chari";
+ break;
+ case 12:
+ name = "Ouaddai";
+ break;
+ case 13:
+ name = "Salamat";
+ break;
+ case 14:
+ name = "Tandjile";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TG") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Amlame";
+ break;
+ case 2:
+ name = "Aneho";
+ break;
+ case 3:
+ name = "Atakpame";
+ break;
+ case 4:
+ name = "Bafilo";
+ break;
+ case 5:
+ name = "Bassar";
+ break;
+ case 6:
+ name = "Dapaong";
+ break;
+ case 7:
+ name = "Kante";
+ break;
+ case 8:
+ name = "Klouto";
+ break;
+ case 9:
+ name = "Lama-Kara";
+ break;
+ case 10:
+ name = "Lome";
+ break;
+ case 11:
+ name = "Mango";
+ break;
+ case 12:
+ name = "Niamtougou";
+ break;
+ case 13:
+ name = "Notse";
+ break;
+ case 14:
+ name = "Kpagouda";
+ break;
+ case 15:
+ name = "Badou";
+ break;
+ case 16:
+ name = "Sotouboua";
+ break;
+ case 17:
+ name = "Tabligbo";
+ break;
+ case 18:
+ name = "Tsevie";
+ break;
+ case 19:
+ name = "Tchamba";
+ break;
+ case 20:
+ name = "Tchaoudjo";
+ break;
+ case 21:
+ name = "Vogan";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TH") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Mae Hong Son";
+ break;
+ case 2:
+ name = "Chiang Mai";
+ break;
+ case 3:
+ name = "Chiang Rai";
+ break;
+ case 4:
+ name = "Nan";
+ break;
+ case 5:
+ name = "Lamphun";
+ break;
+ case 6:
+ name = "Lampang";
+ break;
+ case 7:
+ name = "Phrae";
+ break;
+ case 8:
+ name = "Tak";
+ break;
+ case 9:
+ name = "Sukhothai";
+ break;
+ case 10:
+ name = "Uttaradit";
+ break;
+ case 11:
+ name = "Kamphaeng Phet";
+ break;
+ case 12:
+ name = "Phitsanulok";
+ break;
+ case 13:
+ name = "Phichit";
+ break;
+ case 14:
+ name = "Phetchabun";
+ break;
+ case 15:
+ name = "Uthai Thani";
+ break;
+ case 16:
+ name = "Nakhon Sawan";
+ break;
+ case 17:
+ name = "Nong Khai";
+ break;
+ case 18:
+ name = "Loei";
+ break;
+ case 20:
+ name = "Sakon Nakhon";
+ break;
+ case 21:
+ name = "Nakhon Phanom";
+ break;
+ case 22:
+ name = "Khon Kaen";
+ break;
+ case 23:
+ name = "Kalasin";
+ break;
+ case 24:
+ name = "Maha Sarakham";
+ break;
+ case 25:
+ name = "Roi Et";
+ break;
+ case 26:
+ name = "Chaiyaphum";
+ break;
+ case 27:
+ name = "Nakhon Ratchasima";
+ break;
+ case 28:
+ name = "Buriram";
+ break;
+ case 29:
+ name = "Surin";
+ break;
+ case 30:
+ name = "Sisaket";
+ break;
+ case 31:
+ name = "Narathiwat";
+ break;
+ case 32:
+ name = "Chai Nat";
+ break;
+ case 33:
+ name = "Sing Buri";
+ break;
+ case 34:
+ name = "Lop Buri";
+ break;
+ case 35:
+ name = "Ang Thong";
+ break;
+ case 36:
+ name = "Phra Nakhon Si Ayutthaya";
+ break;
+ case 37:
+ name = "Saraburi";
+ break;
+ case 38:
+ name = "Nonthaburi";
+ break;
+ case 39:
+ name = "Pathum Thani";
+ break;
+ case 40:
+ name = "Krung Thep";
+ break;
+ case 41:
+ name = "Phayao";
+ break;
+ case 42:
+ name = "Samut Prakan";
+ break;
+ case 43:
+ name = "Nakhon Nayok";
+ break;
+ case 44:
+ name = "Chachoengsao";
+ break;
+ case 45:
+ name = "Prachin Buri";
+ break;
+ case 46:
+ name = "Chon Buri";
+ break;
+ case 47:
+ name = "Rayong";
+ break;
+ case 48:
+ name = "Chanthaburi";
+ break;
+ case 49:
+ name = "Trat";
+ break;
+ case 50:
+ name = "Kanchanaburi";
+ break;
+ case 51:
+ name = "Suphan Buri";
+ break;
+ case 52:
+ name = "Ratchaburi";
+ break;
+ case 53:
+ name = "Nakhon Pathom";
+ break;
+ case 54:
+ name = "Samut Songkhram";
+ break;
+ case 55:
+ name = "Samut Sakhon";
+ break;
+ case 56:
+ name = "Phetchaburi";
+ break;
+ case 57:
+ name = "Prachuap Khiri Khan";
+ break;
+ case 58:
+ name = "Chumphon";
+ break;
+ case 59:
+ name = "Ranong";
+ break;
+ case 60:
+ name = "Surat Thani";
+ break;
+ case 61:
+ name = "Phangnga";
+ break;
+ case 62:
+ name = "Phuket";
+ break;
+ case 63:
+ name = "Krabi";
+ break;
+ case 64:
+ name = "Nakhon Si Thammarat";
+ break;
+ case 65:
+ name = "Trang";
+ break;
+ case 66:
+ name = "Phatthalung";
+ break;
+ case 67:
+ name = "Satun";
+ break;
+ case 68:
+ name = "Songkhla";
+ break;
+ case 69:
+ name = "Pattani";
+ break;
+ case 70:
+ name = "Yala";
+ break;
+ case 72:
+ name = "Yasothon";
+ break;
+ case 75:
+ name = "Ubon Ratchathani";
+ break;
+ case 76:
+ name = "Udon Thani";
+ break;
+ case 78:
+ name = "Mukdahan";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TJ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Kuhistoni Badakhshon";
+ break;
+ case 2:
+ name = "Khatlon";
+ break;
+ case 3:
+ name = "Sughd";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Ahal";
+ break;
+ case 2:
+ name = "Balkan";
+ break;
+ case 3:
+ name = "Dashoguz";
+ break;
+ case 4:
+ name = "Lebap";
+ break;
+ case 5:
+ name = "Mary";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TN") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Al Qasrayn";
+ break;
+ case 3:
+ name = "Al Qayrawan";
+ break;
+ case 6:
+ name = "Jundubah";
+ break;
+ case 10:
+ name = "Qafsah";
+ break;
+ case 14:
+ name = "Kef";
+ break;
+ case 15:
+ name = "Al Mahdiyah";
+ break;
+ case 16:
+ name = "Al Munastir";
+ break;
+ case 17:
+ name = "Bajah";
+ break;
+ case 18:
+ name = "Banzart";
+ break;
+ case 19:
+ name = "Nabul";
+ break;
+ case 22:
+ name = "Silyanah";
+ break;
+ case 23:
+ name = "Susah";
+ break;
+ case 27:
+ name = "Bin";
+ break;
+ case 28:
+ name = "Madanin";
+ break;
+ case 29:
+ name = "Qabis";
+ break;
+ case 31:
+ name = "Qibili";
+ break;
+ case 32:
+ name = "Safaqis";
+ break;
+ case 33:
+ name = "Sidi Bu Zayd";
+ break;
+ case 34:
+ name = "Tatawin";
+ break;
+ case 35:
+ name = "Tawzar";
+ break;
+ case 36:
+ name = "Tunis";
+ break;
+ case 37:
+ name = "Zaghwan";
+ break;
+ case 38:
+ name = "Ariana";
+ break;
+ case 39:
+ name = "Manouba";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TO") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Ha";
+ break;
+ case 2:
+ name = "Tongatapu";
+ break;
+ case 3:
+ name = "Vava";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TR") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Adiyaman";
+ break;
+ case 3:
+ name = "Afyon";
+ break;
+ case 4:
+ name = "Agri";
+ break;
+ case 5:
+ name = "Amasya";
+ break;
+ case 7:
+ name = "Antalya";
+ break;
+ case 8:
+ name = "Artvin";
+ break;
+ case 9:
+ name = "Aydin";
+ break;
+ case 10:
+ name = "Balikesir";
+ break;
+ case 11:
+ name = "Bilecik";
+ break;
+ case 12:
+ name = "Bingol";
+ break;
+ case 13:
+ name = "Bitlis";
+ break;
+ case 14:
+ name = "Bolu";
+ break;
+ case 15:
+ name = "Burdur";
+ break;
+ case 16:
+ name = "Bursa";
+ break;
+ case 17:
+ name = "Canakkale";
+ break;
+ case 19:
+ name = "Corum";
+ break;
+ case 20:
+ name = "Denizli";
+ break;
+ case 21:
+ name = "Diyarbakir";
+ break;
+ case 22:
+ name = "Edirne";
+ break;
+ case 23:
+ name = "Elazig";
+ break;
+ case 24:
+ name = "Erzincan";
+ break;
+ case 25:
+ name = "Erzurum";
+ break;
+ case 26:
+ name = "Eskisehir";
+ break;
+ case 28:
+ name = "Giresun";
+ break;
+ case 31:
+ name = "Hatay";
+ break;
+ case 32:
+ name = "Icel";
+ break;
+ case 33:
+ name = "Isparta";
+ break;
+ case 34:
+ name = "Istanbul";
+ break;
+ case 35:
+ name = "Izmir";
+ break;
+ case 37:
+ name = "Kastamonu";
+ break;
+ case 38:
+ name = "Kayseri";
+ break;
+ case 39:
+ name = "Kirklareli";
+ break;
+ case 40:
+ name = "Kirsehir";
+ break;
+ case 41:
+ name = "Kocaeli";
+ break;
+ case 43:
+ name = "Kutahya";
+ break;
+ case 44:
+ name = "Malatya";
+ break;
+ case 45:
+ name = "Manisa";
+ break;
+ case 46:
+ name = "Kahramanmaras";
+ break;
+ case 48:
+ name = "Mugla";
+ break;
+ case 49:
+ name = "Mus";
+ break;
+ case 50:
+ name = "Nevsehir";
+ break;
+ case 52:
+ name = "Ordu";
+ break;
+ case 53:
+ name = "Rize";
+ break;
+ case 54:
+ name = "Sakarya";
+ break;
+ case 55:
+ name = "Samsun";
+ break;
+ case 57:
+ name = "Sinop";
+ break;
+ case 58:
+ name = "Sivas";
+ break;
+ case 59:
+ name = "Tekirdag";
+ break;
+ case 60:
+ name = "Tokat";
+ break;
+ case 61:
+ name = "Trabzon";
+ break;
+ case 62:
+ name = "Tunceli";
+ break;
+ case 63:
+ name = "Sanliurfa";
+ break;
+ case 64:
+ name = "Usak";
+ break;
+ case 65:
+ name = "Van";
+ break;
+ case 66:
+ name = "Yozgat";
+ break;
+ case 68:
+ name = "Ankara";
+ break;
+ case 69:
+ name = "Gumushane";
+ break;
+ case 70:
+ name = "Hakkari";
+ break;
+ case 71:
+ name = "Konya";
+ break;
+ case 72:
+ name = "Mardin";
+ break;
+ case 73:
+ name = "Nigde";
+ break;
+ case 74:
+ name = "Siirt";
+ break;
+ case 75:
+ name = "Aksaray";
+ break;
+ case 76:
+ name = "Batman";
+ break;
+ case 77:
+ name = "Bayburt";
+ break;
+ case 78:
+ name = "Karaman";
+ break;
+ case 79:
+ name = "Kirikkale";
+ break;
+ case 80:
+ name = "Sirnak";
+ break;
+ case 81:
+ name = "Adana";
+ break;
+ case 82:
+ name = "Cankiri";
+ break;
+ case 83:
+ name = "Gaziantep";
+ break;
+ case 84:
+ name = "Kars";
+ break;
+ case 85:
+ name = "Zonguldak";
+ break;
+ case 86:
+ name = "Ardahan";
+ break;
+ case 87:
+ name = "Bartin";
+ break;
+ case 88:
+ name = "Igdir";
+ break;
+ case 89:
+ name = "Karabuk";
+ break;
+ case 90:
+ name = "Kilis";
+ break;
+ case 91:
+ name = "Osmaniye";
+ break;
+ case 92:
+ name = "Yalova";
+ break;
+ case 93:
+ name = "Duzce";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TT") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Arima";
+ break;
+ case 2:
+ name = "Caroni";
+ break;
+ case 3:
+ name = "Mayaro";
+ break;
+ case 4:
+ name = "Nariva";
+ break;
+ case 5:
+ name = "Port-of-Spain";
+ break;
+ case 6:
+ name = "Saint Andrew";
+ break;
+ case 7:
+ name = "Saint David";
+ break;
+ case 8:
+ name = "Saint George";
+ break;
+ case 9:
+ name = "Saint Patrick";
+ break;
+ case 10:
+ name = "San Fernando";
+ break;
+ case 11:
+ name = "Tobago";
+ break;
+ case 12:
+ name = "Victoria";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TW") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Fu-chien";
+ break;
+ case 2:
+ name = "Kao-hsiung";
+ break;
+ case 3:
+ name = "T'ai-pei";
+ break;
+ case 4:
+ name = "T'ai-wan";
+ break;
+ }
+ }
+ if (strcmp(country_code,"TZ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Arusha";
+ break;
+ case 2:
+ name = "Pwani";
+ break;
+ case 3:
+ name = "Dodoma";
+ break;
+ case 4:
+ name = "Iringa";
+ break;
+ case 5:
+ name = "Kigoma";
+ break;
+ case 6:
+ name = "Kilimanjaro";
+ break;
+ case 7:
+ name = "Lindi";
+ break;
+ case 8:
+ name = "Mara";
+ break;
+ case 9:
+ name = "Mbeya";
+ break;
+ case 10:
+ name = "Morogoro";
+ break;
+ case 11:
+ name = "Mtwara";
+ break;
+ case 12:
+ name = "Mwanza";
+ break;
+ case 13:
+ name = "Pemba North";
+ break;
+ case 14:
+ name = "Ruvuma";
+ break;
+ case 15:
+ name = "Shinyanga";
+ break;
+ case 16:
+ name = "Singida";
+ break;
+ case 17:
+ name = "Tabora";
+ break;
+ case 18:
+ name = "Tanga";
+ break;
+ case 19:
+ name = "Kagera";
+ break;
+ case 20:
+ name = "Pemba South";
+ break;
+ case 21:
+ name = "Zanzibar Central";
+ break;
+ case 22:
+ name = "Zanzibar North";
+ break;
+ case 23:
+ name = "Dar es Salaam";
+ break;
+ case 24:
+ name = "Rukwa";
+ break;
+ case 25:
+ name = "Zanzibar Urban";
+ break;
+ }
+ }
+ if (strcmp(country_code,"UA") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Cherkas'ka Oblast'";
+ break;
+ case 2:
+ name = "Chernihivs'ka Oblast'";
+ break;
+ case 3:
+ name = "Chernivets'ka Oblast'";
+ break;
+ case 4:
+ name = "Dnipropetrovs'ka Oblast'";
+ break;
+ case 5:
+ name = "Donets'ka Oblast'";
+ break;
+ case 6:
+ name = "Ivano-Frankivs'ka Oblast'";
+ break;
+ case 7:
+ name = "Kharkivs'ka Oblast'";
+ break;
+ case 8:
+ name = "Khersons'ka Oblast'";
+ break;
+ case 9:
+ name = "Khmel'nyts'ka Oblast'";
+ break;
+ case 10:
+ name = "Kirovohrads'ka Oblast'";
+ break;
+ case 11:
+ name = "Krym";
+ break;
+ case 12:
+ name = "Kyyiv";
+ break;
+ case 13:
+ name = "Kyyivs'ka Oblast'";
+ break;
+ case 14:
+ name = "Luhans'ka Oblast'";
+ break;
+ case 15:
+ name = "L'vivs'ka Oblast'";
+ break;
+ case 16:
+ name = "Mykolayivs'ka Oblast'";
+ break;
+ case 17:
+ name = "Odes'ka Oblast'";
+ break;
+ case 18:
+ name = "Poltavs'ka Oblast'";
+ break;
+ case 19:
+ name = "Rivnens'ka Oblast'";
+ break;
+ case 20:
+ name = "Sevastopol'";
+ break;
+ case 21:
+ name = "Sums'ka Oblast'";
+ break;
+ case 22:
+ name = "Ternopil's'ka Oblast'";
+ break;
+ case 23:
+ name = "Vinnyts'ka Oblast'";
+ break;
+ case 24:
+ name = "Volyns'ka Oblast'";
+ break;
+ case 25:
+ name = "Zakarpats'ka Oblast'";
+ break;
+ case 26:
+ name = "Zaporiz'ka Oblast'";
+ break;
+ case 27:
+ name = "Zhytomyrs'ka Oblast'";
+ break;
+ }
+ }
+ if (strcmp(country_code,"UG") == 0) {
+ switch (region_code2) {
+ case 5:
+ name = "Busoga";
+ break;
+ case 8:
+ name = "Karamoja";
+ break;
+ case 12:
+ name = "South Buganda";
+ break;
+ case 18:
+ name = "Central";
+ break;
+ case 20:
+ name = "Eastern";
+ break;
+ case 21:
+ name = "Nile";
+ break;
+ case 22:
+ name = "North Buganda";
+ break;
+ case 23:
+ name = "Northern";
+ break;
+ case 24:
+ name = "Southern";
+ break;
+ case 25:
+ name = "Western";
+ break;
+ case 37:
+ name = "Kampala";
+ break;
+ case 65:
+ name = "Adjumani";
+ break;
+ case 66:
+ name = "Bugiri";
+ break;
+ case 67:
+ name = "Busia";
+ break;
+ case 69:
+ name = "Katakwi";
+ break;
+ case 73:
+ name = "Nakasongola";
+ break;
+ case 74:
+ name = "Sembabule";
+ break;
+ case 77:
+ name = "Arua";
+ break;
+ case 78:
+ name = "Iganga";
+ break;
+ case 79:
+ name = "Kabarole";
+ break;
+ case 80:
+ name = "Kaberamaido";
+ break;
+ case 81:
+ name = "Kamwenge";
+ break;
+ case 82:
+ name = "Kanungu";
+ break;
+ case 83:
+ name = "Kayunga";
+ break;
+ case 84:
+ name = "Kitgum";
+ break;
+ case 85:
+ name = "Kyenjojo";
+ break;
+ case 86:
+ name = "Mayuge";
+ break;
+ case 87:
+ name = "Mbale";
+ break;
+ case 88:
+ name = "Moroto";
+ break;
+ case 89:
+ name = "Mpigi";
+ break;
+ case 90:
+ name = "Mukono";
+ break;
+ case 91:
+ name = "Nakapiripirit";
+ break;
+ case 92:
+ name = "Pader";
+ break;
+ case 93:
+ name = "Rukungiri";
+ break;
+ case 94:
+ name = "Sironko";
+ break;
+ case 95:
+ name = "Soroti";
+ break;
+ case 96:
+ name = "Wakiso";
+ break;
+ case 97:
+ name = "Yumbe";
+ break;
+ }
+ }
+ if (strcmp(country_code,"UY") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Artigas";
+ break;
+ case 2:
+ name = "Canelones";
+ break;
+ case 3:
+ name = "Cerro Largo";
+ break;
+ case 4:
+ name = "Colonia";
+ break;
+ case 5:
+ name = "Durazno";
+ break;
+ case 6:
+ name = "Flores";
+ break;
+ case 7:
+ name = "Florida";
+ break;
+ case 8:
+ name = "Lavalleja";
+ break;
+ case 9:
+ name = "Maldonado";
+ break;
+ case 10:
+ name = "Montevideo";
+ break;
+ case 11:
+ name = "Paysandu";
+ break;
+ case 12:
+ name = "Rio Negro";
+ break;
+ case 13:
+ name = "Rivera";
+ break;
+ case 14:
+ name = "Rocha";
+ break;
+ case 15:
+ name = "Salto";
+ break;
+ case 16:
+ name = "San Jose";
+ break;
+ case 17:
+ name = "Soriano";
+ break;
+ case 18:
+ name = "Tacuarembo";
+ break;
+ case 19:
+ name = "Treinta y Tres";
+ break;
+ }
+ }
+ if (strcmp(country_code,"UZ") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Andijon";
+ break;
+ case 2:
+ name = "Bukhoro";
+ break;
+ case 3:
+ name = "Farghona";
+ break;
+ case 4:
+ name = "Jizzakh";
+ break;
+ case 5:
+ name = "Khorazm";
+ break;
+ case 6:
+ name = "Namangan";
+ break;
+ case 7:
+ name = "Nawoiy";
+ break;
+ case 8:
+ name = "Qashqadaryo";
+ break;
+ case 9:
+ name = "Qoraqalpoghiston";
+ break;
+ case 10:
+ name = "Samarqand";
+ break;
+ case 11:
+ name = "Sirdaryo";
+ break;
+ case 12:
+ name = "Surkhondaryo";
+ break;
+ case 13:
+ name = "Toshkent";
+ break;
+ case 14:
+ name = "Toshkent";
+ break;
+ }
+ }
+ if (strcmp(country_code,"VC") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Charlotte";
+ break;
+ case 2:
+ name = "Saint Andrew";
+ break;
+ case 3:
+ name = "Saint David";
+ break;
+ case 4:
+ name = "Saint George";
+ break;
+ case 5:
+ name = "Saint Patrick";
+ break;
+ case 6:
+ name = "Grenadines";
+ break;
+ }
+ }
+ if (strcmp(country_code,"VE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Amazonas";
+ break;
+ case 2:
+ name = "Anzoategui";
+ break;
+ case 3:
+ name = "Apure";
+ break;
+ case 4:
+ name = "Aragua";
+ break;
+ case 5:
+ name = "Barinas";
+ break;
+ case 6:
+ name = "Bolivar";
+ break;
+ case 7:
+ name = "Carabobo";
+ break;
+ case 8:
+ name = "Cojedes";
+ break;
+ case 9:
+ name = "Delta Amacuro";
+ break;
+ case 11:
+ name = "Falcon";
+ break;
+ case 12:
+ name = "Guarico";
+ break;
+ case 13:
+ name = "Lara";
+ break;
+ case 14:
+ name = "Merida";
+ break;
+ case 15:
+ name = "Miranda";
+ break;
+ case 16:
+ name = "Monagas";
+ break;
+ case 17:
+ name = "Nueva Esparta";
+ break;
+ case 18:
+ name = "Portuguesa";
+ break;
+ case 19:
+ name = "Sucre";
+ break;
+ case 20:
+ name = "Tachira";
+ break;
+ case 21:
+ name = "Trujillo";
+ break;
+ case 22:
+ name = "Yaracuy";
+ break;
+ case 23:
+ name = "Zulia";
+ break;
+ case 24:
+ name = "Dependencias Federales";
+ break;
+ case 25:
+ name = "Distrito Federal";
+ break;
+ case 26:
+ name = "Vargas";
+ break;
+ }
+ }
+ if (strcmp(country_code,"VN") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Bac Thai";
+ break;
+ case 3:
+ name = "Ben Tre";
+ break;
+ case 5:
+ name = "Cao Bang";
+ break;
+ case 11:
+ name = "Ha Bac";
+ break;
+ case 12:
+ name = "Hai Hung";
+ break;
+ case 13:
+ name = "Hai Phong";
+ break;
+ case 22:
+ name = "Lai Chau";
+ break;
+ case 23:
+ name = "Lam Dong";
+ break;
+ case 24:
+ name = "Long An";
+ break;
+ case 29:
+ name = "Quang Nam-Da Nang";
+ break;
+ case 30:
+ name = "Quang Ninh";
+ break;
+ case 32:
+ name = "Son La";
+ break;
+ case 33:
+ name = "Tay Ninh";
+ break;
+ case 34:
+ name = "Thanh Hoa";
+ break;
+ case 35:
+ name = "Thai Binh";
+ break;
+ case 37:
+ name = "Tien Giang";
+ break;
+ case 39:
+ name = "Lang Son";
+ break;
+ case 43:
+ name = "An Giang";
+ break;
+ case 44:
+ name = "Dac Lac";
+ break;
+ case 45:
+ name = "Dong Nai";
+ break;
+ case 46:
+ name = "Dong Thap";
+ break;
+ case 47:
+ name = "Kien Giang";
+ break;
+ case 48:
+ name = "Minh Hai";
+ break;
+ case 49:
+ name = "Song Be";
+ break;
+ case 50:
+ name = "Vinh Phu";
+ break;
+ case 51:
+ name = "Ha Noi";
+ break;
+ case 52:
+ name = "Ho Chi Minh";
+ break;
+ case 53:
+ name = "Ba Ria-Vung Tau";
+ break;
+ case 54:
+ name = "Binh Dinh";
+ break;
+ case 55:
+ name = "Binh Thuan";
+ break;
+ case 56:
+ name = "Can Tho";
+ break;
+ case 57:
+ name = "Gia Lai";
+ break;
+ case 58:
+ name = "Ha Giang";
+ break;
+ case 59:
+ name = "Ha Tay";
+ break;
+ case 60:
+ name = "Ha Tinh";
+ break;
+ case 61:
+ name = "Hoa Binh";
+ break;
+ case 62:
+ name = "Khanh Hoa";
+ break;
+ case 63:
+ name = "Kon Tum";
+ break;
+ case 64:
+ name = "Lao Cai";
+ break;
+ case 65:
+ name = "Nam Ha";
+ break;
+ case 66:
+ name = "Nghe An";
+ break;
+ case 67:
+ name = "Ninh Binh";
+ break;
+ case 68:
+ name = "Ninh Thuan";
+ break;
+ case 69:
+ name = "Phu Yen";
+ break;
+ case 70:
+ name = "Quang Binh";
+ break;
+ case 71:
+ name = "Quang Ngai";
+ break;
+ case 72:
+ name = "Quang Tri";
+ break;
+ case 73:
+ name = "Soc Trang";
+ break;
+ case 74:
+ name = "Thua Thien";
+ break;
+ case 75:
+ name = "Tra Vinh";
+ break;
+ case 76:
+ name = "Tuyen Quang";
+ break;
+ case 77:
+ name = "Vinh Long";
+ break;
+ case 78:
+ name = "Yen Bai";
+ break;
+ }
+ }
+ if (strcmp(country_code,"VU") == 0) {
+ switch (region_code2) {
+ case 5:
+ name = "Ambrym";
+ break;
+ case 6:
+ name = "Aoba";
+ break;
+ case 7:
+ name = "Torba";
+ break;
+ case 8:
+ name = "Efate";
+ break;
+ case 9:
+ name = "Epi";
+ break;
+ case 10:
+ name = "Malakula";
+ break;
+ case 11:
+ name = "Paama";
+ break;
+ case 12:
+ name = "Pentecote";
+ break;
+ case 13:
+ name = "Sanma";
+ break;
+ case 14:
+ name = "Shepherd";
+ break;
+ case 15:
+ name = "Tafea";
+ break;
+ case 16:
+ name = "Malampa";
+ break;
+ case 17:
+ name = "Penama";
+ break;
+ case 18:
+ name = "Shefa";
+ break;
+ }
+ }
+ if (strcmp(country_code,"WS") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "Aiga-i-le-Tai";
+ break;
+ case 3:
+ name = "Atua";
+ break;
+ case 4:
+ name = "Fa";
+ break;
+ case 5:
+ name = "Gaga";
+ break;
+ case 6:
+ name = "Va";
+ break;
+ case 7:
+ name = "Gagaifomauga";
+ break;
+ case 8:
+ name = "Palauli";
+ break;
+ case 9:
+ name = "Satupa";
+ break;
+ case 10:
+ name = "Tuamasaga";
+ break;
+ case 11:
+ name = "Vaisigano";
+ break;
+ }
+ }
+ if (strcmp(country_code,"YE") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Abyan";
+ break;
+ case 3:
+ name = "Al Mahrah";
+ break;
+ case 4:
+ name = "Hadramawt";
+ break;
+ case 5:
+ name = "Shabwah";
+ break;
+ case 8:
+ name = "Al Hudaydah";
+ break;
+ case 10:
+ name = "Al Mahwit";
+ break;
+ case 11:
+ name = "Dhamar";
+ break;
+ case 14:
+ name = "Ma'rib";
+ break;
+ case 15:
+ name = "Sa";
+ break;
+ case 16:
+ name = "San";
+ break;
+ case 20:
+ name = "Al Bayda'";
+ break;
+ case 21:
+ name = "Al Jawf";
+ break;
+ case 22:
+ name = "Hajjah";
+ break;
+ case 23:
+ name = "Ibb";
+ break;
+ case 24:
+ name = "Lahij";
+ break;
+ case 25:
+ name = "Ta";
+ break;
+ }
+ }
+ if (strcmp(country_code,"ZA") == 0) {
+ switch (region_code2) {
+ case 2:
+ name = "KwaZulu-Natal";
+ break;
+ case 3:
+ name = "Free State";
+ break;
+ case 5:
+ name = "Eastern Cape";
+ break;
+ case 6:
+ name = "Gauteng";
+ break;
+ case 7:
+ name = "Mpumalanga";
+ break;
+ case 8:
+ name = "Northern Cape";
+ break;
+ case 9:
+ name = "Limpopo";
+ break;
+ case 10:
+ name = "North-West";
+ break;
+ case 11:
+ name = "Western Cape";
+ break;
+ }
+ }
+ if (strcmp(country_code,"ZM") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Western";
+ break;
+ case 2:
+ name = "Central";
+ break;
+ case 3:
+ name = "Eastern";
+ break;
+ case 4:
+ name = "Luapula";
+ break;
+ case 5:
+ name = "Northern";
+ break;
+ case 6:
+ name = "North-Western";
+ break;
+ case 7:
+ name = "Southern";
+ break;
+ case 8:
+ name = "Copperbelt";
+ break;
+ case 9:
+ name = "Lusaka";
+ break;
+ }
+ }
+ if (strcmp(country_code,"ZR") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Bandundu";
+ break;
+ case 2:
+ name = "Equateur";
+ break;
+ case 3:
+ name = "Kasai-Occidental";
+ break;
+ case 4:
+ name = "Kasai-Oriental";
+ break;
+ case 5:
+ name = "Katanga";
+ break;
+ case 6:
+ name = "Kinshasa";
+ break;
+ case 7:
+ name = "Kivu";
+ break;
+ case 8:
+ name = "Bas-Congo";
+ break;
+ case 9:
+ name = "Orientale";
+ break;
+ case 10:
+ name = "Maniema";
+ break;
+ case 11:
+ name = "Nord-Kivu";
+ break;
+ case 12:
+ name = "Sud-Kivu";
+ break;
+ }
+ }
+ if (strcmp(country_code,"ZW") == 0) {
+ switch (region_code2) {
+ case 1:
+ name = "Manicaland";
+ break;
+ case 2:
+ name = "Midlands";
+ break;
+ case 3:
+ name = "Mashonaland Central";
+ break;
+ case 4:
+ name = "Mashonaland East";
+ break;
+ case 5:
+ name = "Mashonaland West";
+ break;
+ case 6:
+ name = "Matabeleland North";
+ break;
+ case 7:
+ name = "Matabeleland South";
+ break;
+ case 8:
+ name = "Masvingo";
+ break;
+ case 9:
+ name = "Bulawayo";
+ break;
+ case 10:
+ name = "Harare";
+ break;
+ }
+ }
+ return name;
+}
diff --git a/src/GeoIP-1.4.0/libGeoIP/timeZone.c b/src/GeoIP-1.4.0/libGeoIP/timeZone.c
new file mode 100644
index 0000000..6e514fa
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/timeZone.c
@@ -0,0 +1,551 @@
+#include <string.h>
+#include "GeoIP.h"
+const char* GeoIP_time_zone_by_country_and_region(const char * country,const char * region) {
+ const char* timezone = NULL;
+ if (country == NULL) {
+ return NULL;
+ }
+ if (region == NULL) {
+ region = "";
+ }
+ if (strcmp(country,"US") == 0) {
+ if (strcmp(region,"AL") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"AK") == 0) {
+ timezone = "America/Anchorage";
+ } else if (strcmp(region,"AZ") == 0) {
+ timezone = "America/Phoenix";
+ } else if (strcmp(region,"AR") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"CA") == 0) {
+ timezone = "America/Los_Angeles";
+ } else if (strcmp(region,"CO") == 0) {
+ timezone = "America/Denver";
+ } else if (strcmp(region,"CT") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"DE") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"DC") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"FL") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"GA") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"HI") == 0) {
+ timezone = "Pacific/Honolulu";
+ } else if (strcmp(region,"ID") == 0) {
+ timezone = "America/Denver";
+ } else if (strcmp(region,"IL") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"IN") == 0) {
+ timezone = "America/Indianapolis";
+ } else if (strcmp(region,"IA") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"KS") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"KY") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"LA") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"ME") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"MD") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"MA") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"MI") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"MN") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"MS") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"MO") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"MT") == 0) {
+ timezone = "America/Denver";
+ } else if (strcmp(region,"NE") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"NV") == 0) {
+ timezone = "America/Los_Angeles";
+ } else if (strcmp(region,"NH") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"NJ") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"NM") == 0) {
+ timezone = "America/Denver";
+ } else if (strcmp(region,"NY") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"NC") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"ND") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"OH") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"OK") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"OR") == 0) {
+ timezone = "America/Los_Angeles";
+ } else if (strcmp(region,"PA") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"RI") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"SC") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"SD") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"TN") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"TX") == 0) {
+ timezone = "America/Chicago";
+ } else if (strcmp(region,"UT") == 0) {
+ timezone = "America/Denver";
+ } else if (strcmp(region,"VT") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"VA") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"WA") == 0) {
+ timezone = "America/Los_Angeles";
+ } else if (strcmp(region,"WV") == 0) {
+ timezone = "America/New_York";
+ } else if (strcmp(region,"WI") == 0) {
+ timezone = "America/Chicago";
+ } else {
+ timezone = "America/Chicago";
+ }
+ } else if (strcmp(country,"CA") == 0) {
+ if (strcmp(region,"AB") == 0) {
+ timezone = "America/Edmonton";
+ } else if (strcmp(region,"BC") == 0) {
+ timezone = "America/Vancouver";
+ } else if (strcmp(region,"MB") == 0) {
+ timezone = "America/Winnipeg";
+ } else if (strcmp(region,"NB") == 0) {
+ timezone = "America/Halifax";
+ } else if (strcmp(region,"NF") == 0) {
+ timezone = "America/St_Johns";
+ } else if (strcmp(region,"NT") == 0) {
+ timezone = "America/Yellowknife";
+ } else if (strcmp(region,"NS") == 0) {
+ timezone = "America/Halifax";
+ } else if (strcmp(region,"NU") == 0) {
+ timezone = "America/Rankin_Inlet";
+ } else if (strcmp(region,"ON") == 0) {
+ timezone = "America/Rainy_River";
+ } else if (strcmp(region,"PE") == 0) {
+ timezone = "America/Halifax";
+ } else if (strcmp(region,"QC") == 0) {
+ timezone = "America/Montreal";
+ } else if (strcmp(region,"SK") == 0) {
+ timezone = "America/Regina";
+ } else {
+ timezone = "America/Rainy_River";
+ }
+ } else if (strcmp(country,"AS") == 0) {
+ timezone = "US/Samoa";
+ } else if (strcmp(country,"CI") == 0) {
+ timezone = "Africa/Abidjan";
+ } else if (strcmp(country,"GH") == 0) {
+ timezone = "Africa/Accra";
+ } else if (strcmp(country,"DZ") == 0) {
+ timezone = "Africa/Algiers";
+ } else if (strcmp(country,"ER") == 0) {
+ timezone = "Africa/Asmera";
+ } else if (strcmp(country,"ML") == 0) {
+ timezone = "Africa/Bamako";
+ } else if (strcmp(country,"CF") == 0) {
+ timezone = "Africa/Bangui";
+ } else if (strcmp(country,"GM") == 0) {
+ timezone = "Africa/Banjul";
+ } else if (strcmp(country,"GW") == 0) {
+ timezone = "Africa/Bissau";
+ } else if (strcmp(country,"CG") == 0) {
+ timezone = "Africa/Brazzaville";
+ } else if (strcmp(country,"BI") == 0) {
+ timezone = "Africa/Bujumbura";
+ } else if (strcmp(country,"EG") == 0) {
+ timezone = "Africa/Cairo";
+ } else if (strcmp(country,"MA") == 0) {
+ timezone = "Africa/Casablanca";
+ } else if (strcmp(country,"GN") == 0) {
+ timezone = "Africa/Conakry";
+ } else if (strcmp(country,"SN") == 0) {
+ timezone = "Africa/Dakar";
+ } else if (strcmp(country,"DJ") == 0) {
+ timezone = "Africa/Djibouti";
+ } else if (strcmp(country,"SL") == 0) {
+ timezone = "Africa/Freetown";
+ } else if (strcmp(country,"BW") == 0) {
+ timezone = "Africa/Gaborone";
+ } else if (strcmp(country,"ZW") == 0) {
+ timezone = "Africa/Harare";
+ } else if (strcmp(country,"ZA") == 0) {
+ timezone = "Africa/Johannesburg";
+ } else if (strcmp(country,"UG") == 0) {
+ timezone = "Africa/Kampala";
+ } else if (strcmp(country,"SD") == 0) {
+ timezone = "Africa/Khartoum";
+ } else if (strcmp(country,"RW") == 0) {
+ timezone = "Africa/Kigali";
+ } else if (strcmp(country,"NG") == 0) {
+ timezone = "Africa/Lagos";
+ } else if (strcmp(country,"GA") == 0) {
+ timezone = "Africa/Libreville";
+ } else if (strcmp(country,"TG") == 0) {
+ timezone = "Africa/Lome";
+ } else if (strcmp(country,"AO") == 0) {
+ timezone = "Africa/Luanda";
+ } else if (strcmp(country,"ZM") == 0) {
+ timezone = "Africa/Lusaka";
+ } else if (strcmp(country,"GQ") == 0) {
+ timezone = "Africa/Malabo";
+ } else if (strcmp(country,"MZ") == 0) {
+ timezone = "Africa/Maputo";
+ } else if (strcmp(country,"LS") == 0) {
+ timezone = "Africa/Maseru";
+ } else if (strcmp(country,"SZ") == 0) {
+ timezone = "Africa/Mbabane";
+ } else if (strcmp(country,"SO") == 0) {
+ timezone = "Africa/Mogadishu";
+ } else if (strcmp(country,"LR") == 0) {
+ timezone = "Africa/Monrovia";
+ } else if (strcmp(country,"KE") == 0) {
+ timezone = "Africa/Nairobi";
+ } else if (strcmp(country,"TD") == 0) {
+ timezone = "Africa/Ndjamena";
+ } else if (strcmp(country,"NE") == 0) {
+ timezone = "Africa/Niamey";
+ } else if (strcmp(country,"MR") == 0) {
+ timezone = "Africa/Nouakchott";
+ } else if (strcmp(country,"BF") == 0) {
+ timezone = "Africa/Ouagadougou";
+ } else if (strcmp(country,"ST") == 0) {
+ timezone = "Africa/Sao_Tome";
+ } else if (strcmp(country,"LY") == 0) {
+ timezone = "Africa/Tripoli";
+ } else if (strcmp(country,"TN") == 0) {
+ timezone = "Africa/Tunis";
+ } else if (strcmp(country,"AI") == 0) {
+ timezone = "America/Anguilla";
+ } else if (strcmp(country,"AG") == 0) {
+ timezone = "America/Antigua";
+ } else if (strcmp(country,"AW") == 0) {
+ timezone = "America/Aruba";
+ } else if (strcmp(country,"BB") == 0) {
+ timezone = "America/Barbados";
+ } else if (strcmp(country,"BZ") == 0) {
+ timezone = "America/Belize";
+ } else if (strcmp(country,"CO") == 0) {
+ timezone = "America/Bogota";
+ } else if (strcmp(country,"VE") == 0) {
+ timezone = "America/Caracas";
+ } else if (strcmp(country,"KY") == 0) {
+ timezone = "America/Cayman";
+ } else if (strcmp(country,"MX") == 0) {
+ timezone = "America/Chihuahua";
+ } else if (strcmp(country,"CR") == 0) {
+ timezone = "America/Costa_Rica";
+ } else if (strcmp(country,"DM") == 0) {
+ timezone = "America/Dominica";
+ } else if (strcmp(country,"SV") == 0) {
+ timezone = "America/El_Salvador";
+ } else if (strcmp(country,"GD") == 0) {
+ timezone = "America/Grenada";
+ } else if (strcmp(country,"FR") == 0) {
+ timezone = "Europe/Paris";
+ } else if (strcmp(country,"GP") == 0) {
+ timezone = "America/Guadeloupe";
+ } else if (strcmp(country,"GT") == 0) {
+ timezone = "America/Guatemala";
+ } else if (strcmp(country,"EC") == 0) {
+ timezone = "America/Guayaquil";
+ } else if (strcmp(country,"GY") == 0) {
+ timezone = "America/Guyana";
+ } else if (strcmp(country,"CU") == 0) {
+ timezone = "America/Havana";
+ } else if (strcmp(country,"JM") == 0) {
+ timezone = "America/Jamaica";
+ } else if (strcmp(country,"BO") == 0) {
+ timezone = "America/La_Paz";
+ } else if (strcmp(country,"PE") == 0) {
+ timezone = "America/Lima";
+ } else if (strcmp(country,"NI") == 0) {
+ timezone = "America/Managua";
+ } else if (strcmp(country,"MQ") == 0) {
+ timezone = "America/Martinique";
+ } else if (strcmp(country,"AR") == 0) {
+ timezone = "America/Mendoza";
+ } else if (strcmp(country,"UY") == 0) {
+ timezone = "America/Montevideo";
+ } else if (strcmp(country,"MS") == 0) {
+ timezone = "America/Montserrat";
+ } else if (strcmp(country,"BS") == 0) {
+ timezone = "America/Nassau";
+ } else if (strcmp(country,"PA") == 0) {
+ timezone = "America/Panama";
+ } else if (strcmp(country,"SR") == 0) {
+ timezone = "America/Paramaribo";
+ } else if (strcmp(country,"PR") == 0) {
+ timezone = "America/Puerto_Rico";
+ } else if (strcmp(country,"KN") == 0) {
+ timezone = "America/St_Kitts";
+ } else if (strcmp(country,"LC") == 0) {
+ timezone = "America/St_Lucia";
+ } else if (strcmp(country,"VC") == 0) {
+ timezone = "America/St_Vincent";
+ } else if (strcmp(country,"HN") == 0) {
+ timezone = "America/Tegucigalpa";
+ } else if (strcmp(country,"YE") == 0) {
+ timezone = "Asia/Aden";
+ } else if (strcmp(country,"KZ") == 0) {
+ timezone = "Asia/Almaty";
+ } else if (strcmp(country,"JO") == 0) {
+ timezone = "Asia/Amman";
+ } else if (strcmp(country,"TM") == 0) {
+ timezone = "Asia/Ashgabat";
+ } else if (strcmp(country,"IQ") == 0) {
+ timezone = "Asia/Baghdad";
+ } else if (strcmp(country,"BH") == 0) {
+ timezone = "Asia/Bahrain";
+ } else if (strcmp(country,"AZ") == 0) {
+ timezone = "Asia/Baku";
+ } else if (strcmp(country,"TH") == 0) {
+ timezone = "Asia/Bangkok";
+ } else if (strcmp(country,"LB") == 0) {
+ timezone = "Asia/Beirut";
+ } else if (strcmp(country,"KG") == 0) {
+ timezone = "Asia/Bishkek";
+ } else if (strcmp(country,"BN") == 0) {
+ timezone = "Asia/Brunei";
+ } else if (strcmp(country,"IN") == 0) {
+ timezone = "Asia/Calcutta";
+ } else if (strcmp(country,"MN") == 0) {
+ timezone = "Asia/Choibalsan";
+ } else if (strcmp(country,"CN") == 0) {
+ timezone = "Asia/Chongqing";
+ } else if (strcmp(country,"LK") == 0) {
+ timezone = "Asia/Colombo";
+ } else if (strcmp(country,"BD") == 0) {
+ timezone = "Asia/Dhaka";
+ } else if (strcmp(country,"AE") == 0) {
+ timezone = "Asia/Dubai";
+ } else if (strcmp(country,"TJ") == 0) {
+ timezone = "Asia/Dushanbe";
+ } else if (strcmp(country,"HK") == 0) {
+ timezone = "Asia/Hong_Kong";
+ } else if (strcmp(country,"TR") == 0) {
+ timezone = "Asia/Istanbul";
+ } else if (strcmp(country,"ID") == 0) {
+ timezone = "Asia/Jakarta";
+ } else if (strcmp(country,"IL") == 0) {
+ timezone = "Asia/Jerusalem";
+ } else if (strcmp(country,"AF") == 0) {
+ timezone = "Asia/Kabul";
+ } else if (strcmp(country,"PK") == 0) {
+ timezone = "Asia/Karachi";
+ } else if (strcmp(country,"NP") == 0) {
+ timezone = "Asia/Katmandu";
+ } else if (strcmp(country,"KW") == 0) {
+ timezone = "Asia/Kuwait";
+ } else if (strcmp(country,"MO") == 0) {
+ timezone = "Asia/Macao";
+ } else if (strcmp(country,"PH") == 0) {
+ timezone = "Asia/Manila";
+ } else if (strcmp(country,"OM") == 0) {
+ timezone = "Asia/Muscat";
+ } else if (strcmp(country,"CY") == 0) {
+ timezone = "Asia/Nicosia";
+ } else if (strcmp(country,"KP") == 0) {
+ timezone = "Asia/Pyongyang";
+ } else if (strcmp(country,"QA") == 0) {
+ timezone = "Asia/Qatar";
+ } else if (strcmp(country,"MM") == 0) {
+ timezone = "Asia/Rangoon";
+ } else if (strcmp(country,"SA") == 0) {
+ timezone = "Asia/Riyadh";
+ } else if (strcmp(country,"KR") == 0) {
+ timezone = "Asia/Seoul";
+ } else if (strcmp(country,"SG") == 0) {
+ timezone = "Asia/Singapore";
+ } else if (strcmp(country,"TW") == 0) {
+ timezone = "Asia/Taipei";
+ } else if (strcmp(country,"UZ") == 0) {
+ timezone = "Asia/Tashkent";
+ } else if (strcmp(country,"GE") == 0) {
+ timezone = "Asia/Tbilisi";
+ } else if (strcmp(country,"BT") == 0) {
+ timezone = "Asia/Thimphu";
+ } else if (strcmp(country,"JP") == 0) {
+ timezone = "Asia/Tokyo";
+ } else if (strcmp(country,"LA") == 0) {
+ timezone = "Asia/Vientiane";
+ } else if (strcmp(country,"AM") == 0) {
+ timezone = "Asia/Yerevan";
+ } else if (strcmp(country,"PT") == 0) {
+ timezone = "Atlantic/Azores";
+ } else if (strcmp(country,"BM") == 0) {
+ timezone = "Atlantic/Bermuda";
+ } else if (strcmp(country,"CV") == 0) {
+ timezone = "Atlantic/Cape_Verde";
+ } else if (strcmp(country,"FO") == 0) {
+ timezone = "Atlantic/Faeroe";
+ } else if (strcmp(country,"IS") == 0) {
+ timezone = "Atlantic/Reykjavik";
+ } else if (strcmp(country,"GS") == 0) {
+ timezone = "Atlantic/South_Georgia";
+ } else if (strcmp(country,"SH") == 0) {
+ timezone = "Atlantic/St_Helena";
+ } else if (strcmp(country,"AU") == 0) {
+ timezone = "Australia/Queensland";
+ } else if (strcmp(country,"BR") == 0) {
+ timezone = "Brazil/Acre";
+ } else if (strcmp(country,"CL") == 0) {
+ timezone = "Chile/Continental";
+ } else if (strcmp(country,"NL") == 0) {
+ timezone = "Europe/Amsterdam";
+ } else if (strcmp(country,"AD") == 0) {
+ timezone = "Europe/Andorra";
+ } else if (strcmp(country,"GR") == 0) {
+ timezone = "Europe/Athens";
+ } else if (strcmp(country,"YU") == 0) {
+ timezone = "Europe/Belgrade";
+ } else if (strcmp(country,"DE") == 0) {
+ timezone = "Europe/Berlin";
+ } else if (strcmp(country,"SK") == 0) {
+ timezone = "Europe/Bratislava";
+ } else if (strcmp(country,"BE") == 0) {
+ timezone = "Europe/Brussels";
+ } else if (strcmp(country,"RO") == 0) {
+ timezone = "Europe/Bucharest";
+ } else if (strcmp(country,"HU") == 0) {
+ timezone = "Europe/Budapest";
+ } else if (strcmp(country,"DK") == 0) {
+ timezone = "Europe/Copenhagen";
+ } else if (strcmp(country,"IE") == 0) {
+ timezone = "Europe/Dublin";
+ } else if (strcmp(country,"GI") == 0) {
+ timezone = "Europe/Gibraltar";
+ } else if (strcmp(country,"FI") == 0) {
+ timezone = "Europe/Helsinki";
+ } else if (strcmp(country,"UA") == 0) {
+ timezone = "Europe/Kiev";
+ } else if (strcmp(country,"SI") == 0) {
+ timezone = "Europe/Ljubljana";
+ } else if (strcmp(country,"GB") == 0) {
+ timezone = "Europe/London";
+ } else if (strcmp(country,"LU") == 0) {
+ timezone = "Europe/Luxembourg";
+ } else if (strcmp(country,"ES") == 0) {
+ timezone = "Europe/Madrid";
+ } else if (strcmp(country,"MT") == 0) {
+ timezone = "Europe/Malta";
+ } else if (strcmp(country,"BY") == 0) {
+ timezone = "Europe/Minsk";
+ } else if (strcmp(country,"MC") == 0) {
+ timezone = "Europe/Monaco";
+ } else if (strcmp(country,"RU") == 0) {
+ timezone = "Europe/Moscow";
+ } else if (strcmp(country,"NO") == 0) {
+ timezone = "Europe/Oslo";
+ } else if (strcmp(country,"CZ") == 0) {
+ timezone = "Europe/Prague";
+ } else if (strcmp(country,"LV") == 0) {
+ timezone = "Europe/Riga";
+ } else if (strcmp(country,"IT") == 0) {
+ timezone = "Europe/Rome";
+ } else if (strcmp(country,"SM") == 0) {
+ timezone = "Europe/San_Marino";
+ } else if (strcmp(country,"BA") == 0) {
+ timezone = "Europe/Sarajevo";
+ } else if (strcmp(country,"MK") == 0) {
+ timezone = "Europe/Skopje";
+ } else if (strcmp(country,"BG") == 0) {
+ timezone = "Europe/Sofia";
+ } else if (strcmp(country,"SE") == 0) {
+ timezone = "Europe/Stockholm";
+ } else if (strcmp(country,"EE") == 0) {
+ timezone = "Europe/Tallinn";
+ } else if (strcmp(country,"AL") == 0) {
+ timezone = "Europe/Tirane";
+ } else if (strcmp(country,"LI") == 0) {
+ timezone = "Europe/Vaduz";
+ } else if (strcmp(country,"VA") == 0) {
+ timezone = "Europe/Vatican";
+ } else if (strcmp(country,"AT") == 0) {
+ timezone = "Europe/Vienna";
+ } else if (strcmp(country,"LT") == 0) {
+ timezone = "Europe/Vilnius";
+ } else if (strcmp(country,"PL") == 0) {
+ timezone = "Europe/Warsaw";
+ } else if (strcmp(country,"HR") == 0) {
+ timezone = "Europe/Zagreb";
+ } else if (strcmp(country,"IR") == 0) {
+ timezone = "Asia/Tehran";
+ } else if (strcmp(country,"NZ") == 0) {
+ timezone = "Pacific/Auckland";
+ } else if (strcmp(country,"MG") == 0) {
+ timezone = "Indian/Antananarivo";
+ } else if (strcmp(country,"CX") == 0) {
+ timezone = "Indian/Christmas";
+ } else if (strcmp(country,"CC") == 0) {
+ timezone = "Indian/Cocos";
+ } else if (strcmp(country,"KM") == 0) {
+ timezone = "Indian/Comoro";
+ } else if (strcmp(country,"MV") == 0) {
+ timezone = "Indian/Maldives";
+ } else if (strcmp(country,"MU") == 0) {
+ timezone = "Indian/Mauritius";
+ } else if (strcmp(country,"YT") == 0) {
+ timezone = "Indian/Mayotte";
+ } else if (strcmp(country,"RE") == 0) {
+ timezone = "Indian/Reunion";
+ } else if (strcmp(country,"FJ") == 0) {
+ timezone = "Pacific/Fiji";
+ } else if (strcmp(country,"TV") == 0) {
+ timezone = "Pacific/Funafuti";
+ } else if (strcmp(country,"GU") == 0) {
+ timezone = "Pacific/Guam";
+ } else if (strcmp(country,"NR") == 0) {
+ timezone = "Pacific/Nauru";
+ } else if (strcmp(country,"NU") == 0) {
+ timezone = "Pacific/Niue";
+ } else if (strcmp(country,"NF") == 0) {
+ timezone = "Pacific/Norfolk";
+ } else if (strcmp(country,"PW") == 0) {
+ timezone = "Pacific/Palau";
+ } else if (strcmp(country,"PN") == 0) {
+ timezone = "Pacific/Pitcairn";
+ } else if (strcmp(country,"CK") == 0) {
+ timezone = "Pacific/Rarotonga";
+ } else if (strcmp(country,"WS") == 0) {
+ timezone = "Pacific/Samoa";
+ } else if (strcmp(country,"KI") == 0) {
+ timezone = "Pacific/Tarawa";
+ } else if (strcmp(country,"TO") == 0) {
+ timezone = "Pacific/Tongatapu";
+ } else if (strcmp(country,"WF") == 0) {
+ timezone = "Pacific/Wallis";
+ } else if (strcmp(country,"TZ") == 0) {
+ timezone = "Africa/Dar_es_Salaam";
+ } else if (strcmp(country,"VN") == 0) {
+ timezone = "Asia/Phnom_Penh";
+ } else if (strcmp(country,"KH") == 0) {
+ timezone = "Asia/Phnom_Penh";
+ } else if (strcmp(country,"CM") == 0) {
+ timezone = "Africa/Lagos";
+ } else if (strcmp(country,"DO") == 0) {
+ timezone = "America/Santo_Domingo";
+ } else if (strcmp(country,"TL") == 0) {
+ timezone = "Asia/Jakarta";
+ } else if (strcmp(country,"ET") == 0) {
+ timezone = "Africa/Addis_Ababa";
+ } else if (strcmp(country,"FX") == 0) {
+ timezone = "Europe/Paris";
+ } else if (strcmp(country,"GL") == 0) {
+ timezone = "America/Godthab";
+ } else if (strcmp(country,"HT") == 0) {
+ timezone = "America/Port-au-Prince";
+ } else if (strcmp(country,"CH") == 0) {
+ timezone = "Europe/Zurich";
+ }
+ return timezone;
+}
diff --git a/src/GeoIP-1.4.0/libGeoIP/types.h b/src/GeoIP-1.4.0/libGeoIP/types.h
new file mode 100644
index 0000000..4a8b80a
--- /dev/null
+++ b/src/GeoIP-1.4.0/libGeoIP/types.h
@@ -0,0 +1,140 @@
+/* types.h - some common typedefs
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef G10_TYPES_H
+#define G10_TYPES_H
+
+#ifdef HAVE_INTTYPES_H
+/* For uint64_t */
+#include <inttypes.h>
+#endif
+
+/* The AC_CHECK_SIZEOF() in configure fails for some machines.
+ * we provide some fallback values here */
+#if !SIZEOF_UNSIGNED_SHORT
+#undef SIZEOF_UNSIGNED_SHORT
+#define SIZEOF_UNSIGNED_SHORT 2
+#endif
+#if !SIZEOF_UNSIGNED_INT
+#undef SIZEOF_UNSIGNED_INT
+#define SIZEOF_UNSIGNED_INT 4
+#endif
+#if !SIZEOF_UNSIGNED_LONG
+#undef SIZEOF_UNSIGNED_LONG
+#define SIZEOF_UNSIGNED_LONG 4
+#endif
+
+
+#include <sys/types.h>
+
+#ifndef HAVE_BYTE_TYPEDEF
+#undef byte /* maybe there is a macro with this name */
+#ifndef __riscos__
+typedef unsigned char byte;
+#else
+/* Norcroft treats char = unsigned char as legal assignment
+ but char* = unsigned char* as illegal assignment
+ and the same applies to the signed variants as well */
+typedef char byte;
+#endif
+#define HAVE_BYTE_TYPEDEF
+#endif
+
+#ifndef HAVE_USHORT_TYPEDEF
+#undef ushort /* maybe there is a macro with this name */
+typedef unsigned short ushort;
+#define HAVE_USHORT_TYPEDEF
+#endif
+
+#ifndef HAVE_ULONG_TYPEDEF
+#undef ulong /* maybe there is a macro with this name */
+typedef unsigned long ulong;
+#define HAVE_ULONG_TYPEDEF
+#endif
+
+#ifndef HAVE_U16_TYPEDEF
+#undef u16 /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 2
+typedef unsigned int u16;
+#elif SIZEOF_UNSIGNED_SHORT == 2
+typedef unsigned short u16;
+#else
+#error no typedef for u16
+#endif
+#define HAVE_U16_TYPEDEF
+#endif
+
+#ifndef HAVE_U32_TYPEDEF
+#undef u32 /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 4
+typedef unsigned int u32;
+#elif SIZEOF_UNSIGNED_LONG == 4
+typedef unsigned long u32;
+#else
+#error no typedef for u32
+#endif
+#define HAVE_U32_TYPEDEF
+#endif
+
+/****************
+ * Warning: Some systems segfault when this u64 typedef and
+ * the dummy code in cipher/md.c is not available. Examples are
+ * Solaris and IRIX.
+ */
+#ifndef HAVE_U64_TYPEDEF
+#undef u64 /* maybe there is a macro with this name */
+#if SIZEOF_UINT64_T == 8
+typedef uint64_t u64;
+#define U64_C(c) (UINT64_C(c))
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_INT == 8
+typedef unsigned int u64;
+#define U64_C(c) (c ## U)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_LONG == 8
+typedef unsigned long u64;
+#define U64_C(c) (c ## UL)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_LONG_LONG == 8
+typedef unsigned long long u64;
+#define U64_C(c) (c ## ULL)
+#define HAVE_U64_TYPEDEF
+#endif
+#endif
+
+typedef union {
+ int a;
+ short b;
+ char c[1];
+ long d;
+#ifdef HAVE_U64_TYPEDEF
+ u64 e;
+#endif
+ float f;
+ double g;
+} PROPERLY_ALIGNED_TYPE;
+
+typedef struct string_list {
+ struct string_list *next;
+ unsigned int flags;
+ char d[1];
+} *STRLIST;
+
+#endif /*G10_TYPES_H*/
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..8f0198a
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,96 @@
+## Makefile.am for tork
+
+# this is the program that gets installed. it's name is used for all
+# of the other Makefile.am variables
+bin_PROGRAMS = tork
+
+if EXTERNAL_GEOIP
+geoiplib=-lGeoIP
+geoipdir=
+else
+geoiplib=GeoIP-1.4.0/libGeoIP/libGeoIP.la
+geoipdir=GeoIP-1.4.0
+endif
+
+SUBDIRS=icons arkollon $(geoipdir) privoxytemplates \
+ menu upnp .
+# torkapplet konqplugin tor_ioslave - removed from build
+
+DISTCLEANFILES=dcoptork.kidl
+
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes)
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+# the library search path.
+tork_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+
+# the libraries to link against.
+tork_LDADD = $(LIB_KIO) $(LIB_KFILE) $(LIB_KHTML) $(geoiplib) \
+ upnp/libktupnp.la $(CRYPTO_LIBS)
+
+# which sources should be compiled for tork
+tork_SOURCES = chart.cpp configdialog.cpp crashhandler.cpp \
+ crypto.cpp dcoptork.kidl dcoptork.skel dndlistview.cpp firewallsproxies.ui \
+ functions.cpp hiddensrvs.ui hidsrvwizard.ui hitwidget.cpp hitwidget_layout.ui \
+ introwizard.ui kerrylabel.cpp konqueror.ui kwidgetlistbox.cpp likeback.cpp main.cpp \
+ maxmin.ui mixminion.ui newfirstrunwizard.ui newstreamosd.cpp overlayWidget.cpp \
+ paranoia.ui popupMessage.cpp quickconfig.ui running.ui server.ui serverwizard.ui \
+ statgraph.cpp testprivacyproxy.cpp torclient.cpp tork.cpp torkactivelabel.cpp \
+ torkconfig.kcfgc torkview.cpp torkview_base.ui torservers.ui trayhoverpopup.cpp \
+ trayicon.cpp update.cpp upnpmanager.cpp usability.ui
+
+xdg_apps_DATA = tork.desktop
+kde_kcfg_DATA = torkconfig.kcfg
+
+# these are the headers for your project
+noinst_HEADERS = crypto.h dcoptork.h likeback.h likeback_private.h \
+ update.h warnings.h
+
+
+messages: rc.cpp
+ $(EXTRACTRC) `find . -name \*.ui -o -name \*.rc` > rc.cpp
+ $(XGETTEXT) *.h *.cpp -o $(podir)/tork.pot
+
+KDE_ICON = AUTO
+
+kde_icon_KDEICON = \
+ cr16-app-tork.png \
+ cr22-app-tork.png \
+ cr32-app-tork.png \
+ cr48-app-tork.png \
+ cr64-app-tork.png \
+ cr128-app-tork.png \
+ hi16-app-tork_old.png \
+ hi32-app-tork_old.png \
+ crsc-app-tork.svg \
+ \
+ cr16-action-likeback_configure_tork.png \
+ cr16-action-likeback_dislike_tork.png \
+ cr16-action-likeback_feature_tork.png \
+ cr16-action-likeback_bug_tork.png \
+ cr16-action-likeback_like_tork.png
+
+
+
+# this is where the servicemenu file will go
+konqservice_DATA = tork_downloadwithfirefox.desktop tork_downloadwithopera.desktop \
+ tork_downloadwithkonqueror.desktop
+konqservicedir = $(kde_datadir)/konqueror/servicemenus
+
+# this is where the XML-GUI resource file goes
+rcdir = $(kde_datadir)/tork
+rc_DATA = torkui.rc
+
+eventsrcdir = $(kde_datadir)/tork
+eventsrc_DATA = eventsrc
+
+manpagedir = $(mandir)/man1
+manpage_DATA = tork.1
+
+pixmapdir = $(prefix)/share/pixmaps
+pixmap_DATA = tork.xpm
+
+main.o : usability.h torservers.h torkview_base.h maxmin.h running.h torkconfig.h firewallsproxies.h server.h quickconfig.h newfirstrunwizard.h hiddensrvs.h hidsrvwizard.h konqueror.h introwizard.h paranoia.h
diff --git a/src/arkollon/Makefile.am b/src/arkollon/Makefile.am
new file mode 100644
index 0000000..81cea55
--- /dev/null
+++ b/src/arkollon/Makefile.am
@@ -0,0 +1,40 @@
+bin_PROGRAMS = torkarkollon
+torkarkollon_SOURCES = torkarkollon.cpp \
+ wizard.cpp \
+ rcparser.cpp \
+ uninstallwizard.cpp \
+ headerlistitem.cpp \
+ data.cpp \
+ logdialog.ui \
+ wizardbase.ui
+
+
+noinst_HEADERS = data.h \
+ headerlistitem.h \
+ rcparser.h \
+ uninstallwizard.h \
+ wizard.h \
+ logdialog.h \
+ wizardbase.h
+
+
+
+# set the include path found by configure
+INCLUDES= $(all_includes)
+# the library search path.
+torkarkollon_LDFLAGS = $(all_libraries)
+LIBS =
+#torkarkollon_LDFLAGS =
+#torkarkollon_LDADD = $(LIB_QT) $(LIB_KFILE)
+torkarkollon_LDADD = $(LIB_KFILE) $(LIB_QT)
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+manpagedir = $(mandir)/man1
+manpage_DATA = torkarkollon.1
+
+torkarkollon.o : wizardbase.h logdialog.h
+wizard.o : wizardbase.h logdialog.h
+uninstallwizard.o : wizardbase.h logdialog.h
+
diff --git a/src/arkollon/data.cpp b/src/arkollon/data.cpp
new file mode 100644
index 0000000..89b57d6
--- /dev/null
+++ b/src/arkollon/data.cpp
@@ -0,0 +1,44 @@
+#include "data.h"
+
+static struct EmbedImage {
+ int width, height, depth;
+ const unsigned char *data;
+ int numColors;
+ const QRgb *colorTable;
+ bool alpha;
+ const char *name;
+} embed_image_vec[] = {
+ { 16, 16, 32, (const unsigned char*)misc_data, 0, 0, TRUE, "misc" },
+ { 130, 300, 32, (const unsigned char*)splash_data, 0, 0, FALSE, "splash" },
+ { 32, 32, 32, (const unsigned char*)packageIcon_data, 0, 0, TRUE, "packageIcon" },
+ { 0, 0, 0, 0, 0, 0, 0, 0 }
+};
+
+const QImage& qembed_findImage( const QString& name )
+{
+ static QDict<QImage> dict;
+ QImage* img = dict.find( name );
+ if ( !img ) {
+ for ( int i = 0; embed_image_vec[i].data; i++ ) {
+ if ( strcmp(embed_image_vec[i].name, name.latin1()) == 0 ) {
+ img = new QImage((uchar*)embed_image_vec[i].data,
+ embed_image_vec[i].width,
+ embed_image_vec[i].height,
+ embed_image_vec[i].depth,
+ (QRgb*)embed_image_vec[i].colorTable,
+ embed_image_vec[i].numColors,
+ QImage::BigEndian );
+ if ( embed_image_vec[i].alpha )
+ img->setAlphaBuffer( TRUE );
+ dict.insert( name, img );
+ break;
+ }
+ }
+ if ( !img ) {
+ static QImage dummy;
+ return dummy;
+ }
+ }
+ return *img;
+}
+
diff --git a/src/arkollon/data.h b/src/arkollon/data.h
new file mode 100644
index 0000000..df9aa43
--- /dev/null
+++ b/src/arkollon/data.h
@@ -0,0 +1,3065 @@
+#ifndef _QEMBED_1804289383
+#define _QEMBED_1804289383
+static const unsigned int postinstall_sh_len = 952;
+static const unsigned char postinstall_sh_data[] = {
+ 0x23,0x21,0x2f,0x62,0x69,0x6e,0x2f,0x62,0x61,0x73,0x68,0x0a,0x0a,0x0a,
+ 0x70,0x72,0x69,0x6e,0x74,0x48,0x65,0x6c,0x70,0x28,0x29,0x0a,0x7b,0x0a,
+ 0x09,0x65,0x63,0x68,0x6f,0x20,0x22,0x54,0x68,0x69,0x73,0x20,0x69,0x73,
+ 0x20,0x61,0x20,0x68,0x65,0x6c,0x70,0x65,0x72,0x20,0x73,0x63,0x72,0x69,
+ 0x70,0x74,0x20,0x66,0x6f,0x72,0x20,0x41,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,
+ 0x6e,0x22,0x0a,0x09,0x65,0x63,0x68,0x6f,0x20,0x22,0x55,0x73,0x61,0x67,
+ 0x65,0x3a,0x20,0x70,0x6f,0x73,0x74,0x69,0x6e,0x73,0x74,0x61,0x6c,0x6c,
+ 0x2e,0x73,0x68,0x22,0x0a,0x09,0x65,0x63,0x68,0x6f,0x20,0x22,0x20,0x20,
+ 0x20,0x2d,0x2d,0x61,0x70,0x70,0x6e,0x61,0x6d,0x65,0x20,0x41,0x50,0x50,
+ 0x4e,0x41,0x4d,0x45,0x22,0x0a,0x09,0x65,0x63,0x68,0x6f,0x20,0x22,0x20,
+ 0x20,0x20,0x2d,0x2d,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x56,0x45,
+ 0x52,0x53,0x49,0x4f,0x4e,0x22,0x0a,0x09,0x65,0x63,0x68,0x6f,0x20,0x22,
+ 0x20,0x20,0x20,0x2d,0x2d,0x66,0x69,0x6c,0x65,0x6c,0x69,0x73,0x74,0x20,
+ 0x46,0x49,0x4c,0x45,0x4c,0x49,0x53,0x54,0x22,0x0a,0x09,0x65,0x78,0x69,
+ 0x74,0x0a,0x7d,0x0a,0x0a,0x77,0x72,0x69,0x74,0x65,0x41,0x72,0x6b,0x6f,
+ 0x6c,0x6c,0x6f,0x6e,0x55,0x6e,0x69,0x6e,0x73,0x74,0x61,0x6c,0x6c,0x4c,
+ 0x69,0x73,0x74,0x28,0x29,0x0a,0x7b,0x0a,0x09,0x69,0x66,0x20,0x5b,0x20,
+ 0x22,0x24,0x77,0x68,0x6f,0x61,0x6d,0x69,0x22,0x20,0x3d,0x3d,0x20,0x22,
+ 0x72,0x6f,0x6f,0x74,0x22,0x20,0x5d,0x0a,0x09,0x74,0x68,0x65,0x6e,0x20,
+ 0x70,0x72,0x65,0x66,0x69,0x78,0x3d,0x22,0x2f,0x76,0x61,0x72,0x2f,0x61,
+ 0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x22,0x0a,0x09,0x65,0x6c,0x73,0x65,
+ 0x20,0x70,0x72,0x65,0x66,0x69,0x78,0x3d,0x22,0x24,0x48,0x4f,0x4d,0x45,
+ 0x2f,0x2e,0x61,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x22,0x0a,0x09,0x66,
+ 0x69,0x0a,0x09,0x0a,0x09,0x65,0x63,0x68,0x6f,0x20,0x22,0x57,0x72,0x69,
+ 0x74,0x69,0x6e,0x67,0x20,0x75,0x6e,0x69,0x6e,0x73,0x74,0x61,0x6c,0x6c,
+ 0x20,0x69,0x6e,0x66,0x6f,0x72,0x6d,0x61,0x74,0x69,0x6f,0x6e,0x20,0x66,
+ 0x6f,0x72,0x20,0x24,0x61,0x70,0x70,0x4e,0x61,0x6d,0x65,0x20,0x69,0x6e,
+ 0x74,0x6f,0x20,0x24,0x70,0x72,0x65,0x66,0x69,0x78,0x22,0x0a,0x09,0x0a,
+ 0x09,0x6d,0x6b,0x64,0x69,0x72,0x20,0x2d,0x70,0x20,0x24,0x70,0x72,0x65,
+ 0x66,0x69,0x78,0x0a,0x09,0x69,0x66,0x20,0x5b,0x20,0x2d,0x65,0x20,0x22,
+ 0x24,0x70,0x72,0x65,0x66,0x69,0x78,0x2f,0x24,0x61,0x70,0x70,0x4e,0x61,
+ 0x6d,0x65,0x3a,0x24,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x22,0x20,0x5d,
+ 0x0a,0x09,0x74,0x68,0x65,0x6e,0x20,0x72,0x6d,0x20,0x2d,0x66,0x20,0x22,
+ 0x24,0x70,0x72,0x65,0x66,0x69,0x78,0x2f,0x24,0x61,0x70,0x70,0x4e,0x61,
+ 0x6d,0x65,0x3a,0x24,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x22,0x0a,0x09,
+ 0x66,0x69,0x0a,0x09,0x0a,0x09,0x63,0x70,0x20,0x2d,0x66,0x20,0x22,0x24,
+ 0x66,0x69,0x6c,0x65,0x4c,0x69,0x73,0x74,0x22,0x20,0x22,0x24,0x70,0x72,
+ 0x65,0x66,0x69,0x78,0x2f,0x24,0x61,0x70,0x70,0x4e,0x61,0x6d,0x65,0x3a,
+ 0x24,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x22,0x0a,0x7d,0x0a,0x0a,0x75,
+ 0x6e,0x74,0x69,0x6c,0x20,0x5b,0x20,0x2d,0x7a,0x20,0x22,0x24,0x31,0x22,
+ 0x20,0x5d,0x20,0x20,0x23,0x20,0x55,0x6e,0x74,0x69,0x6c,0x20,0x61,0x6c,
+ 0x6c,0x20,0x70,0x61,0x72,0x61,0x6d,0x65,0x74,0x65,0x72,0x73,0x20,0x75,
+ 0x73,0x65,0x64,0x20,0x75,0x70,0x2e,0x2e,0x2e,0x0a,0x64,0x6f,0x0a,0x09,
+ 0x69,0x66,0x20,0x5b,0x20,0x22,0x24,0x31,0x22,0x20,0x3d,0x3d,0x20,0x22,
+ 0x2d,0x2d,0x68,0x65,0x6c,0x70,0x22,0x20,0x5d,0x0a,0x09,0x74,0x68,0x65,
+ 0x6e,0x20,0x70,0x72,0x69,0x6e,0x74,0x48,0x65,0x6c,0x70,0x0a,0x09,0x65,
+ 0x6c,0x69,0x66,0x20,0x5b,0x20,0x22,0x24,0x31,0x22,0x20,0x3d,0x3d,0x20,
+ 0x22,0x2d,0x2d,0x66,0x69,0x6c,0x65,0x6c,0x69,0x73,0x74,0x22,0x20,0x5d,
+ 0x0a,0x09,0x74,0x68,0x65,0x6e,0x0a,0x09,0x09,0x73,0x68,0x69,0x66,0x74,
+ 0x0a,0x09,0x09,0x66,0x69,0x6c,0x65,0x4c,0x69,0x73,0x74,0x3d,0x24,0x31,
+ 0x0a,0x09,0x65,0x6c,0x69,0x66,0x20,0x5b,0x20,0x22,0x24,0x31,0x22,0x20,
+ 0x3d,0x3d,0x20,0x22,0x2d,0x2d,0x61,0x70,0x70,0x6e,0x61,0x6d,0x65,0x22,
+ 0x20,0x5d,0x0a,0x09,0x74,0x68,0x65,0x6e,0x0a,0x09,0x09,0x73,0x68,0x69,
+ 0x66,0x74,0x0a,0x09,0x09,0x61,0x70,0x70,0x4e,0x61,0x6d,0x65,0x3d,0x24,
+ 0x31,0x0a,0x09,0x65,0x6c,0x69,0x66,0x20,0x5b,0x20,0x22,0x24,0x31,0x22,
+ 0x20,0x3d,0x3d,0x20,0x22,0x2d,0x2d,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,
+ 0x22,0x20,0x5d,0x0a,0x09,0x74,0x68,0x65,0x6e,0x0a,0x09,0x09,0x73,0x68,
+ 0x69,0x66,0x74,0x0a,0x09,0x09,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3d,
+ 0x24,0x31,0x0a,0x09,0x66,0x69,0x0a,0x09,0x73,0x68,0x69,0x66,0x74,0x0a,
+ 0x64,0x6f,0x6e,0x65,0x0a,0x0a,0x69,0x66,0x20,0x5b,0x20,0x2d,0x7a,0x20,
+ 0x22,0x24,0x66,0x69,0x6c,0x65,0x4c,0x69,0x73,0x74,0x22,0x20,0x2d,0x6f,
+ 0x20,0x2d,0x7a,0x20,0x22,0x24,0x61,0x70,0x70,0x4e,0x61,0x6d,0x65,0x22,
+ 0x20,0x2d,0x6f,0x20,0x2d,0x7a,0x20,0x22,0x24,0x76,0x65,0x72,0x73,0x69,
+ 0x6f,0x6e,0x22,0x20,0x5d,0x0a,0x74,0x68,0x65,0x6e,0x20,0x70,0x72,0x69,
+ 0x6e,0x74,0x48,0x65,0x6c,0x70,0x0a,0x66,0x69,0x0a,0x0a,0x0a,0x77,0x68,
+ 0x6f,0x61,0x6d,0x69,0x3d,0x60,0x77,0x68,0x6f,0x61,0x6d,0x69,0x60,0x0a,
+ 0x0a,0x77,0x72,0x69,0x74,0x65,0x41,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,
+ 0x55,0x6e,0x69,0x6e,0x73,0x74,0x61,0x6c,0x6c,0x4c,0x69,0x73,0x74,0x0a
+};
+
+/* Generated by qembed */
+static const unsigned int uninstaller_sh_len = 1284;
+static const unsigned char uninstaller_sh_data[] = {
+ 0x23,0x21,0x2f,0x62,0x69,0x6e,0x2f,0x62,0x61,0x73,0x68,0x0a,0x0a,0x70,
+ 0x72,0x69,0x6e,0x74,0x48,0x65,0x6c,0x70,0x28,0x29,0x0a,0x7b,0x0a,0x09,
+ 0x65,0x63,0x68,0x6f,0x20,0x22,0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,
+ 0x61,0x20,0x68,0x65,0x6c,0x70,0x65,0x72,0x20,0x73,0x63,0x72,0x69,0x70,
+ 0x74,0x20,0x66,0x6f,0x72,0x20,0x41,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,
+ 0x22,0x0a,0x09,0x65,0x63,0x68,0x6f,0x20,0x22,0x55,0x73,0x61,0x67,0x65,
+ 0x3a,0x20,0x75,0x6e,0x69,0x6e,0x73,0x74,0x61,0x6c,0x6c,0x65,0x72,0x2e,
+ 0x73,0x68,0x22,0x0a,0x09,0x65,0x63,0x68,0x6f,0x20,0x22,0x20,0x20,0x20,
+ 0x2d,0x2d,0x6c,0x69,0x73,0x74,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x4c,0x69,0x73,0x74,0x73,0x20,0x61,0x6c,0x6c,0x20,
+ 0x69,0x6e,0x73,0x74,0x61,0x6c,0x6c,0x65,0x64,0x20,0x70,0x61,0x63,0x6b,
+ 0x61,0x67,0x65,0x73,0x22,0x0a,0x09,0x65,0x63,0x68,0x6f,0x20,0x22,0x20,
+ 0x20,0x20,0x2d,0x2d,0x66,0x69,0x6c,0x65,0x73,0x20,0x50,0x41,0x43,0x4b,
+ 0x41,0x47,0x45,0x20,0x20,0x20,0x4c,0x69,0x73,0x74,0x73,0x20,0x74,0x68,
+ 0x65,0x20,0x66,0x69,0x6c,0x65,0x73,0x20,0x69,0x6e,0x20,0x74,0x68,0x65,
+ 0x20,0x70,0x61,0x63,0x6b,0x61,0x67,0x65,0x20,0x50,0x41,0x43,0x4b,0x41,
+ 0x47,0x45,0x22,0x0a,0x09,0x65,0x63,0x68,0x6f,0x20,0x22,0x20,0x20,0x20,
+ 0x2d,0x2d,0x72,0x65,0x6d,0x6f,0x76,0x65,0x20,0x50,0x41,0x43,0x4b,0x41,
+ 0x47,0x45,0x20,0x20,0x52,0x65,0x6d,0x6f,0x76,0x65,0x73,0x20,0x74,0x68,
+ 0x65,0x20,0x70,0x61,0x63,0x6b,0x61,0x67,0x65,0x20,0x50,0x41,0x43,0x4b,
+ 0x41,0x47,0x45,0x22,0x0a,0x7d,0x0a,0x0a,0x6c,0x69,0x73,0x74,0x41,0x72,
+ 0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x50,0x61,0x63,0x6b,0x61,0x67,0x65,0x73,
+ 0x28,0x29,0x0a,0x7b,0x0a,0x09,0x66,0x69,0x6e,0x64,0x20,0x22,0x2f,0x76,
+ 0x61,0x72,0x2f,0x61,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x22,0x20,0x2d,
+ 0x74,0x79,0x70,0x65,0x20,0x66,0x20,0x2d,0x6d,0x61,0x78,0x64,0x65,0x70,
+ 0x74,0x68,0x20,0x31,0x20,0x2d,0x72,0x65,0x67,0x65,0x78,0x20,0x22,0x2e,
+ 0x2a,0x3a,0x2e,0x2a,0x22,0x20,0x2d,0x70,0x72,0x69,0x6e,0x74,0x66,0x20,
+ 0x22,0x25,0x66,0x5c,0x6e,0x22,0x0a,0x7d,0x0a,0x0a,0x6c,0x69,0x73,0x74,
+ 0x41,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x46,0x69,0x6c,0x65,0x73,0x28,
+ 0x29,0x0a,0x7b,0x0a,0x09,0x23,0x20,0x4c,0x69,0x73,0x74,0x73,0x20,0x74,
+ 0x68,0x65,0x20,0x66,0x69,0x6c,0x65,0x73,0x20,0x69,0x6e,0x73,0x74,0x61,
+ 0x6c,0x6c,0x65,0x64,0x20,0x69,0x6e,0x20,0x61,0x6e,0x20,0x41,0x72,0x6b,
+ 0x6f,0x6c,0x6c,0x6f,0x6e,0x20,0x70,0x61,0x63,0x6b,0x61,0x67,0x65,0x0a,
+ 0x09,0x69,0x66,0x20,0x5b,0x20,0x2d,0x7a,0x20,0x24,0x31,0x20,0x5d,0x0a,
+ 0x09,0x74,0x68,0x65,0x6e,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x0a,0x09,
+ 0x66,0x69,0x0a,0x09,0x0a,0x09,0x69,0x66,0x20,0x5b,0x20,0x2d,0x65,0x20,
+ 0x22,0x2f,0x76,0x61,0x72,0x2f,0x61,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,
+ 0x2f,0x24,0x31,0x22,0x20,0x5d,0x0a,0x09,0x74,0x68,0x65,0x6e,0x20,0x70,
+ 0x72,0x65,0x66,0x69,0x78,0x3d,0x22,0x2f,0x76,0x61,0x72,0x2f,0x61,0x72,
+ 0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x22,0x0a,0x09,0x65,0x6c,0x73,0x65,0x20,
+ 0x72,0x65,0x74,0x75,0x72,0x6e,0x0a,0x09,0x66,0x69,0x0a,0x09,0x0a,0x09,
+ 0x63,0x61,0x74,0x20,0x22,0x24,0x70,0x72,0x65,0x66,0x69,0x78,0x2f,0x24,
+ 0x31,0x22,0x0a,0x7d,0x0a,0x0a,0x72,0x65,0x6d,0x6f,0x76,0x65,0x41,0x72,
+ 0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x50,0x61,0x63,0x6b,0x61,0x67,0x65,0x28,
+ 0x29,0x0a,0x7b,0x0a,0x09,0x23,0x20,0x52,0x65,0x6d,0x6f,0x76,0x65,0x73,
+ 0x20,0x61,0x6e,0x20,0x61,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x20,0x70,
+ 0x61,0x63,0x6b,0x61,0x67,0x65,0x0a,0x09,0x69,0x66,0x20,0x5b,0x20,0x2d,
+ 0x7a,0x20,0x24,0x31,0x20,0x5d,0x0a,0x09,0x74,0x68,0x65,0x6e,0x20,0x72,
+ 0x65,0x74,0x75,0x72,0x6e,0x0a,0x09,0x66,0x69,0x0a,0x09,0x0a,0x09,0x70,
+ 0x72,0x65,0x66,0x69,0x78,0x3d,0x22,0x2f,0x76,0x61,0x72,0x2f,0x61,0x72,
+ 0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x22,0x0a,0x0a,0x09,0x69,0x66,0x20,0x5b,
+ 0x20,0x21,0x20,0x2d,0x65,0x20,0x22,0x24,0x70,0x72,0x65,0x66,0x69,0x78,
+ 0x2f,0x24,0x31,0x22,0x20,0x5d,0x0a,0x09,0x74,0x68,0x65,0x6e,0x0a,0x09,
+ 0x09,0x65,0x63,0x68,0x6f,0x20,0x24,0x31,0x20,0x64,0x6f,0x65,0x73,0x20,
+ 0x6e,0x6f,0x74,0x20,0x65,0x78,0x69,0x73,0x74,0x0a,0x09,0x09,0x72,0x65,
+ 0x74,0x75,0x72,0x6e,0x0a,0x09,0x66,0x69,0x0a,0x0a,0x09,0x65,0x63,0x68,
+ 0x6f,0x20,0x52,0x65,0x6d,0x6f,0x76,0x69,0x6e,0x67,0x20,0x74,0x68,0x65,
+ 0x20,0x41,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x20,0x70,0x61,0x63,0x6b,
+ 0x61,0x67,0x65,0x20,0x24,0x31,0x0a,0x09,0x77,0x68,0x69,0x6c,0x65,0x20,
+ 0x72,0x65,0x61,0x64,0x20,0x6c,0x69,0x6e,0x65,0x0a,0x09,0x64,0x6f,0x0a,
+ 0x09,0x09,0x69,0x66,0x20,0x5b,0x20,0x2d,0x65,0x20,0x22,0x24,0x6c,0x69,
+ 0x6e,0x65,0x22,0x20,0x5d,0x0a,0x09,0x09,0x74,0x68,0x65,0x6e,0x20,0x72,
+ 0x6d,0x20,0x2d,0x66,0x76,0x20,0x22,0x24,0x6c,0x69,0x6e,0x65,0x22,0x0a,
+ 0x09,0x09,0x66,0x69,0x0a,0x09,0x64,0x6f,0x6e,0x65,0x20,0x3c,0x20,0x22,
+ 0x24,0x70,0x72,0x65,0x66,0x69,0x78,0x2f,0x24,0x31,0x22,0x0a,0x09,0x72,
+ 0x6d,0x20,0x2d,0x66,0x76,0x20,0x22,0x24,0x70,0x72,0x65,0x66,0x69,0x78,
+ 0x2f,0x24,0x31,0x22,0x0a,0x7d,0x0a,0x0a,0x69,0x66,0x20,0x5b,0x20,0x2d,
+ 0x7a,0x20,0x22,0x24,0x31,0x22,0x20,0x5d,0x0a,0x74,0x68,0x65,0x6e,0x20,
+ 0x70,0x72,0x69,0x6e,0x74,0x48,0x65,0x6c,0x70,0x0a,0x66,0x69,0x0a,0x0a,
+ 0x75,0x6e,0x74,0x69,0x6c,0x20,0x5b,0x20,0x2d,0x7a,0x20,0x22,0x24,0x31,
+ 0x22,0x20,0x5d,0x20,0x20,0x23,0x20,0x55,0x6e,0x74,0x69,0x6c,0x20,0x61,
+ 0x6c,0x6c,0x20,0x70,0x61,0x72,0x61,0x6d,0x65,0x74,0x65,0x72,0x73,0x20,
+ 0x75,0x73,0x65,0x64,0x20,0x75,0x70,0x2e,0x2e,0x2e,0x0a,0x64,0x6f,0x0a,
+ 0x09,0x69,0x66,0x20,0x5b,0x20,0x22,0x24,0x31,0x22,0x20,0x3d,0x3d,0x20,
+ 0x22,0x2d,0x2d,0x68,0x65,0x6c,0x70,0x22,0x20,0x5d,0x0a,0x09,0x74,0x68,
+ 0x65,0x6e,0x20,0x70,0x72,0x69,0x6e,0x74,0x48,0x65,0x6c,0x70,0x0a,0x09,
+ 0x65,0x6c,0x69,0x66,0x20,0x5b,0x20,0x22,0x24,0x31,0x22,0x20,0x3d,0x3d,
+ 0x20,0x22,0x2d,0x2d,0x6c,0x69,0x73,0x74,0x22,0x20,0x5d,0x0a,0x09,0x74,
+ 0x68,0x65,0x6e,0x0a,0x09,0x09,0x73,0x68,0x69,0x66,0x74,0x0a,0x09,0x09,
+ 0x6c,0x69,0x73,0x74,0x41,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x50,0x61,
+ 0x63,0x6b,0x61,0x67,0x65,0x73,0x20,0x24,0x31,0x0a,0x09,0x65,0x6c,0x69,
+ 0x66,0x20,0x5b,0x20,0x22,0x24,0x31,0x22,0x20,0x3d,0x3d,0x20,0x22,0x2d,
+ 0x2d,0x66,0x69,0x6c,0x65,0x73,0x22,0x20,0x5d,0x0a,0x09,0x74,0x68,0x65,
+ 0x6e,0x0a,0x09,0x09,0x73,0x68,0x69,0x66,0x74,0x0a,0x09,0x09,0x6c,0x69,
+ 0x73,0x74,0x41,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x46,0x69,0x6c,0x65,
+ 0x73,0x20,0x24,0x31,0x0a,0x09,0x65,0x6c,0x69,0x66,0x20,0x5b,0x20,0x22,
+ 0x24,0x31,0x22,0x20,0x3d,0x3d,0x20,0x22,0x2d,0x2d,0x72,0x65,0x6d,0x6f,
+ 0x76,0x65,0x22,0x20,0x5d,0x0a,0x09,0x74,0x68,0x65,0x6e,0x0a,0x09,0x09,
+ 0x73,0x68,0x69,0x66,0x74,0x0a,0x09,0x09,0x72,0x65,0x6d,0x6f,0x76,0x65,
+ 0x41,0x72,0x6b,0x6f,0x6c,0x6c,0x6f,0x6e,0x50,0x61,0x63,0x6b,0x61,0x67,
+ 0x65,0x20,0x24,0x31,0x0a,0x09,0x66,0x69,0x0a,0x09,0x73,0x68,0x69,0x66,
+ 0x74,0x0a,0x64,0x6f,0x6e,0x65,0x0a,0x09,0x09,0x0a
+};
+
+#include <qimage.h>
+#include <qdict.h>
+static const QRgb misc_data[] = {
+ 0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,
+ 0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffefefe,0xfffcfcfc,0xfffbfbfb,0xfff9f9f9,
+ 0xfff7f7f7,0xfff6f6f6,0xffffffff,0xff8f8f8f,0xff8f8f8f,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffefefe,0xfffbfbfb,0xfffafafa,0xfff8f8f8,
+ 0xfff7f7f7,0xfff4f4f4,0xfff3f3f3,0xfff2f2f2,0xffffffff,0xff8f8f8f,0xff8f8f8f,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffdfdfd,0xfffafafa,
+ 0xfff9f9f9,0xfff7f7f7,0xfff5f5f5,0xfff4f4f4,0xfff2f2f2,0xfff1f1f1,0xffffffff,0xff8f8f8f,0xff8f8f8f,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffefefe,
+ 0xfffcfcfc,0xfff9f9f9,0xfff8f8f8,0xfff6f6f6,0xfff5f5f5,0xfff3f3f3,0xfff2f2f2,0xffefefef,0xffffffff,0xff8f8f8f,0xff8f8f8f,0xffffffff,0xffffffff,0xffffffff,
+ 0xfffefefe,0xfffcfcfc,0xfffbfbfb,0xfff8f8f8,0xfff7f7f7,0xfff5f5f5,0xfff4f4f4,0xfff2f2f2,0xfff0f0f0,0xffe9e9e9,0xffffffff,0xff8f8f8f,0xff8f8f8f,0xffffffff,
+ 0xffffffff,0xffffffff,0xfffdfdfd,0xfffbfbfb,0xfffafafa,0xfff7f7f7,0xfff6f6f6,0xfff4f4f4,0xfff3f3f3,0xfff1f1f1,0xffebebeb,0xffe8e8e8,0xffffffff,0xff8f8f8f,
+ 0xff8f8f8f,0xffffffff,0xffffffff,0xfffefefe,0xfffbfbfb,0xfffafafa,0xfff8f8f8,0xfff7f7f7,0xfff5f5f5,0xfff3f3f3,0xfff1f1f1,0xffececec,0xffeaeaea,0xffebebeb,
+ 0xffffffff,0xff8f8f8f,0xff8f8f8f,0xffffffff,0xfffdfdfd,0xfffcfcfc,0xfffbfbfb,0xfff9f9f9,0xfff6f6f6,0xfff5f5f5,0xfff2f2f2,0xffefefef,0xffededed,0xffececec,
+ 0xffededed,0xffededed,0xffffffff,0xff8f8f8f,0xff8f8f8f,0xffffffff,0xfff0f0f0,0xfff2f2f2,0xfff3f3f3,0xfff2f2f2,0xfff1f1f1,0xfff0f0f0,0xffeeeeee,0xffeeeeee,
+ 0xffefefef,0xffefefef,0xffefefef,0xffefefef,0xffffffff,0xff8f8f8f,0xff8f8f8f,0xffffffff,0xfff0f0f0,0xfff0f0f0,0xfff0f0f0,0xfff0f0f0,0xfff0f0f0,0xfff0f0f0,
+ 0xfff0f0f0,0xfff1f1f1,0xfff1f1f1,0xffececec,0xffeaeaea,0xffe9e9e9,0xffffffff,0xff8f8f8f,0xff8f8f8f,0xffffffff,0xfff3f3f3,0xfff3f3f3,0xfff3f3f3,0xfff3f3f3,
+ 0xfff3f3f3,0xfff3f3f3,0xfff3f3f3,0xfff4f4f4,0xffebebeb,0xffa8a8a8,0xffa8a8a8,0xffa8a8a8,0xffa8a8a8,0xff8f8f8f,0xff8f8f8f,0xffffffff,0xfff5f5f5,0xfff5f5f5,
+ 0xfff5f5f5,0xfff5f5f5,0xfff5f5f5,0xfff5f5f5,0xfff5f5f5,0xfff6f6f6,0xffececec,0xffa8a8a8,0xffffffff,0xffffffff,0xff8f8f8f,0xe000000,0xff8f8f8f,0xffffffff,
+ 0xfff7f7f7,0xfff7f7f7,0xfff7f7f7,0xfff7f7f7,0xfff7f7f7,0xfff7f7f7,0xfff7f7f7,0xfff8f8f8,0xffededed,0xffa8a8a8,0xffffffff,0xff8f8f8f,0x6000000,0x0,
+ 0xff8f8f8f,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffbfbfb,0xffa8a8a8,0xff8f8f8f,0x0,
+ 0x0,0x0,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,0xff8f8f8f,
+ 0x0,0x0,0x0,0x0
+};
+
+static const QRgb splash_data[] = {
+ 0xff40bdff,0xff60cbff,0xff50c5ff,0xff61ccff,0xff51c5ff,0xff62ccff,0xff62ccff,0xff63ccff,0xff63ccff,0xff43c1ff,0xff64cdff,0xff54c8ff,0xff65ceff,0xff65ceff,
+ 0xff55c8ff,0xff46c3ff,0xff67cfff,0xff47c3ff,0xff57cbff,0xff78d5ff,0xff68cfff,0xff57cbff,0xff46c3ff,0xff46c3ff,0xff66cfff,0xff45c2ff,0xff54c8ff,0xff75d3ff,
+ 0xff43c1ff,0xff44c0ff,0xff43c1ff,0xff42c0ff,0xff63ccff,0xff41c0ff,0xff41bfff,0xff61ccff,0xff60ccff,0xff60ccff,0xff5fcbff,0xff3fbcff,0xff4fc2ff,0xff5fc9ff,
+ 0xff4dc1ff,0xff5ec8ff,0xff3cbbff,0xff5dc8ff,0xff3cbaff,0xff5cc7ff,0xff6dceff,0xff4ac1ff,0xff5cc7ff,0xff3ab9ff,0xff5bc6ff,0xff49bfff,0xff5ac6ff,0xff5ac6ff,
+ 0xff37b7ff,0xff37b5ff,0xff37b5ff,0xff35b5ff,0xff36b5ff,0xff46bbff,0xff57c3ff,0xff44bbff,0xff56c2ff,0xff56c1ff,0xff55c1ff,0xff32b3ff,0xff32b2ff,0xff32b2ff,
+ 0xff32b2ff,0xff65c7ff,0xff54c0ff,0xff53c0ff,0xff40b8ff,0xff52bfff,0xff51bfff,0xff3fb7ff,0xff2eaeff,0xff2daeff,0xff2daeff,0xff3eb5ff,0xff4fbdff,0xff4fbcff,
+ 0xff4ebdff,0xff4ebcff,0xff4dbcff,0xff4cbbff,0xff4cbbff,0xff28abff,0xff28abff,0xff4bbaff,0xff4bbaff,0xff4bb9ff,0xff4ab9ff,0xff26a9ff,0xff26a9ff,0xff25a8ff,
+ 0xff24a8ff,0xff24a7ff,0xff48b8ff,0xff24a7ff,0xff35aeff,0xff47b7ff,0xff47b7ff,0xff33adff,0xff46b5ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,
+ 0xff1fa2ff,0xff1fa2ff,0xff1fa1ff,0xff1ea2ff,0xff30aaff,0xff41b3ff,0xff41b2ff,0xff41b3ff,0xff2ea9ff,0xff55baff,0xff41b2ff,0xff1ca0ff,0xff41b3ff,0xff56bbff,
+ 0xff2fabff,0xff1ea1ff,0xff1fa1ff,0xff20a2ff,0xff4fcaff,0xff50caff,0xff51cbff,0xff51cbff,0xff51cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff54ccff,0xff54ccff,
+ 0xff54cdff,0xff55ceff,0xff55ceff,0xff56ceff,0xff57cfff,0xff57ceff,0xff8addff,0xff7ad9ff,0xff59d0ff,0xff5ad0ff,0xff59d0ff,0xff58cfff,0xff69d4ff,0xff79d9ff,
+ 0xff79d8ff,0xff57ceff,0xff56cdff,0xff55cdff,0xff54cdff,0xff54cdff,0xff54ccff,0xff53ccff,0xff53ccff,0xff52ccff,0xff52cbff,0xff51cbff,0xff51cbff,0xff50caff,
+ 0xff4fc9ff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff4ac7ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,0xff48c6ff,
+ 0xff49c6ff,0xff5accff,0xff6cd1ff,0xff6cd0ff,0xff5acaff,0xff46c4ff,0xff45c3ff,0xff45c3ff,0xff45c3ff,0xff44c2ff,0xff43c2ff,0xff42c2ff,0xff42c1ff,0xff41c2ff,
+ 0xff41c1ff,0xff41c0ff,0xff40c1ff,0xff40c0ff,0xff3fc0ff,0xff3fc0ff,0xff3ebfff,0xff3ebeff,0xff3dbeff,0xff3cbeff,0xff3dbeff,0xff3cbdff,0xff3bbdff,0xff3abcff,
+ 0xff3abdff,0xff39bdff,0xff39bcff,0xff38bcff,0xff38bcff,0xff37bbff,0xff37bbff,0xff36bbff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff34b9ff,0xff33b9ff,0xff33b8ff,
+ 0xff32b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff31b6ff,0xff31b6ff,0xff30b7ff,0xff30b5ff,0xff2fb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2db5ff,0xff2cb4ff,
+ 0xff2cb3ff,0xff2cb3ff,0xff2bb3ff,0xff2bb3ff,0xff2ab2ff,0xff29b2ff,0xff28b2ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,
+ 0xff25afff,0xff26b0ff,0xff26b0ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff40bfff,0xff41bfff,0xff41bfff,0xff41c0ff,
+ 0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff43c1ff,0xff43c2ff,0xff44c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff46c3ff,0xff47c3ff,0xff47c3ff,0xff48c5ff,0xff48c5ff,
+ 0xff48c5ff,0xff47c5ff,0xff47c3ff,0xff46c2ff,0xff46c2ff,0xff46c2ff,0xff45c2ff,0xff44c2ff,0xff44c1ff,0xff43c1ff,0xff43c0ff,0xff43c0ff,0xff41c0ff,0xff41bfff,
+ 0xff41bfff,0xff41bfff,0xff40bdff,0xff40bdff,0xff40bdff,0xff3fbcff,0xff3fbcff,0xff3ebcff,0xff3dbcff,0xff3dbcff,0xff3dbbff,0xff3cbbff,0xff3cbbff,0xff3bbaff,
+ 0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff39b8ff,0xff39b7ff,0xff37b8ff,0xff38b7ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff35b4ff,
+ 0xff34b4ff,0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,0xff33b2ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,
+ 0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2eaeff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2bacff,0xff2aacff,0xff29acff,0xff29abff,0xff29abff,
+ 0xff28aaff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff26a9ff,0xff25a9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,
+ 0xff22a5ff,0xff23a4ff,0xff21a4ff,0xff22a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff20a3ff,0xff1fa3ff,0xff1fa2ff,0xff1ea2ff,0xff1ea1ff,0xff1da1ff,
+ 0xff1ca1ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,0xff1ca0ff,0xff1ca0ff,0xff1ca1ff,0xff1da0ff,0xff1ea1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff4fcaff,0xff50caff,
+ 0xff51cbff,0xff51cbff,0xff51cbff,0xff52cbff,0xff52ccff,0xff53ccff,0xff65d2ff,0xff54cdff,0xff54cdff,0xff56cdff,0xff55ceff,0xff56ceff,0xff57ceff,0xff57cfff,
+ 0xff89ddff,0xff7ad9ff,0xff59d0ff,0xff7bd9ff,0xff7ad9ff,0xff58d0ff,0xff69d4ff,0xff79d8ff,0xff78d8ff,0xff56ceff,0xff56cdff,0xff55cdff,0xff55cdff,0xff55cdff,
+ 0xff54cdff,0xff53ccff,0xff63d1ff,0xff52ccff,0xff52cbff,0xff51caff,0xff50caff,0xff50cbff,0xff50caff,0xff4fc9ff,0xff4fc9ff,0xff4ec9ff,0xff4dc9ff,0xff4dc8ff,
+ 0xff4dc8ff,0xff4cc8ff,0xff4bc7ff,0xff4bc7ff,0xff5dcdff,0xff4ac6ff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,0xff46c4ff,0xff47c5ff,0xff46c4ff,
+ 0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff56c8ff,0xff42c1ff,0xff55c7ff,0xff41c1ff,0xff41c0ff,0xff41c0ff,0xff3fc0ff,0xff3fc0ff,0xff3ebfff,
+ 0xff3ebfff,0xff3ebfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff4ec4ff,0xff3abdff,0xff3abcff,0xff39bcff,0xff39bcff,0xff38bbff,0xff37bbff,
+ 0xff37bbff,0xff36bbff,0xff35baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff46bfff,0xff46bfff,0xff31b7ff,0xff31b7ff,
+ 0xff30b6ff,0xff59c4ff,0xff44bdff,0xff2fb5ff,0xff2eb5ff,0xff2db4ff,0xff2cb5ff,0xff2cb4ff,0xff2cb3ff,0xff2bb3ff,0xff2ab3ff,0xff2ab2ff,0xff29b3ff,0xff29b2ff,
+ 0xff28b2ff,0xff28b2ff,0xff28b2ff,0xff27b1ff,0xff26b0ff,0xff52c0ff,0xff25afff,0xff25b0ff,0xff3bb8ff,0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff27b1ff,0xff28b2ff,
+ 0xff28b2ff,0xff29b2ff,0xff40bdff,0xff40bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff63ccff,0xff44c0ff,0xff44c1ff,0xff44c1ff,
+ 0xff44c2ff,0xff46c2ff,0xff45c2ff,0xff46c3ff,0xff66cfff,0xff47c5ff,0xff68cfff,0xff48c5ff,0xff48c3ff,0xff67cfff,0xff47c3ff,0xff46c2ff,0xff66ceff,0xff45c2ff,
+ 0xff45c2ff,0xff55c7ff,0xff44c1ff,0xff43c1ff,0xff42c0ff,0xff42c0ff,0xff63ccff,0xff42bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff40bdff,0xff3fbcff,0xff3fbcff,
+ 0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff3dbbff,0xff3cbbff,0xff3cbaff,0xff3bbaff,0xff3bbaff,0xff4ac0ff,0xff3ab9ff,0xff3ab9ff,0xff3ab8ff,0xff39b9ff,0xff39b8ff,
+ 0xff38b8ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff35b4ff,0xff34b5ff,0xff57c2ff,0xff33b4ff,0xff44baff,0xff33b3ff,0xff32b3ff,
+ 0xff32b2ff,0xff31b2ff,0xff31b2ff,0xff31b1ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff50bdff,0xff2daeff,0xff2cadff,
+ 0xff2cadff,0xff2badff,0xff2bacff,0xff2bacff,0xff2aabff,0xff29abff,0xff29abff,0xff28abff,0xff28aaff,0xff28abff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff26a9ff,
+ 0xff26a8ff,0xff37b0ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff49b7ff,0xff48b7ff,0xff23a5ff,0xff23a4ff,0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff21a4ff,0xff21a3ff,
+ 0xff20a3ff,0xff20a3ff,0xff1fa3ff,0xff1fa2ff,0xff1fa2ff,0xff1fa1ff,0xff1ea1ff,0xff1da0ff,0xff41b2ff,0xff1ca0ff,0xff1c9fff,0xff1ba0ff,0xff41b1ff,0xff1ca0ff,
+ 0xff1ca1ff,0xff1da1ff,0xff1da1ff,0xff1ea2ff,0xff1ea2ff,0xff1fa2ff,0xff4fcaff,0xff74d5ff,0xff73d5ff,0xff74d6ff,0xff62d1ff,0xff75d6ff,0xff75d6ff,0xff65d2ff,
+ 0xff76d6ff,0xff65d2ff,0xff66d2ff,0xff66d2ff,0xff78d7ff,0xff78d8ff,0xff68d3ff,0xff57cfff,0xff79d9ff,0xff58cfff,0xff59d0ff,0xff5ad0ff,0xff69d5ff,0xff69d5ff,
+ 0xff58cfff,0xff57cfff,0xff78d8ff,0xff56ceff,0xff66d3ff,0xff88ddff,0xff55cdff,0xff54cdff,0xff54cdff,0xff53ccff,0xff76d6ff,0xff52ccff,0xff51cbff,0xff51caff,
+ 0xff73d6ff,0xff73d5ff,0xff73d5ff,0xff61cfff,0xff72d4ff,0xff72d4ff,0xff60ceff,0xff71d3ff,0xff4dc8ff,0xff70d2ff,0xff4bc7ff,0xff5dcdff,0xff6fd2ff,0xff4ac7ff,
+ 0xff80d7ff,0xff6ed1ff,0xff6dd1ff,0xff5acbff,0xff6cd1ff,0xff6cd1ff,0xff59caff,0xff46c4ff,0xff45c4ff,0xff45c4ff,0xff57c9ff,0xff6aceff,0xff69ceff,0xff68ceff,
+ 0xff42c1ff,0xff7ad3ff,0xff41c1ff,0xff67cdff,0xff66cdff,0xff66cdff,0xff52c6ff,0xff66ccff,0xff65ccff,0xff64cbff,0xff50c5ff,0xff64cbff,0xff63caff,0xff4fc5ff,
+ 0xff63cbff,0xff75d1ff,0xff4ec4ff,0xff4dc3ff,0xff61caff,0xff61c9ff,0xff4cc2ff,0xff73cfff,0xff5fc9ff,0xff5fc9ff,0xff5ec8ff,0xff36baff,0xff35baff,0xff5dc7ff,
+ 0xff34b8ff,0xff33b9ff,0xff33b8ff,0xff32b8ff,0xff31b8ff,0xff31b7ff,0xff31b6ff,0xff30b7ff,0xff5ac5ff,0xff2fb6ff,0xff58c4ff,0xff58c4ff,0xff57c4ff,0xff42bcff,
+ 0xff57c3ff,0xff57c3ff,0xff57c3ff,0xff2bb4ff,0xff6acaff,0xff55c2ff,0xff3fbaff,0xff54c1ff,0xff54c1ff,0xff53c1ff,0xff28b1ff,0xff27b1ff,0xff52c0ff,0xff26b1ff,
+ 0xff52c0ff,0xff51bfff,0xff67c8ff,0xff3cb8ff,0xff52c0ff,0xff52c1ff,0xff3db9ff,0xff54c1ff,0xff28b2ff,0xff54c1ff,0xff40bdff,0xff60cbff,0xff61cbff,0xff61ccff,
+ 0xff41bfff,0xff62ccff,0xff62ccff,0xff63ccff,0xff74d3ff,0xff64cdff,0xff43c1ff,0xff64cdff,0xff64ceff,0xff66ceff,0xff66cfff,0xff46c3ff,0xff67cfff,0xff47c5ff,
+ 0xff48c5ff,0xff49c5ff,0xff68cfff,0xff47c3ff,0xff47c3ff,0xff46c3ff,0xff66cfff,0xff45c2ff,0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,0xff43c1ff,0xff42c0ff,
+ 0xff63ccff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff72d0ff,0xff61cbff,0xff71d0ff,0xff3fbcff,0xff5fc9ff,0xff5fc9ff,0xff5ec8ff,0xff4dc1ff,0xff4cc1ff,0xff5dc7ff,
+ 0xff3bbbff,0xff3abaff,0xff5cc7ff,0xff3ab9ff,0xff5bc6ff,0xff3ab8ff,0xff5bc6ff,0xff5bc6ff,0xff39b8ff,0xff59c5ff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,
+ 0xff58c2ff,0xff34b5ff,0xff34b4ff,0xff57c2ff,0xff33b4ff,0xff56c2ff,0xff33b3ff,0xff55c1ff,0xff32b2ff,0xff31b2ff,0xff41b9ff,0xff65c7ff,0xff53c0ff,0xff65c7ff,
+ 0xff53bfff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff51bdff,0xff2daeff,0xff4fbdff,0xff2cadff,0xff2badff,0xff4ebdff,0xff4ebcff,0xff2aacff,0xff3ab3ff,
+ 0xff4cbbff,0xff28abff,0xff28aaff,0xff4bbaff,0xff28a9ff,0xff27aaff,0xff27a9ff,0xff26a9ff,0xff25a8ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff49b8ff,0xff24a7ff,
+ 0xff48b8ff,0xff23a7ff,0xff23a5ff,0xff46b7ff,0xff46b5ff,0xff21a4ff,0xff46b4ff,0xff20a3ff,0xff45b4ff,0xff44b3ff,0xff44b4ff,0xff57bcff,0xff42b3ff,0xff56bcff,
+ 0xff1ea1ff,0xff2faaff,0xff2fa9ff,0xff1ca0ff,0xff41b2ff,0xff1ba0ff,0xff41b2ff,0xff1ca0ff,0xff41b3ff,0xff41b3ff,0xff42b3ff,0xff31aaff,0xff30abff,0xff43b3ff,
+ 0xff50caff,0xff73d5ff,0xff73d5ff,0xff74d6ff,0xff74d6ff,0xff52ccff,0xff53ccff,0xff76d6ff,0xff76d6ff,0xff66d2ff,0xff66d2ff,0xff77d7ff,0xff56ceff,0xff57ceff,
+ 0xff67d3ff,0xff57cfff,0xff7ad9ff,0xff59d0ff,0xff59d0ff,0xff7bd9ff,0xff58cfff,0xff59d0ff,0xff58cfff,0xff57cfff,0xff79d9ff,0xff56ceff,0xff66d3ff,0xff88dcff,
+ 0xff55cdff,0xff54ccff,0xff54ccff,0xff53ccff,0xff75d6ff,0xff52ccff,0xff51cbff,0xff51cbff,0xff73d6ff,0xff50caff,0xff61cfff,0xff72d5ff,0xff4fcaff,0xff4ec9ff,
+ 0xff71d3ff,0xff4dc8ff,0xff70d2ff,0xff5ecdff,0xff4bc7ff,0xff4bc7ff,0xff6fd2ff,0xff4ac6ff,0xff6fd1ff,0xff49c6ff,0xff6dd1ff,0xff48c5ff,0xff7fd6ff,0xff5acaff,
+ 0xff47c4ff,0xff46c3ff,0xff45c4ff,0xff45c3ff,0xff6acfff,0xff44c2ff,0xff56c9ff,0xff69ceff,0xff42c2ff,0xff68cdff,0xff41c1ff,0xff66cdff,0xff40c0ff,0xff3fc0ff,
+ 0xff3fc0ff,0xff66ccff,0xff3ebfff,0xff51c5ff,0xff64ccff,0xff3dbeff,0xff3cbeff,0xff4fc5ff,0xff3bbeff,0xff62caff,0xff4ec4ff,0xff61caff,0xff39bcff,0xff39bcff,
+ 0xff60c9ff,0xff5fc9ff,0xff36bbff,0xff36bbff,0xff4ac1ff,0xff5ec8ff,0xff5ec8ff,0xff5ec7ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,
+ 0xff31b7ff,0xff45bdff,0xff45beff,0xff2fb5ff,0xff58c5ff,0xff2eb5ff,0xff2db5ff,0xff57c4ff,0xff57c3ff,0xff2db4ff,0xff57c2ff,0xff2bb4ff,0xff56c2ff,0xff55c2ff,
+ 0xff54c2ff,0xff54c1ff,0xff29b1ff,0xff3eb9ff,0xff28b1ff,0xff52c1ff,0xff27b1ff,0xff26b0ff,0xff51c0ff,0xff25b0ff,0xff67c8ff,0xff52c0ff,0xff27b1ff,0xff27b0ff,
+ 0xff52c1ff,0xff28b2ff,0xff53c1ff,0xff3fbaff,0xff40bdff,0xff50c3ff,0xff41bdff,0xff50c5ff,0xff41bfff,0xff62ccff,0xff62ccff,0xff52c6ff,0xff53c7ff,0xff43c1ff,
+ 0xff54c7ff,0xff45c2ff,0xff64cdff,0xff65ceff,0xff46c3ff,0xff47c2ff,0xff66cfff,0xff47c3ff,0xff57c9ff,0xff68cfff,0xff68cfff,0xff57c9ff,0xff47c3ff,0xff46c2ff,
+ 0xff65ceff,0xff45c2ff,0xff44c1ff,0xff54c7ff,0xff43c1ff,0xff43c0ff,0xff43c0ff,0xff42c0ff,0xff52c5ff,0xff62ccff,0xff62ccff,0xff50c5ff,0xff50c5ff,0xff60cbff,
+ 0xff50c3ff,0xff3fbdff,0xff5fc9ff,0xff5fc9ff,0xff4ec2ff,0xff3dbbff,0xff4cc1ff,0xff3cbbff,0xff3bbaff,0xff5cc7ff,0xff5cc6ff,0xff4ac1ff,0xff49c0ff,0xff3ab9ff,
+ 0xff49c0ff,0xff5bc6ff,0xff49bdff,0xff5ac5ff,0xff48bfff,0xff36b7ff,0xff36b7ff,0xff36b5ff,0xff35b5ff,0xff58c3ff,0xff45bbff,0xff45bbff,0xff44bbff,0xff55c1ff,
+ 0xff55c1ff,0xff43baff,0xff32b3ff,0xff32b2ff,0xff32b2ff,0xff41b9ff,0xff53c0ff,0xff40b8ff,0xff2fb0ff,0xff52bfff,0xff51bfff,0xff2eaeff,0xff2eaeff,0xff3fb7ff,
+ 0xff3eb5ff,0xff2dadff,0xff4fbdff,0xff4fbdff,0xff2badff,0xff3bb3ff,0xff2aabff,0xff29abff,0xff3ab3ff,0xff28aaff,0xff28aaff,0xff4bbaff,0xff28a9ff,0xff27a9ff,
+ 0xff27a9ff,0xff26a9ff,0xff25a9ff,0xff25a8ff,0xff25a8ff,0xff49b8ff,0xff24a7ff,0xff24a5ff,0xff35adff,0xff23a7ff,0xff23a5ff,0xff33adff,0xff33adff,0xff46b5ff,
+ 0xff33acff,0xff20a3ff,0xff32acff,0xff20a3ff,0xff31abff,0xff31abff,0xff42b3ff,0xff30aaff,0xff30aaff,0xff2faaff,0xff1ca0ff,0xff1ca0ff,0xff2ea8ff,0xff41b2ff,
+ 0xff2ea9ff,0xff1ca0ff,0xff41b2ff,0xff41b3ff,0xff30aaff,0xff1ea1ff,0xff30aaff,0xff1fa2ff,0xff4fcaff,0xff50cbff,0xff51cbff,0xff51caff,0xff52cbff,0xff52ccff,
+ 0xff52ccff,0xff53ccff,0xff53cdff,0xff54cdff,0xff55cdff,0xff55ceff,0xff56ceff,0xff57ceff,0xff57ceff,0xff57ceff,0xff7ad9ff,0xff7ad9ff,0xff59cfff,0xff5ad0ff,
+ 0xff59d0ff,0xff58cfff,0xff69d4ff,0xff7ad9ff,0xff67d4ff,0xff56ceff,0xff56ceff,0xff55cdff,0xff54cdff,0xff54ccff,0xff53ccff,0xff53ccff,0xff53ccff,0xff52cbff,
+ 0xff52cbff,0xff51cbff,0xff51cbff,0xff50cbff,0xff4fcaff,0xff4fcaff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,0xff4cc7ff,0xff4bc7ff,0xff4bc7ff,
+ 0xff4ac7ff,0xff4ac6ff,0xff4ac6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,0xff6cd1ff,0xff6cd0ff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,
+ 0xff43c3ff,0xff43c2ff,0xff42c1ff,0xff41c1ff,0xff42c1ff,0xff41c0ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3fc0ff,0xff3ebfff,0xff3dbeff,0xff3dbeff,0xff3cbeff,
+ 0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff3bbdff,0xff3abcff,0xff3abdff,0xff39bcff,0xff38bbff,0xff38bbff,0xff37bbff,0xff37baff,0xff36bbff,0xff35baff,0xff5ec8ff,
+ 0xff5ec8ff,0xff34b9ff,0xff34b9ff,0xff33b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff30b7ff,0xff45beff,0xff30b7ff,0xff2fb6ff,0xff2fb6ff,0xff2eb5ff,
+ 0xff2eb5ff,0xff2db4ff,0xff2db4ff,0xff2db4ff,0xff2cb4ff,0xff2cb3ff,0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff2ab2ff,0xff28b2ff,0xff28b2ff,0xff3eb9ff,0xff27b1ff,
+ 0xff26b1ff,0xff26b0ff,0xff25b0ff,0xff25afff,0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff27b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff40bdff,
+ 0xff41bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff43c0ff,0xff43c0ff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff45c2ff,0xff46c3ff,0xff46c3ff,
+ 0xff47c3ff,0xff47c3ff,0xff48c3ff,0xff49c5ff,0xff47c3ff,0xff48c5ff,0xff47c3ff,0xff46c3ff,0xff46c3ff,0xff45c2ff,0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,
+ 0xff42c1ff,0xff42c0ff,0xff41c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff40bdff,0xff3fbdff,0xff3fbdff,0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff3dbcff,
+ 0xff3cbbff,0xff3cbbff,0xff3cbaff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff39b8ff,0xff39b8ff,0xff38b8ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,
+ 0xff37b5ff,0xff36b5ff,0xff35b5ff,0xff35b5ff,0xff35b5ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff33b2ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff30b1ff,
+ 0xff31b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2badff,0xff2badff,0xff2bacff,
+ 0xff29abff,0xff2aacff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff26a8ff,0xff26a8ff,0xff25a8ff,0xff24a8ff,0xff24a8ff,
+ 0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff22a5ff,0xff22a5ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,
+ 0xff1ea1ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,0xff1b9fff,0xff1ca0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,
+ 0xff1ea2ff,0xff1fa2ff,0xff50caff,0xff84daff,0xff50caff,0xff85daff,0xff52cbff,0xff52ccff,0xff53ccff,0xff53ccff,0xff76d7ff,0xff54ccff,0xff55cdff,0xff55cdff,
+ 0xff55ceff,0xff78d8ff,0xff57ceff,0xff57cfff,0xff58cfff,0xff58cfff,0xff58cfff,0xff5ad0ff,0xff59d0ff,0xff58d0ff,0xff58cfff,0xff57cfff,0xff57cfff,0xff56ceff,
+ 0xff55ceff,0xff55ceff,0xff55ceff,0xff54cdff,0xff87dbff,0xff53cdff,0xff53ccff,0xff63d0ff,0xff75d6ff,0xff52caff,0xff50cbff,0xff50caff,0xff4fcaff,0xff4fc9ff,
+ 0xff4ec9ff,0xff72d4ff,0xff4ec9ff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff4bc7ff,0xff4bc7ff,0xff4ac6ff,0xff4ac6ff,0xff49c6ff,0xff49c5ff,0xff49c5ff,0xff47c5ff,
+ 0xff47c5ff,0xff46c4ff,0xff47c4ff,0xff46c4ff,0xff45c3ff,0xff45c3ff,0xff45c2ff,0xff44c2ff,0xff43c3ff,0xff43c2ff,0xff43c1ff,0xff42c1ff,0xff42c1ff,0xff40c1ff,
+ 0xff40c0ff,0xff40c0ff,0xff3fbfff,0xff3ebfff,0xff3fbfff,0xff3ebfff,0xff3dbfff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3bbeff,0xff3bbdff,0xff3abdff,0xff39bcff,
+ 0xff39bcff,0xff39bbff,0xff38bbff,0xff38bbff,0xff37bbff,0xff36baff,0xff36baff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff34b8ff,0xff33b9ff,0xff33b8ff,0xff33b8ff,
+ 0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b7ff,0xff30b6ff,0xff2fb6ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2db5ff,0xff2db4ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,
+ 0xff2bb3ff,0xff2ab3ff,0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff27b1ff,0xff27b1ff,0xff26b1ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff25b0ff,0xff26b0ff,
+ 0xff26b1ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff40bdff,0xff71d0ff,0xff61ccff,0xff72d0ff,0xff41bfff,0xff62ccff,0xff62ccff,0xff42c0ff,
+ 0xff63ccff,0xff43c1ff,0xff53c8ff,0xff44c1ff,0xff55c8ff,0xff56c8ff,0xff45c3ff,0xff57c8ff,0xff66cfff,0xff57c9ff,0xff48c5ff,0xff68cfff,0xff58cbff,0xff58cbff,
+ 0xff47c3ff,0xff47c3ff,0xff46c3ff,0xff45c2ff,0xff65cdff,0xff64cdff,0xff43c1ff,0xff43c1ff,0xff63ccff,0xff43c0ff,0xff42c0ff,0xff41c0ff,0xff61ccff,0xff41bfff,
+ 0xff41bdff,0xff40bfff,0xff40bdff,0xff3fbdff,0xff4ec2ff,0xff4ec2ff,0xff3dbcff,0xff4dc1ff,0xff5ec8ff,0xff4cc1ff,0xff3cbbff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,
+ 0xff49c0ff,0xff5bc6ff,0xff49bfff,0xff49bfff,0xff49bfff,0xff59c5ff,0xff37b7ff,0xff47bdff,0xff36b5ff,0xff47bcff,0xff36b5ff,0xff35b4ff,0xff34b4ff,0xff34b4ff,
+ 0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff32b3ff,0xff32b2ff,0xff31b2ff,0xff30b2ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2eb1ff,0xff2eb0ff,0xff2eaeff,
+ 0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2dadff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2bacff,0xff2aabff,0xff2aabff,0xff29abff,0xff29aaff,0xff28abff,0xff28aaff,
+ 0xff28aaff,0xff27a9ff,0xff26a9ff,0xff27a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff22a5ff,0xff22a4ff,
+ 0xff21a4ff,0xff21a4ff,0xff21a4ff,0xff21a3ff,0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff20a2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1da0ff,0xff1ca0ff,
+ 0xff1ca0ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1ca1ff,0xff1da0ff,0xff1ea1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff4fcaff,0xff73d5ff,0xff73d5ff,0xff74d5ff,
+ 0xff62d0ff,0xff53cbff,0xff52ccff,0xff76d6ff,0xff76d6ff,0xff76d7ff,0xff54cdff,0xff55cdff,0xff56cdff,0xff79d8ff,0xff57ceff,0xff89ddff,0xff58cfff,0xff7ad9ff,
+ 0xff7bd9ff,0xff5ad0ff,0xff7bd9ff,0xff58cfff,0xff57cfff,0xff57cfff,0xff56ceff,0xff67d3ff,0xff56ceff,0xff55cdff,0xff76d8ff,0xff54ccff,0xff76d7ff,0xff53ccff,
+ 0xff53ccff,0xff52cbff,0xff75d6ff,0xff51cbff,0xff50cbff,0xff50caff,0xff50caff,0xff4fc9ff,0xff4fcaff,0xff72d3ff,0xff4ec9ff,0xff82d9ff,0xff4cc8ff,0xff70d3ff,
+ 0xff4bc7ff,0xff4bc7ff,0xff4bc6ff,0xff4ac6ff,0xff6ed1ff,0xff49c6ff,0xff6dd1ff,0xff6dd1ff,0xff5acaff,0xff47c4ff,0xff6bd0ff,0xff6bcfff,0xff45c4ff,0xff6acfff,
+ 0xff44c3ff,0xff44c2ff,0xff43c3ff,0xff43c2ff,0xff42c1ff,0xff41c2ff,0xff41c1ff,0xff40c0ff,0xff40c1ff,0xff3fc0ff,0xff3fc0ff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,
+ 0xff3dbfff,0xff3dbfff,0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff3abcff,0xff39bcff,0xff38bbff,0xff38bcff,0xff37baff,0xff37bbff,0xff36bbff,
+ 0xff36baff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff33b7ff,0xff31b8ff,0xff32b8ff,0xff31b7ff,0xff30b6ff,0xff2fb6ff,0xff30b6ff,
+ 0xff2eb6ff,0xff2eb6ff,0xff2eb5ff,0xff2db5ff,0xff2db4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff28b1ff,
+ 0xff28b1ff,0xff27b1ff,0xff26b1ff,0xff26b0ff,0xff26b0ff,0xff25afff,0xff25b0ff,0xff27b0ff,0xff27b0ff,0xff27b0ff,0xff28b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,
+ 0xff3fbdff,0xff60cbff,0xff41bfff,0xff61ccff,0xff51c6ff,0xff62ccff,0xff63ccff,0xff63ccff,0xff74d2ff,0xff63cdff,0xff44c1ff,0xff44c1ff,0xff45c2ff,0xff65ceff,
+ 0xff46c2ff,0xff66cfff,0xff47c3ff,0xff67cfff,0xff58cbff,0xff68cfff,0xff68cfff,0xff47c3ff,0xff47c3ff,0xff46c2ff,0xff46c3ff,0xff55c8ff,0xff65cdff,0xff65ceff,
+ 0xff63cdff,0xff43c1ff,0xff63cdff,0xff42c0ff,0xff42bfff,0xff41c0ff,0xff61ccff,0xff41bfff,0xff41bfff,0xff40bdff,0xff40bdff,0xff3fbcff,0xff3fbcff,0xff5fc9ff,
+ 0xff3dbcff,0xff5ec8ff,0xff3cbbff,0xff5dc8ff,0xff3cbaff,0xff3bbaff,0xff3abaff,0xff3abaff,0xff5bc6ff,0xff5bc6ff,0xff49c0ff,0xff5bc6ff,0xff38b8ff,0xff37b8ff,
+ 0xff5ac5ff,0xff59c5ff,0xff36b5ff,0xff58c3ff,0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff33b2ff,0xff32b2ff,0xff31b2ff,
+ 0xff31b2ff,0xff30b2ff,0xff30b1ff,0xff30b0ff,0xff2fb1ff,0xff2eb0ff,0xff2eaeff,0xff2eb0ff,0xff2eaeff,0xff2daeff,0xff2daeff,0xff2cadff,0xff2cadff,0xff2cadff,
+ 0xff2bacff,0xff2aacff,0xff2aabff,0xff2aabff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff28a9ff,0xff28a9ff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a8ff,
+ 0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff21a5ff,0xff21a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,
+ 0xff20a2ff,0xff20a2ff,0xff1ea2ff,0xff1fa1ff,0xff1ea1ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,0xff1ba0ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,
+ 0xff1ea1ff,0xff1ea2ff,0xff1ea1ff,0xff1fa2ff,0xff4fcaff,0xff73d5ff,0xff51caff,0xff74d6ff,0xff63d0ff,0xff75d6ff,0xff75d6ff,0xff76d6ff,0xff76d7ff,0xff54cdff,
+ 0xff76d7ff,0xff55ceff,0xff78d7ff,0xff89ddff,0xff68d3ff,0xff79d9ff,0xff57cfff,0xff7ad9ff,0xff6ad5ff,0xff7bd9ff,0xff7bd9ff,0xff58cfff,0xff58cfff,0xff57ceff,
+ 0xff57ceff,0xff67d3ff,0xff78d6fe,0xff77d6fe,0xff77d6fe,0xff65d1fe,0xff87dbff,0xff76d6ff,0xff52ccff,0xff75d6ff,0xff85daff,0xff62cfff,0xff51cbff,0xff50caff,
+ 0xff4fcaff,0xff4fcaff,0xff72d4ff,0xff83d9ff,0xff5fcdff,0xff71d4ff,0xff4cc8ff,0xff70d2ff,0xff4bc8ff,0xff4bc7ff,0xff4bc7ff,0xff49c6ff,0xff6ed1ff,0xff6ed1ff,
+ 0xff5accff,0xff6dd1ff,0xff48c4ff,0xff47c5ff,0xff6bd0ff,0xff6bd0ff,0xff6acfff,0xff7dd5ff,0xff44c3ff,0xff44c3ff,0xff43c3ff,0xff43c2ff,0xff42c2ff,0xff42c1ff,
+ 0xff41c1ff,0xff41c1ff,0xff40c1ff,0xff40c0ff,0xff3fbfff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3abdff,
+ 0xff3abdff,0xff39bcff,0xff39bcff,0xff39bbff,0xff38bcff,0xff38bbff,0xff37baff,0xff37baff,0xff36baff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff33b8ff,0xff33b9ff,
+ 0xff32b8ff,0xff33b8ff,0xff32b7ff,0xff31b8ff,0xff31b6ff,0xff30b6ff,0xff30b6ff,0xff2fb6ff,0xff2fb6ff,0xff2eb5ff,0xff2db5ff,0xff2db5ff,0xff2db4ff,0xff2cb4ff,
+ 0xff2cb3ff,0xff2cb3ff,0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,0xff29b2ff,0xff28b2ff,0xff28b2ff,0xff27b1ff,0xff28b1ff,0xff26b0ff,0xff26b0ff,0xff26b0ff,0xff25afff,
+ 0xff25afff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff28b1ff,0xff29b2ff,0xff2ab2ff,0xff3fbcff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,
+ 0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff43c1ff,0xff44c1ff,0xff44c2ff,0xff45c2ff,0xff45c2ff,0xff45c2ff,0xff47c3ff,0xff47c3ff,0xff47c3ff,0xff58cbff,0xff68cfff,
+ 0xff68cfff,0xff57c9ff,0xff47c2fe,0xff47c1fe,0xff47c2ff,0xff45c1fe,0xff44c1fe,0xff45c1fe,0xff44c1ff,0xff43c0fe,0xff43c0fe,0xff43c0ff,0xff43c0ff,0xff41bffe,
+ 0xff41befe,0xff41befe,0xff41befe,0xff40bcfe,0xff3fbcfe,0xff3fbbfe,0xff3ebcff,0xff3ebcff,0xff3ebcff,0xff3dbbff,0xff3dbbff,0xff3cbbff,0xff3cbaff,0xff3bbaff,
+ 0xff3abaff,0xff3ab9ff,0xff5bc6ff,0xff5bc6ff,0xff5bc6ff,0xff39b8ff,0xff38b8ff,0xff38b8ff,0xff37b7ff,0xff37b5ff,0xff36b5ff,0xff35b5ff,0xff35b5ff,0xff34b4ff,
+ 0xff34b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff32b2ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,0xff2fb0ff,0xff2fb0ff,
+ 0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2eaeff,0xff2dadff,0xff2dadff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2bacff,0xff2aacff,0xff29acff,0xff29abff,0xff28aaff,
+ 0xff28aaff,0xff28aaff,0xff28a9ff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff25a9ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a7ff,0xff23a7ff,
+ 0xff23a5ff,0xff23a5ff,0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1fa2ff,0xff1fa2ff,0xff1da1ff,0xff1da0ff,
+ 0xff1ca0ff,0xff1ca0ff,0xff1c9fff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1da1ff,0xff1da0ff,0xff1da1ff,0xff1ea2ff,0xff1ea1ff,0xff1fa2ff,0xff4fcaff,0xff50caff,
+ 0xff51caff,0xff51cbff,0xff52cbff,0xff52cbff,0xff53cbff,0xff53ccff,0xff54ccff,0xff54cdff,0xff55cdff,0xff55cdff,0xff56ceff,0xff56ceff,0xff57cfff,0xff57cfff,
+ 0xff58cfff,0xff58cfff,0xff59d0ff,0xff5ad0ff,0xff59cefe,0xff59d0ff,0xff59cfff,0xff58cefe,0xff58cffe,0xff58cefe,0xff59cefe,0xff58cdfe,0xff58cdfe,0xff57cdfe,
+ 0xff56cdfe,0xff55ccfe,0xff55ccfe,0xff53ccfe,0xff52cbfe,0xff52cbfe,0xff52cafe,0xff51cafe,0xff51cafe,0xff4fc9fe,0xff4ec9fe,0xff4ec8fe,0xff4dc7fe,0xff4dc7fe,
+ 0xff4dc8ff,0xff4cc7ff,0xff4bc8ff,0xff4bc7ff,0xff4bc7ff,0xff49c7ff,0xff4ac6ff,0xff49c5ff,0xff49c6ff,0xff48c5ff,0xff47c5ff,0xff47c4ff,0xff47c4ff,0xff46c4ff,
+ 0xff46c4ff,0xff44c3ff,0xff44c3ff,0xff44c2ff,0xff43c3ff,0xff42c2ff,0xff43c2ff,0xff41c1ff,0xff41c1ff,0xff41c1ff,0xff40c1ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,
+ 0xff3ebfff,0xff3ebfff,0xff3dbeff,0xff3dbfff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3bbdff,0xff3abcff,0xff3abcff,0xff39bcff,0xff38bcff,0xff38bbff,0xff38bbff,
+ 0xff37baff,0xff36bbff,0xff36baff,0xff36baff,0xff35b9ff,0xff34b9ff,0xff34b8ff,0xff33b9ff,0xff33b9ff,0xff33b8ff,0xff32b8ff,0xff31b7ff,0xff30b7ff,0xff30b7ff,
+ 0xff30b6ff,0xff30b5ff,0xff2fb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,0xff2ab2ff,
+ 0xff28b1ff,0xff28b2ff,0xff28b1ff,0xff27b1ff,0xff26b1ff,0xff26b0ff,0xff26afff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,
+ 0xff28b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff41bdff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff42c0ff,0xff42c0ff,0xff53c7ff,0xff43c0ff,0xff44c1ff,0xff44c1ff,
+ 0xff45c2ff,0xff45c2ff,0xff45c3ff,0xff46c2ff,0xff77d4ff,0xff67cfff,0xff47c4fe,0xff68cefe,0xff68cffe,0xff49c5fe,0xff5ac9fe,0xff6bd0ff,0xff69cffe,0xff4cc5fe,
+ 0xff4dc4fe,0xff4dc3fe,0xff4cc3fe,0xff4bc3fe,0xff49c3fe,0xff49c1fe,0xff56c7fe,0xff65ccfe,0xff65ccfe,0xff54c6fe,0xff45c0fe,0xff44befe,0xff43befe,0xff43bdfe,
+ 0xff51c3fe,0xff40bcfe,0xff3fbcfe,0xff3ebbfe,0xff3dbbff,0xff3cbbff,0xff3cbaff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,0xff49c0ff,0xff39b9ff,0xff38b8ff,
+ 0xff38b7ff,0xff37b7ff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff35b5ff,0xff34b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff43baff,0xff33b3ff,
+ 0xff33b2ff,0xff42b9ff,0xff31b2ff,0xff30b2ff,0xff30b2ff,0xff30b1ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2daeff,0xff2dadff,0xff2dadff,
+ 0xff3db5ff,0xff2badff,0xff2bacff,0xff2bacff,0xff2aacff,0xff29acff,0xff29abff,0xff29abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a8ff,
+ 0xff25a8ff,0xff25a8ff,0xff25a8ff,0xff24a7ff,0xff48b8ff,0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff23a5ff,0xff46b5ff,0xff33adff,0xff21a4ff,0xff21a3ff,0xff20a3ff,
+ 0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff1fa2ff,0xff1fa1ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,0xff41b2ff,0xff1ca0ff,
+ 0xff1da0ff,0xff1da1ff,0xff30abff,0xff1ea2ff,0xff1fa1ff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff50cbff,0xff51caff,0xff52cbff,0xff52cbff,0xff52ccff,0xff53cdff,
+ 0xff76d7ff,0xff54cdff,0xff55cdff,0xff55cdff,0xff56ceff,0xff56ceff,0xff57ceff,0xff57cfff,0xff7ad8fe,0xff59d0ff,0xff7cd8fe,0xff5cd0fe,0xff5bd0fe,0xff7dd9fe,
+ 0xff5ed0fe,0xff60d0fe,0xff81dafe,0xff63d1fe,0xff64d0fe,0xff73d5fe,0xff62d0fd,0xff61cffd,0xff5fcffd,0xff5dcefe,0xff7dd7fd,0xff5acefe,0xff59ccfd,0xff59cdfe,
+ 0xff58cbfd,0xff58ccfe,0xff58ccfe,0xff56cbfe,0xff77d5fe,0xff53cafe,0xff51c9fe,0xff50c9ff,0xff4ec8fe,0xff4bc7fe,0xff4bc6fe,0xff4bc7ff,0xff4ac7ff,0xff49c7ff,
+ 0xff4ac6ff,0xff5bccff,0xff48c5ff,0xff48c5ff,0xff47c4ff,0xff47c5ff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff43c2ff,0xff43c2ff,
+ 0xff42c1ff,0xff42c1ff,0xff67cdff,0xff41c0ff,0xff40c0ff,0xff53c6ff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,0xff3ebeff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3bbeff,
+ 0xff3bbdff,0xff3abdff,0xff3abcff,0xff39bcff,0xff61caff,0xff39bbff,0xff38bcff,0xff37bbff,0xff36baff,0xff36baff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,
+ 0xff33b9ff,0xff33b9ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,0xff30b7ff,0xff30b6ff,0xff2fb6ff,0xff45bdff,0xff2fb6ff,0xff2eb6ff,0xff58c4ff,0xff2db4ff,
+ 0xff57c3ff,0xff2cb4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff28b2ff,0xff28b1ff,0xff27b0ff,0xff26b1ff,0xff26b0ff,
+ 0xff25afff,0xff25b0ff,0xff51c0ff,0xff26b0ff,0xff26b0ff,0xff27b1ff,0xff52c1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff60cbff,0xff60cbff,0xff61ccff,
+ 0xff50c5ff,0xff62ccff,0xff62ccff,0xff52c6ff,0xff63cdff,0xff54c7ff,0xff54c8ff,0xff54c7ff,0xff64ceff,0xff65ceff,0xff56c7fe,0xff47c2ff,0xff67cfff,0xff49c3fe,
+ 0xff4bc3fe,0xff4ec7ff,0xff5eccfe,0xff61cdfe,0xff53c7fe,0xff57c8fe,0xff76d2fd,0xff5cc8fd,0xff6ccffe,0xff88d8fd,0xff5dc9fe,0xff5bc8fd,0xff59c7fd,0xff56c6fd,
+ 0xff72cffd,0xff6fcffd,0xff60c9fe,0xff52c4fe,0xff7dd3fe,0xff6ed0fe,0xff6dcffe,0xff5cc7fe,0xff7ad1fe,0xff67cbfe,0xff46bdfe,0xff63c9fe,0xff61c8fe,0xff5fc8fe,
+ 0xff5dc7ff,0xff5dc7ff,0xff5cc7ff,0xff4ac1ff,0xff3ab9ff,0xff6dcdff,0xff39b9ff,0xff5bc6ff,0xff5ac6ff,0xff5ac6ff,0xff48bdff,0xff59c5ff,0xff58c5ff,0xff58c5ff,
+ 0xff36b5ff,0xff35b4ff,0xff34b4ff,0xff34b4ff,0xff57c2ff,0xff56c1ff,0xff67c8ff,0xff33b2ff,0xff42baff,0xff54c1ff,0xff31b2ff,0xff66c7ff,0xff53c0ff,0xff53c0ff,
+ 0xff40b8ff,0xff51bfff,0xff51bfff,0xff40b8ff,0xff51bdff,0xff50bdff,0xff50bdff,0xff3db7ff,0xff61c5ff,0xff4fbdff,0xff2bacff,0xff4dbcff,0xff4dbbff,0xff4cbbff,
+ 0xff4cbbff,0xff4cbbff,0xff4bbbff,0xff39b2ff,0xff4bbaff,0xff27aaff,0xff4ab9ff,0xff26a8ff,0xff26a9ff,0xff25a8ff,0xff24a7ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,
+ 0xff24a7ff,0xff23a5ff,0xff47b7ff,0xff22a4ff,0xff5abfff,0xff46b5ff,0xff45b4ff,0xff32acff,0xff45b4ff,0xff44b4ff,0xff31abff,0xff43b3ff,0xff43b3ff,0xff42b3ff,
+ 0xff2fabff,0xff41b3ff,0xff41b2ff,0xff2ea9ff,0xff1ba0ff,0xff41b1ff,0xff1ba0ff,0xff2eaaff,0xff41b3ff,0xff41b2ff,0xff42b3ff,0xff42b3ff,0xff42b3ff,0xff43b3ff,
+ 0xff4fc9ff,0xff73d6ff,0xff73d6ff,0xff74d6ff,0xff51cbff,0xff76d6ff,0xff76d6ff,0xff76d7ff,0xff87dcff,0xff76d6ff,0xff54cdff,0xff77d8ff,0xff78d6fe,0xff7ad8ff,
+ 0xff7ad9ff,0xff59cffe,0xff7cd9fe,0xff5dd0fe,0xff60d1fe,0xff62d2fe,0xff85dbfe,0xff69d3fe,0xff6dd4fe,0xff70d5fe,0xff90dffe,0xff77d7fe,0xff7ad8fe,0xff7ad6fd,
+ 0xff7ad8fe,0xff77d7fe,0xff74d6fe,0xff71d4fe,0xff8bdcfe,0xff6cd3fe,0xff6bd2fe,0xff6bd1fe,0xff88dafe,0xff6ad1fe,0xff85d9fd,0xff66d0fe,0xff81d7fd,0xff5ecdfe,
+ 0xff5accfe,0xff88dafe,0xff75d4fe,0xff83d9fe,0xff71d3ff,0xff4bc7ff,0xff4bc7ff,0xff5cccff,0xff4ac6ff,0xff6dd1ff,0xff48c5ff,0xff6cd1ff,0xff47c5ff,0xff47c5ff,
+ 0xff6cd0ff,0xff6bd0ff,0xff45c3ff,0xff6acfff,0xff45c3ff,0xff43c3ff,0xff44c2ff,0xff43c2ff,0xff68cdff,0xff42c2ff,0xff67cdff,0xff40c0ff,0xff41c0ff,0xff66cdff,
+ 0xff3fbfff,0xff66cdff,0xff3ebfff,0xff51c5ff,0xff64ccff,0xff64cbff,0xff63cbff,0xff63cbff,0xff63cbff,0xff3abdff,0xff3abcff,0xff3abcff,0xff61caff,0xff38bcff,
+ 0xff38bbff,0xff60c9ff,0xff37baff,0xff5ec8ff,0xff5ec8ff,0xff36baff,0xff35b9ff,0xff49c0ff,0xff5dc7ff,0xff33b9ff,0xff5cc6ff,0xff32b7ff,0xff31b7ff,0xff32b7ff,
+ 0xff31b7ff,0xff30b7ff,0xff30b7ff,0xff2fb6ff,0xff2eb6ff,0xff43bcff,0xff43bcff,0xff2eb5ff,0xff57c4ff,0xff2cb4ff,0xff56c2ff,0xff56c2ff,0xff2ab3ff,0xff2ab2ff,
+ 0xff54c2ff,0xff54c1ff,0xff54c1ff,0xff53c1ff,0xff53c1ff,0xff52c1ff,0xff52c0ff,0xff52c0ff,0xff25b0ff,0xff51bfff,0xff25b0ff,0xff52c0ff,0xff26b1ff,0xff27b1ff,
+ 0xff53c1ff,0xff3eb9ff,0xff54c1ff,0xff69c9ff,0xff3fbdff,0xff60ccff,0xff60cbff,0xff61ccff,0xff62ccff,0xff41bfff,0xff42c0ff,0xff63ccff,0xff63cdff,0xff53c7ff,
+ 0xff53c8ff,0xff65cdff,0xff45c1fe,0xff47c3ff,0xff57c9fe,0xff4bc3fe,0xff6dd0fe,0xff51c6fe,0xff55c9fe,0xff76d3fe,0xff5fccfe,0xff64ccfe,0xff6acefe,0xff6fcffd,
+ 0xff8edbfe,0xff7bd3fe,0xff88d8fe,0xffa0e1fe,0xff7dd3fe,0xff7bd2fe,0xff77d1fd,0xff72cffd,0xff88d7fe,0xff6dcefe,0xff6ccdfe,0xff6ccdfe,0xff84d6fe,0xff6bcdfe,
+ 0xff82d6fe,0xff66c9fe,0xff7bd3fe,0xff5bc5fe,0xff62c8fe,0xff6dcdfe,0xff49bffe,0xff53c3fe,0xff60c8fe,0xff3ebafe,0xff3bbafe,0xff3bbaff,0xff3ab9ff,0xff5bc6ff,
+ 0xff3ab9ff,0xff5ac6ff,0xff39b8ff,0xff38b7ff,0xff5ac5ff,0xff59c3ff,0xff58c5ff,0xff35b5ff,0xff35b5ff,0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff56c1ff,0xff33b3ff,
+ 0xff67c8ff,0xff33b3ff,0xff32b2ff,0xff54c1ff,0xff32b1ff,0xff53c0ff,0xff31b1ff,0xff30b1ff,0xff52bfff,0xff2eb0ff,0xff2eaeff,0xff3fb8ff,0xff51bdff,0xff2eaeff,
+ 0xff3eb7ff,0xff2cadff,0xff4fbdff,0xff2cadff,0xff3cb4ff,0xff4ebcff,0xff2aacff,0xff4cbcff,0xff4cbbff,0xff29aaff,0xff28aaff,0xff28aaff,0xff4bbaff,0xff4bbaff,
+ 0xff5dc2ff,0xff26a9ff,0xff25a8ff,0xff26a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff48b8ff,0xff23a5ff,0xff22a5ff,0xff46b7ff,0xff21a4ff,
+ 0xff46b5ff,0xff45b5ff,0xff20a3ff,0xff20a2ff,0xff44b3ff,0xff43b3ff,0xff42b3ff,0xff42b3ff,0xff41b3ff,0xff1da0ff,0xff1ca0ff,0xff2ea9ff,0xff2ea9ff,0xff2ea9ff,
+ 0xff1ca0ff,0xff41b2ff,0xff1ca0ff,0xff2fa9ff,0xff42b3ff,0xff42b3ff,0xff1ea1ff,0xff43b3ff,0xff4fcaff,0xff62cfff,0xff50cbff,0xff63d0ff,0xff51cbff,0xff75d6ff,
+ 0xff75d6ff,0xff64d1ff,0xff65d2ff,0xff55cdff,0xff66d1fe,0xff56cefe,0xff79d7fe,0xff7bd8fe,0xff5dcffe,0xff5fd0fe,0xff83dbfe,0xff67d3fe,0xff7bd7fd,0xff8fdefe,
+ 0xff93dffd,0xff8cddfe,0xff86dbfe,0xff8cddfe,0xffa9e5fe,0xff98e0fd,0xff9ce1fe,0xffa6e4fd,0xff9ce1fe,0xff99e0fe,0xff93ddfd,0xff90ddfe,0xff98e0fe,0xffa1e2fe,
+ 0xffa0e2fe,0xff94ddfe,0xff94defe,0xff87dafd,0xff92ddfe,0xff82d9fe,0xff7dd6fe,0xff91dcfd,0xff6ed1fe,0xff76d4fe,0xff7fd7fe,0xff6ad0fe,0xff65cffe,0xff50c8fe,
+ 0xff4fc7ff,0xff4bc7fe,0xff5ccdff,0xff6ed1ff,0xff6dd1ff,0xff5accff,0xff48c5ff,0xff47c4ff,0xff5acaff,0xff6bcfff,0xff6bcfff,0xff6ad0ff,0xff44c3ff,0xff44c3ff,
+ 0xff43c2ff,0xff42c2ff,0xff55c7ff,0xff68cdff,0xff54c7ff,0xff41c1ff,0xff66cdff,0xff66cdff,0xff52c5ff,0xff51c5ff,0xff3fbfff,0xff3ebfff,0xff3dbeff,0xff63cbff,
+ 0xff63cbff,0xff3bbdff,0xff4fc4ff,0xff62caff,0xff4ec4ff,0xff39bcff,0xff39bcff,0xff61caff,0xff38bbff,0xff4cc2ff,0xff5fc9ff,0xff4ac1ff,0xff4ac1ff,0xff35b9ff,
+ 0xff35b9ff,0xff34b9ff,0xff47bfff,0xff34b8ff,0xff5cc6ff,0xff33b8ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff30b6ff,0xff2fb6ff,0xff44bdff,0xff43bcff,
+ 0xff2eb5ff,0xff2eb4ff,0xff42bcff,0xff2cb4ff,0xff41bbff,0xff2bb4ff,0xff56c2ff,0xff55c1ff,0xff2ab2ff,0xff3fbaff,0xff29b1ff,0xff3eb9ff,0xff28b1ff,0xff52c1ff,
+ 0xff52c0ff,0xff26b0ff,0xff51bfff,0xff25b0ff,0xff26b0ff,0xff26b1ff,0xff52c1ff,0xff3eb9ff,0xff3eb9ff,0xff3ebaff,0xff53c1ff,0xff54c1ff,0xff3fbdff,0xff40bfff,
+ 0xff40bfff,0xff41bfff,0xff41bfff,0xff42bfff,0xff41bfff,0xff42bffe,0xff44c0ff,0xff44c1ff,0xff46c1fe,0xff48c2ff,0xff4bc2fe,0xff4dc4fe,0xff51c5fe,0xff56c8fe,
+ 0xff78d4fe,0xff7dd4fd,0xff69cffe,0xff72d1fe,0xff7ad3fe,0xff82d5fd,0xff95dbfd,0xffa7e2fe,0xffa5e1fe,0xffa3e0fe,0xffa7e1fe,0xffa8e1fe,0xffa7e1fe,0xffa3dffd,
+ 0xff9edefe,0xff99dbfd,0xff95dbfe,0xff93dafe,0xff92d9fe,0xff92dafe,0xff92d8fd,0xff92d8fd,0xff90d8fe,0xff8ad5fd,0xff83d2fd,0xff79cffd,0xff6fccfd,0xff65c8fe,
+ 0xff5bc5fe,0xff53c1fe,0xff4cbffe,0xff46bdfe,0xff41bbff,0xff3ebafe,0xff3cbaff,0xff3bb8fe,0xff39b7fe,0xff39b8ff,0xff39b8ff,0xff38b8ff,0xff37b7ff,0xff48bdff,
+ 0xff58c5ff,0xff47bcff,0xff35b5ff,0xff34b4ff,0xff34b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff33b2ff,0xff33b2ff,0xff31b2ff,0xff32b1ff,0xff31b2ff,
+ 0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2cadff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2aacff,
+ 0xff2aacff,0xff29abff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff38b1ff,0xff4ab9ff,0xff38b1ff,0xff26a9ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,
+ 0xff24a7ff,0xff24a5ff,0xff34adff,0xff23a5ff,0xff23a5ff,0xff23a4ff,0xff22a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,
+ 0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca0ff,0xff2ea9ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,
+ 0xff1fa2ff,0xff20a2ff,0xff50caff,0xff50cbff,0xff50caff,0xff51cbff,0xff51cbff,0xff52cbff,0xff53ccff,0xff53cbfe,0xff55cdff,0xff57ceff,0xff5acfff,0xff5ccffe,
+ 0xff5fd0fe,0xff64d1fe,0xff6ad4fe,0xff6fd4fe,0xff91defd,0xff97e1fe,0xff85dcfe,0xff8edefe,0xff96dffd,0xff9fe2fd,0xffb0e7fd,0xffc0ebfd,0xffbfecfe,0xffbdebfe,
+ 0xffd3d6ac,0xfff6b41e,0xffffae00,0xffb9d3cc,0xffb3e1f5,0xffb3e6fc,0xffb1e6fd,0xffafe5fd,0xffaee5fd,0xffaee5fd,0xffafe5fd,0xffbbd9cc,0xffaeddea,0xffa5e1fb,
+ 0xff9fe0fd,0xff96defe,0xff8adafd,0xff7fd8fe,0xff73d3fd,0xff6bd1fe,0xff62cefe,0xff5acbfe,0xff55cafe,0xff50c8fe,0xff4dc7ff,0xff4bc7ff,0xff49c4fe,0xff48c4fe,
+ 0xff47c4ff,0xff47c5ff,0xff47c4ff,0xff46c4ff,0xff45c4ff,0xff44c3ff,0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff42c2ff,0xff42c1ff,0xff42c2ff,0xff42c1ff,0xff40c1ff,
+ 0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3fc0ff,0xff3fbfff,0xff3ebeff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3bbeff,0xff3bbcff,0xff3abcff,0xff3abcff,
+ 0xff39bcff,0xff38bbff,0xff38bbff,0xff38bbff,0xff37bbff,0xff36bbff,0xff36baff,0xff35baff,0xff35baff,0xff35b9ff,0xff34b8ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,
+ 0xff32b7ff,0xff32b8ff,0xff31b7ff,0xff30b7ff,0xff2fb7ff,0xff2fb5ff,0xff2eb6ff,0xff2eb5ff,0xff2eb4ff,0xff2eb5ff,0xff2db4ff,0xff2cb4ff,0xff2bb4ff,0xff2cb3ff,
+ 0xff2bb3ff,0xff2ab2ff,0xff2ab3ff,0xff29b2ff,0xff3eb9ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff25b0ff,0xff26b0ff,
+ 0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff28b2ff,0xff3fbaff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff40bfff,0xff41bfff,0xff41bfff,0xff42bfff,0xff43c0ff,0xff44c0fe,
+ 0xff67ceff,0xff4ac1fe,0xff4dc4ff,0xff52c5fe,0xff58c7fe,0xff5dc8fd,0xff66ccfe,0xff6ecffe,0xff8ddafd,0xff7fd5fd,0xff94dcfd,0xffa6e1fd,0xffafe4fd,0xffb0e4fd,
+ 0xffb2e4fd,0xffbbe7fc,0xffd9ddbc,0xfff0bb3d,0xffffae00,0xffffcc2a,0xffffb80e,0xffdfaf3c,0xffadcdde,0xffbce3f7,0xffc9ecfe,0xffbbe6fc,0xffbbe7fe,0xffc7ecfe,
+ 0xffd4ce9c,0xfffba700,0xffefa91c,0xffb3c8bc,0xffb3dff6,0xff9edcfd,0xff92d8fd,0xff99dcfe,0xff76cffe,0xff6acafe,0xff5ec6fe,0xff54c1fd,0xff6acafe,0xff46bdfe,
+ 0xff41bbfe,0xff3ebafe,0xff3bb8fe,0xff3bb9ff,0xff39b8ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,0xff36b7ff,0xff35b5ff,0xff35b5ff,0xff58c3ff,0xff34b4ff,0xff33b4ff,
+ 0xff33b3ff,0xff33b4ff,0xff33b3ff,0xff32b2ff,0xff33b3ff,0xff32b2ff,0xff31b1ff,0xff53c0ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb1ff,0xff2eaeff,0xff2eb0ff,
+ 0xff2eaeff,0xff2eaeff,0xff2dadff,0xff2cadff,0xff2bacff,0xff2cadff,0xff4ebcff,0xff2bacff,0xff2aabff,0xff29abff,0xff29abff,0xff28aaff,0xff28aaff,0xff28aaff,
+ 0xff28a9ff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff49b8ff,0xff48b8ff,0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff22a5ff,
+ 0xff21a5ff,0xff21a4ff,0xff21a3ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff31abff,0xff30abff,0xff1ea1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,
+ 0xff1ca0ff,0xff55baff,0xff1c9fff,0xff1ca0ff,0xff2ea9ff,0xff41b3ff,0xff1da1ff,0xff1ea1ff,0xff43b3ff,0xff1fa2ff,0xff50c9ff,0xff62cfff,0xff62d0ff,0xff62d0ff,
+ 0xff52cbff,0xff76d6ff,0xff77d6fe,0xff57cdfe,0xff7bd7fe,0xff5ecefe,0xff73d5fe,0xff69d3fe,0xff8cdbfd,0xff92defd,0xff80d8fd,0xff89dcfd,0xffa7e5fd,0xff9de2fe,
+ 0xffaee7fd,0xffafe7fd,0xffb9eafe,0xffcef0fe,0xffd0e6dd,0xffefc04d,0xffffae00,0xffffc21f,0xfffff061,0xffffff70,0xffffea50,0xffffae00,0xffbdb791,0xffc5dfea,
+ 0xffd9f0fa,0xffdaf2fd,0xffd1f0fd,0xffe6d59c,0xfffba700,0xfffbc73a,0xfff9b31c,0xffefa10c,0xffc1c5b1,0xffbee2f2,0xfface4fd,0xffb1e5fd,0xffa7e3fe,0xff90dbfd,
+ 0xff77d5fe,0xff7bd5fe,0xff72d3fe,0xff5bcbfe,0xff66cfff,0xff74d3ff,0xff5ecbfe,0xff4bc6ff,0xff6ed1ff,0xff5bcaff,0xff59caff,0xff45c4ff,0xff45c3ff,0xff45c3ff,
+ 0xff57c9ff,0xff7cd4ff,0xff69ceff,0xff43c2ff,0xff55c8ff,0xff67cdff,0xff54c7ff,0xff40c1ff,0xff40c0ff,0xff40c0ff,0xff3fbfff,0xff65ccff,0xff65cdff,0xff50c5ff,
+ 0xff3dbeff,0xff64cbff,0xff63cbff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff3abdff,0xff3abcff,0xff61caff,0xff4dc3ff,0xff60c9ff,0xff4bc2ff,0xff5fc9ff,0xff4ac1ff,
+ 0xff4ac1ff,0xff49c0ff,0xff5ec8ff,0xff35b9ff,0xff48c0ff,0xff5cc7ff,0xff47bfff,0xff33b8ff,0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff30b7ff,0xff59c5ff,0xff2fb6ff,
+ 0xff2eb5ff,0xff58c4ff,0xff57c4ff,0xff2db4ff,0xff41bcff,0xff57c3ff,0xff40bbff,0xff2cb4ff,0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff28b1ff,
+ 0xff28b1ff,0xff53c1ff,0xff52c0ff,0xff26b0ff,0xff26b0ff,0xff51bfff,0xff25afff,0xff26b0ff,0xff27b1ff,0xff52c1ff,0xff27b1ff,0xff28b1ff,0xff3fbaff,0xff29b2ff,
+ 0xff3fbdff,0xff60cbff,0xff60ccff,0xff61cbfe,0xff51c5fe,0xff43c0ff,0xff45c1ff,0xff69cdfe,0xff6ccefe,0xff71d1fe,0xff5dc8fe,0xff7fd6fe,0xff6ecefe,0xff79d2fe,
+ 0xff99ddfd,0xff8fd9fd,0xffabe3fd,0xffa5e0fd,0xffb0e4fd,0xffbae7fc,0xffd1eaed,0xffe7c76d,0xffffae00,0xffffb812,0xffffeb64,0xffffff7e,0xffffff76,0xffffff6f,
+ 0xfffffe69,0xffffc119,0xffe6ac2b,0xffbccdd5,0xffdbecf4,0xffdef3fd,0xffe8d59c,0xfffba700,0xfffbc73c,0xffffff97,0xfffef983,0xfff8c131,0xffeb9a0b,0xffc1b485,
+ 0xffadd8ef,0xffbde7fc,0xff99dafe,0xff9ddcfd,0xff7ad0fe,0xff6ccafd,0xff7cd1fe,0xff56c2fe,0xff7bd2fe,0xff47bdfe,0xff62c8fe,0xff60c8ff,0xff3cb9ff,0xff5bc6ff,
+ 0xff39b7ff,0xff37b5ff,0xff37b5ff,0xff36b5ff,0xff35b5ff,0xff58c3ff,0xff34b5ff,0xff34b3ff,0xff56c2ff,0xff33b3ff,0xff55c1ff,0xff32b3ff,0xff32b2ff,0xff31b2ff,
+ 0xff31b2ff,0xff65c7ff,0xff30b1ff,0xff52bfff,0xff52bfff,0xff2fb0ff,0xff2eb0ff,0xff51bdff,0xff2eb0ff,0xff2eaeff,0xff2daeff,0xff4fbdff,0xff2cadff,0xff3db5ff,
+ 0xff4ebcff,0xff4ebcff,0xff2aacff,0xff4dbbff,0xff4cbbff,0xff3ab2ff,0xff28aaff,0xff4bbaff,0xff4ab9ff,0xff28a9ff,0xff49b9ff,0xff26a8ff,0xff26a9ff,0xff26a9ff,
+ 0xff25a7ff,0xff49b8ff,0xff5bc0ff,0xff36aeff,0xff48b7ff,0xff23a5ff,0xff22a5ff,0xff46b7ff,0xff5abfff,0xff22a4ff,0xff45b5ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,
+ 0xff1fa3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff2faaff,0xff1da1ff,0xff1da1ff,0xff41b2ff,0xff1ca0ff,0xff41b2ff,0xff1ca0ff,0xff1ca0ff,0xff1ca1ff,0xff41b3ff,
+ 0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff20a2ff,0xff4fcaff,0xff73d5ff,0xff74d5ff,0xff75d6ff,0xff65d1ff,0xff77d6fe,0xff7ad8ff,0xff7ed9fe,0xff92ddfe,0xff88dcfe,
+ 0xff74d5fe,0xff98e1fe,0xffa1e3fe,0xffaae6fe,0xffa9e4fd,0xffaae5fd,0xffc3ecfd,0xffbfecfe,0xffcbeaee,0xffe8cd7b,0xfffbb00f,0xffffb813,0xffffe15d,0xffffff8d,
+ 0xffffff84,0xffffff7c,0xffffff74,0xffffff6d,0xfffffd68,0xffffeb50,0xffffae00,0xffcab682,0xffd9e3e7,0xffeed79b,0xfffaa700,0xfffbc73d,0xffffff9c,0xffffff90,
+ 0xffffff85,0xffffff7a,0xfff6be2a,0xffee9400,0xffc1b182,0xffbedeec,0xffafe3fa,0xffb5e6fd,0xff95defe,0xff86d8fd,0xff94dbfd,0xff6ed0fd,0xff84d7fe,0xff5ccbfe,
+ 0xff78d3fe,0xff61ccfe,0xff70d2ff,0xff6dd2ff,0xff47c4ff,0xff47c3ff,0xff46c4ff,0xff45c3ff,0xff44c3ff,0xff6acfff,0xff43c2ff,0xff43c2ff,0xff69ceff,0xff41c2ff,
+ 0xff67cdff,0xff41c0ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff65ccff,0xff3ebfff,0xff65cbff,0xff64cbff,0xff64cbff,0xff63caff,0xff4fc5ff,0xff3bbdff,0xff3abdff,
+ 0xff3abdff,0xff61caff,0xff39bcff,0xff39bcff,0xff60caff,0xff60c9ff,0xff37bbff,0xff5ec8ff,0xff5ec8ff,0xff36baff,0xff35baff,0xff5dc7ff,0xff71cdff,0xff5cc7ff,
+ 0xff5cc6ff,0xff32b8ff,0xff32b7ff,0xff31b8ff,0xff31b7ff,0xff30b7ff,0xff5ac5ff,0xff2fb6ff,0xff59c4ff,0xff2eb6ff,0xff2eb5ff,0xff57c4ff,0xff57c3ff,0xff2cb4ff,
+ 0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff3db9ff,0xff52c1ff,0xff52c1ff,0xff52c0ff,0xff26b0ff,0xff51c0ff,
+ 0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff52c1ff,0xff27b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff60cbff,0xff51c3ff,0xff62ccff,0xff54c6ff,0xff68ceff,
+ 0xff6ccefe,0xff71d0fe,0xff78d3fe,0xff67ccfe,0xff8bd9fe,0xff8bd9fe,0xffa1e0fd,0xfface3fd,0xffb0e5fe,0xffb4e5fd,0xffcaedfd,0xffdcd49d,0xfff8b51e,0xffffb30b,
+ 0xffffd752,0xfffffa92,0xffffff94,0xffffff8b,0xffffff83,0xffffff7b,0xffffff73,0xffffff6c,0xfffffc66,0xfffff861,0xffffc923,0xfff2ac15,0xffdbbf81,0xfffaa700,
+ 0xfffbc73f,0xffffffa1,0xffffff95,0xffffff89,0xffffff7e,0xffffff74,0xfffffe6b,0xfff7cc38,0xffeb8f00,0xffcda25a,0xffaed5ea,0xffb8e3fa,0xff9edcfe,0xffa0ddfd,
+ 0xff9eddfd,0xff7bd0fe,0xff7dd1fe,0xff58c3fe,0xff6ccbfe,0xff56c3fe,0xff61c8fe,0xff5fc8ff,0xff3bb8ff,0xff39b8ff,0xff38b7ff,0xff35b5ff,0xff36b5ff,0xff46bbff,
+ 0xff57c2ff,0xff44bbff,0xff56c2ff,0xff56c1ff,0xff56c1ff,0xff33b2ff,0xff33b2ff,0xff32b2ff,0xff31b2ff,0xff66c8ff,0xff53c0ff,0xff53c0ff,0xff40b8ff,0xff52bfff,
+ 0xff51bfff,0xff3fb8ff,0xff2eb0ff,0xff2eadff,0xff2dadff,0xff3db5ff,0xff4fbdff,0xff4ebcff,0xff4dbdff,0xff4ebcff,0xff4dbcff,0xff4cbcff,0xff4cbbff,0xff29abff,
+ 0xff28abff,0xff4bbaff,0xff4bb9ff,0xff4abaff,0xff4ab9ff,0xff26a9ff,0xff26a9ff,0xff25a8ff,0xff25a7ff,0xff24a7ff,0xff49b8ff,0xff24a7ff,0xff35aeff,0xff47b7ff,
+ 0xff47b7ff,0xff33adff,0xff46b5ff,0xff21a4ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea2ff,0xff1ea1ff,0xff30aaff,0xff42b3ff,
+ 0xff41b2ff,0xff41b3ff,0xff2ea9ff,0xff55bbff,0xff41b2ff,0xff1ca1ff,0xff41b2ff,0xff56bbff,0xff2faaff,0xff1ea1ff,0xff1fa1ff,0xff1fa2ff,0xff50caff,0xff51caff,
+ 0xff51cbff,0xff54ccff,0xff55ccfe,0xff5acefe,0xff61cffe,0xff68d2fe,0xff73d5fe,0xff7fd9fe,0xff8cdcfd,0xff9ae0fe,0xffa7e4fd,0xffb4e8fd,0xffc0ebfc,0xffd6ddbc,
+ 0xfff9b51e,0xffffae00,0xffffd14f,0xfffffaa2,0xffffffa4,0xffffff9b,0xffffff92,0xffffff8a,0xffffff81,0xffffff79,0xffffff72,0xffffff6b,0xfffffb65,0xfffff760,
+ 0xffffea4f,0xfffca900,0xfffaa700,0xfffbc741,0xffffffa6,0xffffff9a,0xffffff8e,0xffffff83,0xffffff78,0xffffff6e,0xfffffc66,0xfffff65f,0xfff7cb37,0xffe78900,
+ 0xffcc9a4b,0xffb2d7e8,0xffb1e3f8,0xffa6e2fd,0xff97ddfd,0xff89d9fe,0xff7bd5fe,0xff6ed0fe,0xff63cdfe,0xff6bd1ff,0xff76d3fe,0xff72d2ff,0xff5dcbff,0xff48c5ff,
+ 0xff46c4ff,0xff45c3ff,0xff44c3ff,0xff43c3ff,0xff43c2ff,0xff43c2ff,0xff43c2ff,0xff42c2ff,0xff42c1ff,0xff40c1ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3ebfff,
+ 0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbfff,0xff3cbeff,0xff3bbeff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff39bdff,0xff39bcff,0xff39bcff,0xff38bbff,0xff38bbff,
+ 0xff37bbff,0xff37baff,0xff35baff,0xff36b9ff,0xff35b9ff,0xff35b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff30b7ff,0xff30b6ff,
+ 0xff30b6ff,0xff30b6ff,0xff2fb6ff,0xff2eb6ff,0xff2db5ff,0xff2db5ff,0xff2db5ff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,0xff2ab3ff,0xff2ab2ff,0xff29b2ff,
+ 0xff29b2ff,0xff28b2ff,0xff28b1ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff26b0ff,0xff25afff,0xff26b0ff,0xff26b1ff,0xff27b1ff,0xff27b1ff,0xff27b1ff,0xff28b2ff,
+ 0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff41bdff,0xff43c0ff,0xff45c0fe,0xff49c1fe,0xff4fc5ff,0xff57c6fe,0xff62cafe,0xff6ecffe,0xff7dd3fd,0xff8ed8fd,0xff9edefd,
+ 0xffafe4fe,0xffc8dbcc,0xfff0bc3d,0xffffae00,0xffffc73d,0xfffff5a5,0xffffffb4,0xffffffab,0xffffffa2,0xffffff99,0xffffff90,0xffffff88,0xffffff80,0xffffff78,
+ 0xffffff70,0xfffffe6a,0xfffffb64,0xffffe447,0xfffdb711,0xfffaa700,0xfff9a400,0xfffbd660,0xffffff9e,0xffffff93,0xffffff87,0xffffff7c,0xffffff72,0xfffffe69,
+ 0xfffff962,0xfffff35b,0xffffed53,0xfff9cf39,0xffe58904,0xffd18d31,0xffafccd7,0xffabdcf7,0xff9fdbfd,0xff8ed6fd,0xff7ed1fe,0xff70cbfe,0xff61c6fe,0xff55c2fe,
+ 0xff4cbfff,0xff44bcff,0xff3ebaff,0xff3bb8ff,0xff39b8ff,0xff37b5ff,0xff35b5ff,0xff35b5ff,0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b4ff,0xff33b3ff,0xff32b3ff,
+ 0xff32b3ff,0xff32b2ff,0xff31b1ff,0xff30b2ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2daeff,0xff2dadff,0xff2cadff,
+ 0xff2cadff,0xff2cadff,0xff2badff,0xff2aacff,0xff2aacff,0xff29abff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff28a9ff,0xff27a9ff,0xff26a9ff,
+ 0xff26a9ff,0xff25a9ff,0xff24a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff20a3ff,0xff21a3ff,
+ 0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1da0ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,0xff1ca0ff,0xff1ca0ff,
+ 0xff1da0ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff51caff,0xff53cbff,0xff58cbfe,0xff5dceff,0xff64d0ff,0xff6dd4ff,0xff78d6fe,
+ 0xff91defe,0xff94defd,0xffa4e3fe,0xffb9e4ee,0xffe6c35c,0xffffae00,0xffffc235,0xffffeb9a,0xffffffc5,0xffffffbb,0xffffffb2,0xffffffa9,0xffffffa0,0xffffff97,
+ 0xffffff8f,0xffffff86,0xffffff7e,0xffffff76,0xffffff6f,0xffffef55,0xfffec019,0xfffca900,0xfffcb712,0xfffee144,0xfffcaf09,0xfff59f00,0xfff8c138,0xffffff8c,
+ 0xffffff81,0xffffff76,0xffffff6d,0xfffffb65,0xfffff55e,0xfffff056,0xffffea4f,0xffffe448,0xfffacd35,0xffe28304,0xffd28624,0xffb1ccd4,0xffb8e4f8,0xffa6e2fd,
+ 0xff97ddfd,0xff87d8fe,0xff78d3fe,0xff6acffe,0xff5eccfe,0xff56c9fe,0xff50c7ff,0xff4ac6ff,0xff47c3fe,0xff45c2fe,0xff45c3ff,0xff44c2ff,0xff43c2ff,0xff55c8ff,
+ 0xff43c1ff,0xff55c7ff,0xff41c1ff,0xff41c1ff,0xff41c0ff,0xff40c0ff,0xff3fbfff,0xff3ebfff,0xff3fc0ff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,
+ 0xff3bbdff,0xff4ec4ff,0xff3abdff,0xff3abcff,0xff39bcff,0xff38bbff,0xff38bbff,0xff37bbff,0xff37bbff,0xff37baff,0xff36baff,0xff35baff,0xff35baff,0xff34b9ff,
+ 0xff34b8ff,0xff33b9ff,0xff33b8ff,0xff32b8ff,0xff47bfff,0xff47bfff,0xff30b7ff,0xff30b7ff,0xff30b6ff,0xff5ac5ff,0xff44bdff,0xff2eb5ff,0xff2eb4ff,0xff2db5ff,
+ 0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,0xff2ab2ff,0xff29b3ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff27b1ff,0xff27b0ff,0xff27b0ff,0xff52c1ff,
+ 0xff25b0ff,0xff25afff,0xff3cb8ff,0xff26b1ff,0xff27b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff41bdff,0xff43beff,0xff45c0fe,0xff4ac1fe,
+ 0xff51c5ff,0xff5ac8ff,0xff66cafe,0xff74d0fe,0xff99dcfd,0xff96dbfd,0xffaae2fe,0xffd7cb8b,0xffffae00,0xffffe18b,0xffffffd6,0xffffffcc,0xffffffc3,0xffffffba,
+ 0xffffffb0,0xffffffa7,0xffffff9e,0xffffff96,0xffffff8d,0xffffff84,0xffffff7d,0xfffff566,0xffffcc29,0xfffeac00,0xfffdb710,0xfffed334,0xffffe74b,0xffffec51,
+ 0xffffbb14,0xfffbb10e,0xfff29900,0xfff6be32,0xfffef873,0xffffff70,0xfffffd68,0xfffff861,0xfffff259,0xffffec52,0xffffe64b,0xffffe143,0xffffdb3c,0xfffbca2e,
+ 0xffe38909,0xffd27c18,0xffb4bcb4,0xffa8d9f5,0xff9bdafc,0xff8bd5fe,0xff79cefe,0xff68c8fe,0xff5ac4ff,0xff4dbefe,0xff45bbfe,0xff3fbaff,0xff3ab8ff,0xff38b6ff,
+ 0xff37b5ff,0xff34b5ff,0xff34b4ff,0xff57c2ff,0xff33b3ff,0xff44bbff,0xff33b3ff,0xff33b2ff,0xff32b2ff,0xff32b2ff,0xff31b1ff,0xff30b2ff,0xff30b2ff,0xff2fb0ff,
+ 0xff2fb0ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff51bdff,0xff2daeff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2aacff,0xff2aacff,0xff29acff,
+ 0xff29abff,0xff28abff,0xff28aaff,0xff28abff,0xff28a9ff,0xff28a9ff,0xff27a9ff,0xff26a9ff,0xff26a9ff,0xff37b1ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff48b8ff,
+ 0xff47b8ff,0xff23a5ff,0xff23a5ff,0xff22a5ff,0xff21a5ff,0xff21a4ff,0xff21a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff20a2ff,0xff1fa2ff,0xff1ea1ff,
+ 0xff1da1ff,0xff1da1ff,0xff41b2ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,0xff41b2ff,0xff1ca1ff,0xff1ca1ff,0xff1da1ff,0xff1da1ff,0xff1ea2ff,0xff1ea2ff,0xff1fa2ff,
+ 0xff50cafe,0xff75d5fe,0xff79d8ff,0xff7ed8ff,0xff74d4fe,0xff8cddff,0xff96dffe,0xff95dffe,0xffaee7fe,0xffb3e7fd,0xffc2ecfe,0xffcee6e7,0xfffab00e,0xffffd76e,
+ 0xffffffd4,0xffffffca,0xffffffc1,0xffffffb8,0xffffffaf,0xffffffa6,0xffffff9d,0xffffff94,0xffffff8b,0xfffffa7b,0xffffd73e,0xffffb307,0xfffeb207,0xfffec925,
+ 0xffffdf41,0xffffe448,0xffffea4f,0xffffef56,0xffffc01a,0xffffc21c,0xfffcbb19,0xffef9702,0xfff0a516,0xfffef764,0xfffffa64,0xfffff45c,0xffffef55,0xffffe94e,
+ 0xffffe346,0xffffdd3f,0xffffd838,0xffffd231,0xfffdc727,0xffe08307,0xffd4740c,0xffafb8b1,0xffc0e3f4,0xffb1e3fb,0xffa3e0fd,0xff89d9fe,0xff8adafe,0xff80d6ff,
+ 0xff68cfff,0xff4ec7ff,0xff4ac6ff,0xff47c4ff,0xff58c9ff,0xff6acfff,0xff6aceff,0xff69ceff,0xff42c2ff,0xff7ad3ff,0xff41c1ff,0xff67cdff,0xff66cdff,0xff66cdff,
+ 0xff52c5ff,0xff66ccff,0xff65ccff,0xff65ccff,0xff50c5ff,0xff64cbff,0xff63cbff,0xff50c5ff,0xff63caff,0xff76d0ff,0xff4ec4ff,0xff4ec3ff,0xff61caff,0xff60caff,
+ 0xff4cc3ff,0xff73cfff,0xff5fc9ff,0xff5ec8ff,0xff5ec8ff,0xff36baff,0xff35b9ff,0xff5ec7ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff31b8ff,
+ 0xff31b7ff,0xff30b6ff,0xff5ac5ff,0xff2fb5ff,0xff59c4ff,0xff58c4ff,0xff58c4ff,0xff42bcff,0xff57c3ff,0xff57c3ff,0xff57c2ff,0xff2bb3ff,0xff6acaff,0xff56c2ff,
+ 0xff3fbaff,0xff54c1ff,0xff54c1ff,0xff53c1ff,0xff28b1ff,0xff27b1ff,0xff52c1ff,0xff26b0ff,0xff51c0ff,0xff51c0ff,0xff67c8ff,0xff3cb8ff,0xff52c1ff,0xff52c1ff,
+ 0xff3db9ff,0xff53c1ff,0xff28b1ff,0xff54c1ff,0xff41bcfe,0xff64ccff,0xff69cfff,0xff6ed0fe,0xff5bc8fe,0xff82d6fe,0xff8fd9fe,0xff9ddefe,0xffb4e6fd,0xffbbe7fd,
+ 0xffbfe9fd,0xffd3ecf8,0xffddc98c,0xffffae00,0xfffff5b7,0xffffffc8,0xffffffbf,0xffffffb6,0xffffffad,0xffffffa4,0xffffff9b,0xffffff92,0xffffdc4e,0xffffb308,
+ 0xffffb003,0xffffc31c,0xffffd838,0xffffdd3e,0xffffe245,0xffffe84c,0xffffed53,0xfffff25a,0xffffc520,0xffffc722,0xffffc824,0xfffcbf1f,0xffec9203,0xffeda013,
+ 0xfffce953,0xfffff158,0xffffeb51,0xffffe549,0xffffe042,0xffffda3b,0xffffd433,0xffffcf2c,0xffffc925,0xfffdbe1c,0xffe28607,0xffcf6e0b,0xffb5a286,0xff9ad2f1,
+ 0xff9fdbfb,0xff90d8fe,0xff67c8fe,0xff74cefe,0xff4cbefe,0xff42bbfe,0xff3db7fe,0xff39b8ff,0xff59c3ff,0xff34b4ff,0xff34b4ff,0xff57c2ff,0xff33b4ff,0xff56c1ff,
+ 0xff33b3ff,0xff55c1ff,0xff32b2ff,0xff32b2ff,0xff41b9ff,0xff66c8ff,0xff53c0ff,0xff65c7ff,0xff52bfff,0xff2eb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff51bdff,
+ 0xff2dadff,0xff4fbdff,0xff2cadff,0xff2bacff,0xff4ebcff,0xff4dbcff,0xff2aabff,0xff3ab3ff,0xff4cbbff,0xff28aaff,0xff28aaff,0xff4bbaff,0xff28aaff,0xff27aaff,
+ 0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff49b8ff,0xff24a7ff,0xff48b8ff,0xff24a5ff,0xff23a5ff,0xff46b7ff,0xff46b5ff,0xff21a4ff,
+ 0xff46b4ff,0xff20a3ff,0xff45b4ff,0xff44b3ff,0xff43b3ff,0xff57bdff,0xff43b3ff,0xff56bbff,0xff1ea1ff,0xff2faaff,0xff2fa9ff,0xff1ca0ff,0xff41b2ff,0xff1ba0ff,
+ 0xff41b2ff,0xff1ca0ff,0xff41b3ff,0xff41b3ff,0xff42b3ff,0xff30aaff,0xff30aaff,0xff43b4ff,0xff52cbff,0xff78d6ff,0xff7dd8ff,0xff83daff,0xff8bdcfe,0xff7bd6fe,
+ 0xff89dbfe,0xffafe6fe,0xffbceafd,0xffc3ecfd,0xffd1f0fd,0xffe0f4fd,0xffdbebf2,0xfff7b019,0xffffcc4d,0xffffffc7,0xffffffbd,0xffffffb4,0xffffffab,0xffffffa2,
+ 0xffffe160,0xffffb812,0xffffae00,0xffffbd14,0xffffce2b,0xffffd535,0xffffdb3c,0xffffe042,0xffffe549,0xffffeb50,0xfffff057,0xfffff55e,0xffffca26,0xffffcb28,
+ 0xffffcd2a,0xffffcf2c,0xfffecc2b,0xffeb9609,0xffe78c06,0xfffad944,0xffffe84c,0xffffe245,0xffffdc3e,0xffffd736,0xfffed02e,0xfffeca27,0xfffec420,0xffffc019,
+ 0xffffba12,0xffe38504,0xffd06500,0xffa5a08f,0xffa6d7ee,0xff8ad7fc,0xffa1e0fe,0xff79d3fe,0xff5ccafe,0xff54c8ff,0xff4dc5fe,0xff48c4ff,0xff6bcfff,0xff44c2ff,
+ 0xff56c9ff,0xff69cdff,0xff42c2ff,0xff67cdff,0xff41c1ff,0xff67cdff,0xff40c1ff,0xff3fc0ff,0xff3fbfff,0xff65cdff,0xff3ebfff,0xff51c5ff,0xff64cbff,0xff3dbfff,
+ 0xff3cbeff,0xff4fc5ff,0xff3bbdff,0xff63caff,0xff4ec4ff,0xff61caff,0xff39bcff,0xff38bbfe,0xff60c8fe,0xff5fc8fe,0xff37b9fe,0xff37bafe,0xff4ac0fe,0xff5ec7fe,
+ 0xff5ec6fe,0xff5dc6fe,0xff34b8fe,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff31b7ff,0xff30b7ff,0xff45beff,0xff44bdff,0xff2fb6ff,0xff59c4ff,0xff2eb6ff,
+ 0xff2eb5ff,0xff57c3ff,0xff57c3ff,0xff2cb4ff,0xff57c2ff,0xff2bb3ff,0xff56c2ff,0xff55c1ff,0xff55c2ff,0xff54c1ff,0xff29b1ff,0xff3eb9ff,0xff27b1ff,0xff52c1ff,
+ 0xff27b1ff,0xff26b0ff,0xff52c0ff,0xff25afff,0xff67c8ff,0xff52c1ff,0xff27b1ff,0xff27b1ff,0xff52c1ff,0xff29b2ff,0xff54c1ff,0xff3fbaff,0xff44beff,0xff57c5ff,
+ 0xff4ec2ff,0xff65ccff,0xff63cbff,0xff8ad8fe,0xff9addfe,0xff9fdffe,0xffbfd9cc,0xffbbe5fa,0xffcfedfb,0xffdbf2fd,0xffe7f4fa,0xffe2d4ab,0xffffae00,0xffffeb93,
+ 0xffffffbb,0xffffffb2,0xffffeb7f,0xffffc229,0xffffae00,0xffffb70c,0xffffc621,0xffffce2b,0xffffd332,0xffffd939,0xffffde40,0xffffe347,0xffffe94d,0xffffee54,
+ 0xfffff35b,0xfffff962,0xffffce2c,0xffffd02e,0xffffd230,0xffffd332,0xffffd534,0xfffdd233,0xffe8930b,0xffe48705,0xfff6ca35,0xfffede40,0xfffed838,0xfffed231,
+ 0xfffdcb2a,0xfffdc622,0xfffdc01b,0xfffebb14,0xfffeb60c,0xffe08102,0xffc7640a,0xff8d9593,0xff91c4df,0xff99d7f8,0xff7fd0fd,0xff7dd1fe,0xff61c5fe,0xff48bdff,
+ 0xff3fbafe,0xff3bb6fe,0xff37b5fe,0xff58c1fe,0xff45bafe,0xff45bafe,0xff44bafe,0xff56c1fe,0xff55c0fe,0xff43baff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff41b8ff,
+ 0xff53c0ff,0xff41b8ff,0xff2fb1ff,0xff52bfff,0xff51bfff,0xff2eaeff,0xff2eaeff,0xff3fb5ff,0xff3eb5ff,0xff2dacfe,0xff4fbcfe,0xff4fbbfe,0xff2bacfe,0xff3bb3fd,
+ 0xff2aaafd,0xff29abfd,0xff3ab2fd,0xff29aafd,0xff28a9fd,0xff4bb9fe,0xff28a8fe,0xff28a9fe,0xff27a8fe,0xff26a9ff,0xff26a9ff,0xff25a8ff,0xff24a8ff,0xff49b8ff,
+ 0xff24a7ff,0xff24a7ff,0xff34adff,0xff24a5ff,0xff23a4ff,0xff33adff,0xff33adff,0xff46b5ff,0xff33adff,0xff20a3ff,0xff31acff,0xff20a2ff,0xff31acff,0xff31abff,
+ 0xff43b3ff,0xff31aaff,0xff30aaff,0xff2faaff,0xff1da1ff,0xff1ca0ff,0xff2ea9ff,0xff41b2ff,0xff2ea9ff,0xff1ca0ff,0xff41b2ff,0xff41b2ff,0xff30aaff,0xff1ea1ff,
+ 0xff31abff,0xff1fa2ff,0xff53cbff,0xff58ccff,0xff5dceff,0xff66d1fe,0xff72d4fe,0xff80d9fe,0xff91defe,0xffa3e3fe,0xffffae00,0xffffae00,0xffeeb839,0xffe9c467,
+ 0xffe6d6a2,0xffe3e0cd,0xfff2b535,0xffffc230,0xfffff5a3,0xffffc738,0xffffae00,0xffffb206,0xffffbe17,0xffffc722,0xffffcc29,0xffffd12f,0xffffd736,0xffffdc3d,
+ 0xffffe144,0xffffe74b,0xffffec51,0xfffff158,0xfffff65f,0xfffffc66,0xffffd332,0xffffd534,0xffffd636,0xffffd838,0xffffda3a,0xfffeda3b,0xfffedc3e,0xffeaa118,
+ 0xffdc7a00,0xfff0b425,0xfffdd334,0xfffdce2d,0xfffdc825,0xfffdc21e,0xfffdbd17,0xfffdb710,0xffdf8103,0xffc76409,0xff8f8a80,0xff8baab9,0xff97c9e0,0xff93d8f8,
+ 0xff9cdefd,0xff8dd9fd,0xff62ccfd,0xff59c9fe,0xff50c6fe,0xff4ac4fd,0xff46c2fd,0xff44c0fc,0xff43c0fd,0xff42c0fd,0xff42c0fd,0xff41bffd,0xff40bffd,0xff40befd,
+ 0xff40bffe,0xff40bffe,0xff3fbffe,0xff3ebffe,0xff3ebefe,0xff3ebefe,0xff3dbfff,0xff3cbdfe,0xff3cbdfe,0xff3cbcfe,0xff3bbcfe,0xff3abcfe,0xff3abcfd,0xff3abbfd,
+ 0xff39bbfd,0xff38bafd,0xff38bafd,0xff38bafd,0xff36b9fc,0xff36b8fc,0xff35b8fc,0xff5dc6fc,0xff5dc6fd,0xff34b8fd,0xff34b7fd,0xff33b8fd,0xff33b7fd,0xff33b7fd,
+ 0xff32b6fe,0xff31b6fe,0xff30b6fe,0xff45bdfe,0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2db5ff,0xff2cb4ff,0xff2cb3ff,0xff2bb3ff,
+ 0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff29b2ff,0xff3db9ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff25b0ff,0xff25afff,0xff25b0ff,0xff26b0ff,
+ 0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff44beff,0xff47bffe,0xff4fc2ff,0xff58c7ff,0xff64cbfe,0xff73cffe,0xff86d5fe,0xff99ddfe,
+ 0xffc5c694,0xffffae00,0xffffb310,0xffffc23c,0xffffae00,0xffffae00,0xffffae00,0xffffae00,0xffffae00,0xffffaf02,0xffffb70e,0xffffbf18,0xffffc51f,0xffffca26,
+ 0xffffcf2d,0xffffd434,0xffffda3a,0xffffdf41,0xffffe448,0xffffea4f,0xffffef56,0xfffff45c,0xfffffa63,0xfffffe6b,0xffffd838,0xffffda3a,0xffffdb3c,0xffffdd3e,
+ 0xfffedd3f,0xfffedf41,0xfffde044,0xfffde146,0xffe79f1b,0xffd77300,0xffeba61a,0xfffbc828,0xfffbc321,0xfffbbd1a,0xfffbb812,0xffdd8004,0xffc56309,0xff958b7e,
+ 0xff93a7b3,0xffa1c3d6,0xffa1d4f1,0xff92d5fa,0xff7ecefc,0xff6ac8fc,0xff5bc3fd,0xff4dbdfc,0xff44bbfd,0xff3db6fd,0xff39b4fc,0xff36b3fc,0xff34b2fc,0xff32b2fc,
+ 0xff32b1fc,0xff32b1fc,0xff32b1fc,0xff32b2fd,0xff32b2fd,0xff32b1fd,0xff31b1fd,0xff31b1fd,0xff30b0fd,0xff30b0fe,0xff2faffe,0xff2faffe,0xff2faffd,0xff2eadfd,
+ 0xff2eadfd,0xff2eadfd,0xff2dacfd,0xff2cabfc,0xff2babfc,0xff2aa9fb,0xff2aa9fb,0xff2aa9fa,0xff29a9fa,0xff28a8fa,0xff27a8fa,0xff27a8fa,0xff27a7fa,0xff27a7fb,
+ 0xff27a7fb,0xff27a7fc,0xff27a7fc,0xff26a8fd,0xff26a7fd,0xff26a7fd,0xff24a6fd,0xff25a6fd,0xff24a7fe,0xff24a6fe,0xff24a4fe,0xff23a6fe,0xff23a3fe,0xff22a4fe,
+ 0xff22a3fe,0xff21a3fe,0xff20a3fe,0xff20a3fe,0xff20a2fe,0xff20a2fe,0xff1fa1fe,0xff20a1fe,0xff1fa1fe,0xff1ea2ff,0xff1ea1ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,
+ 0xff1ba0ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1ea2ff,0xff20a3ff,0xff52cbff,0xff88dafe,0xff5dceff,0xff92ddfe,
+ 0xff70d4ff,0xff7cd8fe,0xff8ddcfe,0xff9de1fe,0xffb6e1f3,0xffc2ba82,0xfff8ad0b,0xffffcc57,0xfffffacc,0xfffff0a5,0xffffdc6a,0xffffc737,0xffffae00,0xffffb40a,
+ 0xffffbd16,0xffffc21c,0xffffc823,0xffffcd2a,0xffffd231,0xffffd838,0xffffdd3e,0xffffe245,0xffffe84c,0xffffed53,0xfffff25a,0xfffff860,0xfffffd67,0xffffff74,
+ 0xffffdd3e,0xffffde40,0xffffe042,0xfffee143,0xfffee245,0xfffde348,0xfffde44a,0xfffce54c,0xfffbe64d,0xffecba32,0xffd16c00,0xffdf8b0d,0xfff9be1d,0xfff8b715,
+ 0xffda8006,0xffc56209,0xff9b8d7d,0xff9eabb1,0xffb3c9d3,0xffbadeee,0xffb1e2f8,0xff9eddf9,0xff8ad6f9,0xff79d1fb,0xff69ccfa,0xff5cc7fa,0xff74cffa,0xff4cc2fa,
+ 0xff47c0fa,0xff45bef9,0xff67c9f9,0xff41bdf9,0xff40bdf9,0xff40bdf9,0xff40bdfa,0xff40bdfa,0xff3fbdfb,0xff3fbdfb,0xff3ebdfc,0xff3ebefc,0xff64cafc,0xff3ebefd,
+ 0xff3dbdfd,0xff3cbdfd,0xff3bbbfc,0xff3abcfc,0xff3abbfc,0xff39b9fb,0xff39b8fa,0xff38b9fa,0xff38b8f9,0xff38b8f9,0xff36b6f8,0xff35b5f7,0xff35b5f7,0xff34b4f7,
+ 0xff34b4f7,0xff34b3f7,0xff33b3f7,0xff34b4f8,0xff33b4f9,0xff32b4f9,0xff32b4f9,0xff32b4fa,0xff31b4fb,0xff30b5fc,0xff2fb5fc,0xff2fb4fc,0xff30b6fd,0xff2fb5fd,
+ 0xff2fb5fd,0xff2eb5fd,0xff2eb4fd,0xff2db3fd,0xff2db4fd,0xff2cb3fd,0xff2cb2fd,0xff2cb3fd,0xff2bb2fd,0xff2bb1fd,0xff29b1fd,0xff29b2fd,0xff29b1fd,0xff28b1fe,
+ 0xff28b0fe,0xff27affe,0xff27b1ff,0xff26b0ff,0xff26afff,0xff25afff,0xff25b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff29b1ff,0xff29b2ff,
+ 0xff43beff,0xff75d1ff,0xff69ceff,0xff7fd4fe,0xff5dc8fe,0xff84d7ff,0xff91dafe,0xff8cd8fe,0xffade2fc,0xffa6d6ee,0xffb4beaa,0xfff8ad0b,0xffffbd26,0xfffffab4,
+ 0xffffffb2,0xffffffa5,0xffffd142,0xffffae00,0xffffb80e,0xffffc521,0xffffcb27,0xffffd02e,0xffffd535,0xffffdb3c,0xffffe042,0xffffe549,0xffffeb50,0xfffff057,
+ 0xfffff55e,0xfffffb64,0xffffff6e,0xffffff80,0xffffe144,0xffffe346,0xfffee447,0xfffee549,0xfffde64b,0xfffde84e,0xfffbe74f,0xfffae851,0xfff9e853,0xfff8e954,
+ 0xffe6b936,0xffca6500,0xffda8208,0xffd87f07,0xffc26209,0xff9c8b7b,0xffa2aaae,0xffb9c7cf,0xffc9dfeb,0xffc8e5f5,0xffb4e0f7,0xff99d5f7,0xff99d6f7,0xff88d0f8,
+ 0xff60c1f8,0xff6ec8f8,0xff74cbf9,0xff4eb9f7,0xff39b1f7,0xff46b6f7,0xff43b6f6,0xff32aef6,0xff42b4f6,0xff53baf6,0xff41b4f7,0xff30acf7,0xff52bcf8,0xff52bcf9,
+ 0xff30aef9,0xff52bcf9,0xff63c3fa,0xff3fb4fa,0xff2eadfa,0xff2dadfa,0xff2dabfa,0xff2dabfa,0xff2dacf9,0xff2daaf9,0xff2ca8f8,0xff2ca9f7,0xff2aa7f6,0xff29a5f5,
+ 0xff29a5f5,0xff29a5f4,0xff28a4f3,0xff27a3f3,0xff27a3f3,0xff26a3f3,0xff26a4f4,0xff26a3f5,0xff26a2f5,0xff27a4f6,0xff26a4f7,0xff26a4f8,0xff25a5f9,0xff25a4f9,
+ 0xff24a4f9,0xff23a5fa,0xff23a4fa,0xff23a4fb,0xff22a2fb,0xff22a2fb,0xff21a2fb,0xff21a2fb,0xff21a1fb,0xff21a1fb,0xff20a0fb,0xff20a0fb,0xff20a0fb,0xff209ffb,
+ 0xff20a0fc,0xff20a0fc,0xff1ea0fd,0xff1ea0fd,0xff1ea0fd,0xff1d9ffd,0xff1da0fe,0xff1c9ffe,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1ca1ff,0xff1da1ff,0xff1da1ff,
+ 0xff1da1ff,0xff1ea2ff,0xff1fa2ff,0xff1fa2ff,0xff52cbff,0xff76d7ff,0xff7bd8ff,0xff7fd8ff,0xff76d5fe,0xff71d3fe,0xff7ed8fe,0xffa4e3fe,0xffb0e6fe,0xffbbe9fc,
+ 0xffb2def0,0xffbcc5ae,0xfff9ad0a,0xffffbd22,0xfffffa9c,0xffffff9a,0xffffff8d,0xffffe151,0xfffdac00,0xfffdb50e,0xffffce2b,0xffffd332,0xffffd939,0xffffde40,
+ 0xffffe347,0xffffe94d,0xffffee54,0xfffff35b,0xfffff962,0xfffffe69,0xffffff78,0xffffff8d,0xffffe64a,0xfffee74b,0xfffee84d,0xfffde94f,0xfffcea51,0xfffbea53,
+ 0xfff9ea54,0xfff8eb56,0xfff6ea57,0xfff4ea58,0xfff2e95a,0xffe0b639,0xffc45e00,0xffc15c00,0xffb85f11,0xffb36827,0xffb77f52,0xffbf906a,0xffc59e7f,0xffbab7ae,
+ 0xffb9b6b0,0xffadd9ee,0xff8dd2f2,0xff7bcff5,0xff87d2f5,0xff5ec4f4,0xff74cbf5,0xff4bbdf3,0xff47bcf4,0xff44bbf3,0xff64c4f2,0xff40b8f2,0xff74c8f2,0xff3fb7f2,
+ 0xff62c3f3,0xff63c4f4,0xff3db8f5,0xff3db8f5,0xff62c5f6,0xff3db9f7,0xff62c7f7,0xff3bbaf8,0xff3bb9f8,0xff3ab9f8,0xff3ab8f7,0xff39b8f7,0xff39b6f6,0xff38b6f5,
+ 0xff38b5f5,0xff38b4f4,0xff36b2f2,0xff36b1f1,0xff35b1f0,0xff34afef,0xff33afee,0xff33aded,0xff32aded,0xff32aded,0xff31adee,0xff32adef,0xff31aff1,0xff31aff1,
+ 0xff31aff3,0xff30b0f4,0xff30b1f5,0xff2fb2f6,0xff2eb1f7,0xff30b1f8,0xff2fb1f8,0xff2eb2f9,0xff2eb2f9,0xff2db2f9,0xff2db1f9,0xff2cb1f9,0xff2cb0f9,0xff2bb0f9,
+ 0xff2aaff9,0xff2aaff9,0xff29aff9,0xff29aff9,0xff28aff9,0xff28affa,0xff28affb,0xff28b0fc,0xff27b0fc,0xff27b0fd,0xff27b0fd,0xff26affe,0xff26aefe,0xff25afff,
+ 0xff26afff,0xff26b0ff,0xff26b1ff,0xff27b1ff,0xff28b2ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff41beff,0xff62cbfe,0xff48c1ff,0xff6acfff,0xff61cafe,0xff79d3ff,
+ 0xff82d6fe,0xff8ed9fe,0xffa6e1fe,0xffa9e2fe,0xffa8e1fd,0xffb2def3,0xffb6c6bd,0xffedae22,0xffffb814,0xfffff074,0xffffff82,0xffffff77,0xfffede44,0xfffaa600,
+ 0xfffbb512,0xffffd736,0xffffdc3d,0xffffe144,0xffffe64b,0xffffec51,0xfffff158,0xfffff65f,0xfffffc66,0xffffff71,0xffffff84,0xffffff9a,0xfffeea4f,0xfffeeb51,
+ 0xfffdec53,0xfffdee55,0xfffbed57,0xfff9ed58,0xfff7ed5a,0xfff5ec5b,0xfff2eb5c,0xffead950,0xffd29322,0xffc05c00,0xffc8750c,0xffd8991b,0xffd28712,0xffd1840e,
+ 0xffc56805,0xffc56503,0xffbd5700,0xffb64900,0xffb54700,0xffa7714e,0xff8cc4e1,0xff84c8ec,0xff6cc2f1,0xff51b8f1,0xff63bff0,0xff3eaef0,0xff38acef,0xff34a8ed,
+ 0xff52b5ed,0xff30a7ed,0xff50b4ed,0xff2fa6ed,0xff4fb3ed,0xff4eb4ee,0xff50b6f0,0xff4fb6f1,0xff3daef1,0xff2fa9f2,0xff4fb7f3,0xff2da9f4,0xff2da8f4,0xff2ca8f4,
+ 0xff2ca6f3,0xff2ca8f3,0xff2ca5f2,0xff2ba4f1,0xff2aa3f0,0xff2aa1ee,0xff29a1ed,0xff299feb,0xff279eea,0xff269de9,0xff259ce8,0xff269be7,0xff259be7,0xff259ae7,
+ 0xff249be8,0xff259be9,0xff259cea,0xff249dec,0xff249ded,0xff259def,0xff249ff1,0xff249ff1,0xff239ff2,0xff229ff3,0xff22a0f4,0xff239ff5,0xff239ff5,0xff229ff5,
+ 0xff229ef5,0xff219ef5,0xff209ef5,0xff209ef5,0xff209ef5,0xff1f9ef5,0xff1f9df5,0xff1f9df6,0xff1f9cf6,0xff1e9ef8,0xff1e9ef9,0xff1d9df9,0xff1c9efa,0xff1d9ffc,
+ 0xff1c9ffd,0xff1c9ffd,0xff1c9ffd,0xff1b9ffe,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1ea1ff,0xff1ea1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff50caff,0xff75d5ff,
+ 0xff55cbff,0xff79d7fe,0xff6dd2fe,0xff83d9fe,0xff8adbfe,0xff94defe,0xff9ee2fe,0xff94dffe,0xffb5e8fd,0xffb2e6fc,0xffc5e5f2,0xffc5d2ce,0xffeeaf23,0xffffb308,
+ 0xffffef61,0xffffff6d,0xfffffb65,0xfffee64c,0xfff7a505,0xfff6a90b,0xfffedb3d,0xffffe448,0xffffea4f,0xffffef55,0xfffff45c,0xfffffa63,0xfffffe6b,0xffffff7c,
+ 0xffffff91,0xffffffa8,0xfffeef55,0xfffdef57,0xfffdf159,0xfffbf05a,0xfff9f05c,0xfff7f05d,0xfff5ef5f,0xffeee458,0xffd9a62f,0xffc15e00,0xffc26908,0xffd7a528,
+ 0xffe4c233,0xffe3bb2c,0xffe3b625,0xffe4b11e,0xffe5ac17,0xffd88f0b,0xffb65200,0xffaf4500,0xff9a613b,0xff7996a3,0xff85b5cb,0xff89c7e4,0xff75c6ec,0xff5abdeb,
+ 0xff6ec2ea,0xff68c0e9,0xff43b4e9,0xff62bde8,0xff71c0e7,0xff4eb4e6,0xff5eb9e6,0xff3cafe7,0xff5ebbe8,0xff4db6e9,0xff5dbbe9,0xff5ebdeb,0xff4cb8ed,0xff3ab2ed,
+ 0xff5ebeee,0xff5dbeee,0xff39b2ef,0xff38b2ef,0xff38b1ee,0xff38b1ed,0xff37b0ed,0xff37afec,0xff35adea,0xff34ace9,0xff34aae7,0xff32a9e5,0xff32a7e3,0xff31a5e1,
+ 0xff31a5e1,0xff2fa3e0,0xff2fa3e0,0xff2fa3e0,0xff2fa3e1,0xff2ea4e2,0xff2ea5e4,0xff2ea6e5,0xff2da7e8,0xff2ea8e9,0xff2da9eb,0xff2eaaed,0xff2eaaed,0xff2dabee,
+ 0xff2dabef,0xff2cabf0,0xff2cabf0,0xff2babf0,0xff2babf1,0xff2ba9f0,0xff2aa9f0,0xff29a9f0,0xff28a8f0,0xff29a9f1,0xff29a9f1,0xff29a9f1,0xff27aaf2,0xff27aaf4,
+ 0xff27aaf5,0xff27abf7,0xff26acf8,0xff26acf9,0xff26adfb,0xff26affc,0xff26affd,0xff25affd,0xff26affe,0xff26b1ff,0xff27b0ff,0xff27b0ff,0xff28b2ff,0xff28b1ff,
+ 0xff28b2ff,0xff29b2ff,0xff40bdff,0xff41beff,0xff43beff,0xff46bfff,0xff4ac2ff,0xff4fc3fe,0xff57c6fe,0xff61cafe,0xff6ecefe,0xff7dd3fe,0xff8ed9fe,0xffa0defd,
+ 0xffb1e3fb,0xffbee4f6,0xffbfd1d1,0xfff1ab18,0xfffcae07,0xfffde146,0xfffff65e,0xffffef56,0xfffddb3f,0xfff49f04,0xfff4a60d,0xfffee247,0xffffed53,0xfffff25a,
+ 0xfffff860,0xfffffd67,0xffffff74,0xffffff89,0xffffff9f,0xfffae485,0xfffbe24a,0xfffdf45d,0xfffcf55e,0xfff9f35f,0xfff8f462,0xfff5f262,0xffddaa31,0xffc66a06,
+ 0xffc16605,0xffd5a72e,0xffe1cb42,0xffdfc33a,0xffddbc33,0xffdbb62b,0xffdbb024,0xffd29919,0xffb65e06,0xffa94400,0xff95552a,0xff707a7e,0xff678a9e,0xff6798b3,
+ 0xff69aacf,0xff63b4e1,0xff56b2e5,0xff4aaee6,0xff41aae5,0xff3aa5e4,0xff34a2e2,0xff31a1e1,0xff2e9fe0,0xff2d9ddf,0xff2d9ddf,0xff2d9ddf,0xff2d9de0,0xff2c9ee1,
+ 0xff2c9ee2,0xff2d9fe4,0xff2c9fe5,0xff2ca1e7,0xff2ca1e8,0xff2ca1e8,0xff2ba1e9,0xff2aa1e9,0xff2aa0e8,0xff2a9fe7,0xff299fe6,0xff289ce5,0xff289be3,0xff2799e1,
+ 0xff2697df,0xff2595dd,0xff2595db,0xff2492d9,0xff2492d8,0xff2390d7,0xff2390d7,0xff2390d7,0xff2292d9,0xff2291da,0xff2393dc,0xff2393de,0xff2294e0,0xff2396e2,
+ 0xff2296e4,0xff2197e5,0xff2298e7,0xff2299e8,0xff2199e9,0xff2199e9,0xff2097ea,0xff2097ea,0xff1f97ea,0xff1f97ea,0xff1f97ea,0xff1e96ea,0xff1d96ea,0xff1d96ea,
+ 0xff1d96eb,0xff1e97ec,0xff1d97ed,0xff1d98ef,0xff1c99f1,0xff1d99f3,0xff1d9bf5,0xff1c9cf7,0xff1b9cf9,0xff1c9dfb,0xff1b9efc,0xff1b9efd,0xff1b9efe,0xff1c9ffe,
+ 0xff1ca1ff,0xff1da1ff,0xff1da1ff,0xff1ea2ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff51caff,0xff51caff,0xff54ccff,0xff55ccfe,0xff5bcfff,0xff60d0ff,0xff68d1fe,
+ 0xff72d4fe,0xff7fd9fe,0xff8ddefe,0xff9fe2fe,0xffb0e7fd,0xffc1ebfc,0xffcdeaf7,0xffecb236,0xfffaa700,0xfff8a300,0xfffcd236,0xffffea4f,0xffffe447,0xfffcd133,
+ 0xfff2a20a,0xfff1a30f,0xfffbde47,0xfffff55e,0xfffffb64,0xffffff6e,0xffffff80,0xfffcec78,0xfff2b129,0xffec9600,0xffec9b05,0xfff5d23d,0xfffaf764,0xfff8f766,
+ 0xffe6c03f,0xffce770c,0xffc66a06,0xffd3a12d,0xffe1d24c,0xffdfd049,0xffdac640,0xfff2eac1,0xffffffff,0xffffffff,0xffffffff,0xffe2c6b2,0xff934f20,0xff796f64,
+ 0xff708893,0xff7496a6,0xff79a8be,0xff77b3ce,0xff70b9da,0xff65b8df,0xff5ab4df,0xff50b1df,0xff47addd,0xff42aadc,0xff3fa8da,0xff3ba6d9,0xffffffff,0xffffffff,
+ 0xffffffff,0xff76c0e4,0xff37a3d8,0xff36a4d9,0xff37a5da,0xff36a6dc,0xff37a6dd,0xff36a7df,0xff36a8e0,0xff37a9e1,0xff37a8e1,0xff36a8e1,0xff35a7e1,0xff35a7e0,
+ 0xff34a5df,0xff32a4dd,0xff32a2dc,0xff31a1d9,0xff309fd7,0xff2f9dd5,0xffffffff,0xffffffff,0xffffffff,0xff6eb6dd,0xff2b96cd,0xffffffff,0xffffffff,0xffffffff,
+ 0xff6db9e1,0xff2b9ad5,0xff2b9dd8,0xff2b9dda,0xff2b9fdd,0xff2b9fde,0xff2aa1e0,0xff2aa1e1,0xff2aa1e1,0xff2ba1e2,0xff29a2e3,0xff29a2e3,0xff29a1e3,0xff28a0e3,
+ 0xff28a0e3,0xff27a0e2,0xff279fe3,0xff26a0e3,0xff26a0e4,0xff27a0e5,0xff26a3e8,0xff25a3e9,0xff25a5ed,0xff26a7ef,0xff26a8f2,0xff25aaf5,0xff26abf7,0xff25acf9,
+ 0xff25adfb,0xff25aefd,0xff25aefd,0xff26affe,0xff26affe,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff40bfff,0xff41bdff,0xff42c0ff,
+ 0xff44bffe,0xff47c0fe,0xff4cc3fe,0xff53c5fe,0xff6acefe,0xff69ccfd,0xff79d1fd,0xff8cd7fd,0xff9fdefd,0xffb4e6fe,0xffc7ecfe,0xffebb23a,0xfffcac05,0xfff9a805,
+ 0xfff49d00,0xfffac92d,0xffffde40,0xffffd838,0xfffece2d,0xffef9b08,0xffeb9406,0xfffbe450,0xfffffe69,0xfffdf268,0xfff4be33,0xffed9700,0xffec9600,0xffec9600,
+ 0xffeb9500,0xffe99400,0xffebbc34,0xffd68413,0xffca6600,0xffd5972a,0xffe6e05e,0xffe4e15b,0xffded551,0xffd9cb49,0xffd6c650,0xfffcfcfa,0xffffffff,0xffffffff,
+ 0xffffffff,0xfffbfbfb,0xff798992,0xff718b99,0xff779baf,0xff7daac1,0xff72adce,0xff68add4,0xff5caad7,0xff50a6d7,0xff45a2d7,0xff3d9fd6,0xff379cd6,0xff3299d4,
+ 0xff2f95d1,0xff2c94d1,0xffffffff,0xffffffff,0xffffffff,0xff6cb3dd,0xff3696ce,0xff2a91d0,0xff2992d1,0xff3699d3,0xff2995d5,0xff2995d6,0xff2996d8,0xff2897d9,
+ 0xff2897d9,0xff2796d9,0xff2796d9,0xff2793d8,0xff2792d6,0xff2691d5,0xff258fd3,0xff258ed1,0xff3192ce,0xff228acc,0xffffffff,0xffffffff,0xffffffff,0xff66abd7,
+ 0xff2083c4,0xffffffff,0xffffffff,0xffffffff,0xff65acdb,0xff1f88cd,0xff2089cf,0xff1f8bd1,0xff208cd4,0xff208cd5,0xff1f8ed7,0xff1f8fd9,0xff3e9dd9,0xff1f8fda,
+ 0xff1e8edb,0xff1f8fdb,0xff1e8edb,0xff3d9ddb,0xff2c94da,0xff1c8cda,0xff1b8ddb,0xff1b8cdb,0xff1c8ddd,0xff1c8ede,0xff1b8fe1,0xff1c91e4,0xff1c93e7,0xff1c95ea,
+ 0xff1c96ee,0xff1b98f1,0xff1c9af5,0xff1b9bf7,0xff1a9cf9,0xff1b9dfb,0xff40b1fd,0xff1ca0fd,0xff1da0fe,0xff1da1ff,0xff30aaff,0xff1ea2ff,0xff1ea2ff,0xff1fa2ff,
+ 0xff50caff,0xff50caff,0xff50cbff,0xff52cbff,0xff52cbfe,0xff56cbfe,0xff5acdff,0xff5ecffe,0xff85dbfe,0xff72d5fe,0xff7fd9fe,0xff8fddfe,0xffa2e3fe,0xffb4e8fd,
+ 0xffc7eefe,0xffebb23a,0xfffbae09,0xffffbb12,0xfffaaf0d,0xfff19800,0xfff5ae15,0xffffd331,0xffffcc29,0xfffec31f,0xffec9405,0xffe88f06,0xfff3c130,0xffed9700,
+ 0xffed9700,0xffed9700,0xffec9600,0xffeb9500,0xffe78e00,0xffd87800,0xffd16b00,0xffd78b22,0xffecdf6f,0xffecec71,0xffe5e564,0xffdfdd5a,0xffd9d150,0xffd1c447,
+ 0xffd5b780,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffb6c4cb,0xff7fa2b3,0xff7caabf,0xff7caec5,0xff6cadcb,0xff61aacc,0xff58aacf,0xff50a7cf,
+ 0xff49a5cf,0xff43a2cf,0xff3ea0ce,0xff3b9ecd,0xff379bca,0xff369ac9,0xffffffff,0xffffffff,0xffffffff,0xff73b6d7,0xff509ec5,0xff3295c6,0xff3297c8,0xff419cc9,
+ 0xff3299cc,0xff329acd,0xff329ace,0xff329bcf,0xff329bd0,0xff319cd0,0xff319acf,0xff319acf,0xff2f98cd,0xff2f97cc,0xff2e95ca,0xff2d93c8,0xff4b9cc5,0xff2c90c3,
+ 0xffffffff,0xffffffff,0xffffffff,0xff6baed0,0xff2788bb,0xffffffff,0xffffffff,0xffffffff,0xff6bafd4,0xff288dc3,0xff288fc6,0xff2791c9,0xff2892ca,0xff2893cd,
+ 0xff2894ce,0xff2794d0,0xff2796d1,0xff389bd1,0xff2796d2,0xff2695d2,0xff48a1d2,0xff2595d2,0xff47a0d1,0xff2494d1,0xff2493d2,0xff2495d3,0xff2495d4,0xff2396d6,
+ 0xff2397d9,0xff249add,0xff249ce1,0xff24a0e5,0xff25a2e9,0xff24a5ee,0xff24a8f2,0xff25a9f5,0xff24abf8,0xff24acfa,0xff51befc,0xff26affd,0xff27affe,0xff27b0ff,
+ 0xff53c1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff60cbff,0xff60ccff,0xff61cbff,0xff51c5ff,0xff63ccfe,0xff66cdff,0xff5ac8fe,0xff71d1fe,0xff6ccefe,
+ 0xff79d3fe,0xff8ad8fe,0xffa5e1fd,0xffb8e8fe,0xffc3eafc,0xffe8af3a,0xfffaaf0d,0xffffc11a,0xffffc11a,0xfff9b111,0xffed9200,0xfff2a30d,0xfff8b518,0xfffebd19,
+ 0xffffba12,0xffee9704,0xffe38200,0xffe98e00,0xffed9700,0xffed9700,0xffea9200,0xffdf7f00,0xffd57000,0xffdb8f2a,0xffedd475,0xfff3f38e,0xffeeee7f,0xffe9e972,
+ 0xffe1e163,0xffdad858,0xffc29c31,0xffa55608,0xffecdccf,0xffffffff,0xffffffff,0xffded0c5,0xffffffff,0xffffffff,0xffe8edf0,0xff7aa4b9,0xff6aa0bd,0xff78a7c0,
+ 0xff569cc3,0xffffffff,0xffffffff,0xffffffff,0xff9bc8e1,0xffe1eef4,0xfffafcfd,0xffd0e4f0,0xff2b8ac3,0xff2989c1,0xffffffff,0xffffffff,0xffffffff,0xff7bb1d0,
+ 0xff4c93bc,0xffaed1e6,0xffffffff,0xffffffff,0xfffdfeff,0xff90bfda,0xff4094c5,0xff4698c8,0xff93c4e1,0xffdcecf5,0xfff7fafc,0xfff6fafc,0xffddecf5,0xff9dc7e0,
+ 0xff4694c4,0xff2f88c0,0xff4892bd,0xff3a8aba,0xffffffff,0xffffffff,0xffffffff,0xff75a9ca,0xff3583b2,0xffffffff,0xffffffff,0xffffffff,0xff75acce,0xff1c7cba,
+ 0xff378abd,0xff2483c2,0xff89bddf,0xffd6e8f4,0xfff6fafc,0xfff5f9fc,0xffd7e9f5,0xff8cc1e4,0xff278acc,0xff1c82c9,0xff3790c9,0xff1b82c9,0xffffffff,0xffffffff,
+ 0xffffffff,0xff6eafdb,0xffa8cfe9,0xffeef5fa,0xfff7fbfd,0xffc2def2,0xff48a1de,0xff3a9de0,0xff2b99e5,0xff3ca4ea,0xff3da8ef,0xff2ca1f3,0xff1a9af6,0xff3fadf9,
+ 0xff1b9dfb,0xff2ea8fd,0xff40b1fd,0xff41b2fe,0xff42b3ff,0xff42b3ff,0xff43b3ff,0xff43b3ff,0xff4fcaff,0xff73d5ff,0xff73d5ff,0xff74d6ff,0xff52cbff,0xff76d6ff,
+ 0xff77d6fe,0xff7cd8ff,0xff90dfff,0xff88dbfe,0xff77d6fe,0xff9fe3fe,0xffaee6fd,0xffbdebfd,0xffcdeffc,0xffe6ad3a,0xfff9b111,0xffffc622,0xffffc722,0xffffc722,
+ 0xfff9b619,0xffef9c0a,0xffe88a00,0xffe68700,0xffe88b02,0xffed9302,0xffe38200,0xffdf7c00,0xffe68a00,0xffe38600,0xffd97300,0xffdb8218,0xffecc576,0xfff9f9ad,
+ 0xfff5f59e,0xfff1f18f,0xffecec80,0xffe5e572,0xffd2bb4b,0xffb16610,0xffa14700,0xffb97e33,0xffffffff,0xffffffff,0xfffcfbf9,0xff915f3e,0xfffefefe,0xffffffff,
+ 0xffffffff,0xff8fb2c1,0xff639bb5,0xff6da0b8,0xff529abc,0xffffffff,0xffffffff,0xffffffff,0xfff8fbfc,0xffffffff,0xffffffff,0xffa1c9dc,0xff3391bd,0xff318eba,
+ 0xffffffff,0xffffffff,0xffffffff,0xff70adcb,0xff9dc3d6,0xffffffff,0xffffffff,0xfffeffff,0xff7eb8d4,0xff4a96bb,0xff3792c0,0xffd5e7f1,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffd8e9f2,0xff358ebc,0xff458fb5,0xff2884b3,0xffffffff,0xffffffff,0xffffffff,0xff7babc5,0xff3f86ab,0xffffffff,
+ 0xffffffff,0xffffffff,0xff7caec9,0xff2481b3,0xff4991b8,0xffd0e4ef,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffd6e9f4,0xff3e95c4,
+ 0xff328ec1,0xff2289c1,0xffffffff,0xffffffff,0xffffffff,0xffdbebf4,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffbbddf0,0xff47a6db,0xff48aae1,0xff4aafe7,
+ 0xff4cb3ed,0xff4eb5f1,0xff25a9f5,0xff4fbaf8,0xff25adfa,0xff51befd,0xff26affd,0xff27affe,0xff52c1ff,0xff3eb9ff,0xff54c1ff,0xff69c9ff,0xff3fbdff,0xff60ccff,
+ 0xff60cbff,0xff61ccff,0xff62ccff,0xff42c0ff,0xff45c0fe,0xff68cdfe,0xff6ed0ff,0xff68cdfe,0xff74d1fe,0xff8fdafd,0xff8dd8fe,0xffa4e0fe,0xffbee8fc,0xffe3aa3a,
+ 0xfff8b215,0xffffcc29,0xffffcd2a,0xffffcd2a,0xffffcd2a,0xffffcd2b,0xffffce2b,0xfff9bc21,0xfff3ae19,0xffea990f,0xffe38706,0xffdd7900,0xffdc7700,0xffd97300,
+ 0xffd67100,0xffde9133,0xffe2a852,0xffe2af57,0xffe4be63,0xffe4cb6c,0xffdbbc59,0xffc0771d,0xffad4f00,0xffb15f06,0xffc48f14,0xffe3cf97,0xffffffff,0xffffffff,
+ 0xffe3d2bc,0xff753e1b,0xffdee1e3,0xffffffff,0xffffffff,0xffb9cfdb,0xff518dae,0xff5993b2,0xff3f8bb5,0xffffffff,0xffffffff,0xffffffff,0xfff9fbfc,0xff92c0d8,
+ 0xff89bad4,0xff358bbd,0xff2683b8,0xff2680b5,0xffffffff,0xffffffff,0xffffffff,0xffa8cadf,0xfffcfdfd,0xffffffff,0xfffeffff,0xff89b6d0,0xff227cb2,0xff3b88b4,
+ 0xff97c2db,0xffffffff,0xffffffff,0xfff0f6f9,0xff7ab1d3,0xff80b4d3,0xfff2f6f9,0xffffffff,0xffffffff,0xff9bc3dc,0xff3682af,0xff1d75ad,0xffffffff,0xffffffff,
+ 0xffffffff,0xff71a3c1,0xff3179a5,0xffffffff,0xffffffff,0xffffffff,0xff72a5c5,0xff337ead,0xffa5c5d9,0xffffffff,0xffffffff,0xfff0f6f9,0xff76aed3,0xff74add3,
+ 0xfff0f6fa,0xffffffff,0xffffffff,0xffa5c9e0,0xff1978b9,0xff1978b9,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffeff6fa,0xff3897d7,0xff399bdd,0xff1a91e5,0xff1b94ea,0xff2ba0f0,0xff2ca2f4,0xff2da4f7,0xff1a9dfa,0xff40b0fc,0xff1c9ffd,0xff2fa9fe,0xff42b3ff,0xff42b3ff,
+ 0xff1ea2ff,0xff43b4ff,0xff4fcaff,0xff62cfff,0xff50caff,0xff62d0ff,0xff51cbff,0xff76d5fe,0xff78d7ff,0xff6ad3ff,0xff6fd4ff,0xff67d2fe,0xff82d9fe,0xff83dafe,
+ 0xffabe6fe,0xffbaeafd,0xffbdeafd,0xffe3a83a,0xfff7b418,0xffffd231,0xffffd331,0xffffd331,0xffffd332,0xffffd332,0xffffd332,0xffffd433,0xffffd433,0xffffd433,
+ 0xffffd534,0xfffbc92e,0xfff6ca59,0xfff0b439,0xffe99d15,0xffe79b14,0xffd9800a,0xffd67b0a,0xffc86502,0xffc05a00,0xffba5500,0xffbd6908,0xffcd9417,0xffd0a31e,
+ 0xffc79d1f,0xfff8f4ea,0xffffffff,0xffffffff,0xffc19f72,0xff723b1a,0xffadb6ba,0xffffffff,0xffffffff,0xfff2f5f7,0xff5e94ac,0xff5c93ac,0xff5994b0,0xffffffff,
+ 0xffffffff,0xffffffff,0xffb5d4e3,0xff4e97b9,0xff4d96b8,0xff4c94b6,0xff3089b4,0xff2f87b1,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffeff5f7,0xff4c8faf,0xff3886ad,0xff3886ae,0xffe5f0f5,0xffffffff,0xffffffff,0xff9bc2d5,0xff458cb1,0xff2a84b1,0xff93bfd5,0xffffffff,0xffffffff,0xffe5f0f5,
+ 0xff267eab,0xff4086a9,0xffffffff,0xffffffff,0xffffffff,0xff70a4bf,0xff2f7aa1,0xffffffff,0xffffffff,0xffffffff,0xff70a5c2,0xff227aa8,0xffe7f0f5,0xffffffff,
+ 0xffffffff,0xff87b9d3,0xff227eb0,0xff217eb1,0xff88bbd6,0xffffffff,0xffffffff,0xffe6f0f6,0xff2080b4,0xff207fb3,0xffffffff,0xffffffff,0xffffffff,0xffb9d7e8,
+ 0xff4892bc,0xffaed0e3,0xffffffff,0xffffffff,0xfffeffff,0xff349bd4,0xff2298db,0xff4aabe2,0xff4bafe9,0xff23a4ee,0xff4db7f3,0xff24a9f6,0xff25acf9,0xff26aefc,
+ 0xff51befd,0xff3db8fe,0xff3db9ff,0xff3ebaff,0xff53c1ff,0xff54c1ff,0xff40bdff,0xff40bdff,0xff41bdff,0xff41bfff,0xff41bfff,0xff42bfff,0xff44c1ff,0xff49c3ff,
+ 0xff4fc4ff,0xff57c7fe,0xff66cdff,0xff76d1fe,0xff8ad8fe,0xff9fdffe,0xffb4e5fd,0xffe0a53a,0xfff6b51c,0xffffd838,0xffffd939,0xffffd939,0xffffd939,0xffffd93a,
+ 0xffffda3a,0xffffda3a,0xffffda3b,0xffffda3b,0xffffda3b,0xffffdb3c,0xffffe462,0xfffedc58,0xfffdd030,0xfffccf2f,0xfff9cc2d,0xfff7ca2d,0xfff3c62b,0xffedc12a,
+ 0xffe8bc28,0xffe0b527,0xffd8ae25,0xffcfa723,0xffd6bc64,0xffffffff,0xffffffff,0xffffffff,0xffdeceb7,0xffc8b4a9,0xffd0d6d9,0xffffffff,0xffffffff,0xffffffff,
+ 0xff80acc3,0xff3b83ab,0xff3583ae,0xffffffff,0xffffffff,0xffffffff,0xff7cb4d3,0xff3488b7,0xff3f8db7,0xff3285b5,0xff257fb3,0xff257db1,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff91bbd4,0xff2075a9,0xff2076aa,0xfffafbfc,0xffffffff,0xffffffff,0xff68a4c8,0xff2076ad,0xff1f77ad,
+ 0xff69a3c8,0xffffffff,0xffffffff,0xfffafbfc,0xff1d73a9,0xff1c71a7,0xffffffff,0xffffffff,0xffffffff,0xff6199be,0xff1a6ca1,0xffffffff,0xffffffff,0xffffffff,
+ 0xff699fc1,0xff3078a6,0xfffafbfc,0xffffffff,0xffffffff,0xff649fc7,0xff1872ad,0xff1871ad,0xff64a1c9,0xffffffff,0xffffffff,0xfff9fbfc,0xff1872b0,0xff1771b0,
+ 0xffffffff,0xffffffff,0xffffffff,0xff66a2cd,0xff1774b5,0xff62a2d0,0xffffffff,0xffffffff,0xffffffff,0xff1985d1,0xff1989d9,0xff1a8ee1,0xff1a92e7,0xff1a95ed,
+ 0xff2ca0f2,0xff1a9af6,0xff1a9cf9,0xff1c9efb,0xff1c9ffd,0xff1d9ffe,0xff1ea0fe,0xff1ea1ff,0xff1fa1ff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff50caff,0xff51cbff,
+ 0xff51cbff,0xff53cbff,0xff54ccfe,0xff58ceff,0xff5ecefe,0xff66d1ff,0xff72d6ff,0xff82daff,0xff92dffe,0xffa6e4fe,0xffb9e9fd,0xffdfa43a,0xfff5b720,0xffffde40,
+ 0xffffde40,0xffffdf41,0xffffdf41,0xffffdf41,0xffffe042,0xffffe042,0xffffe042,0xffffe043,0xffffe043,0xffffe143,0xffffe967,0xfffee15e,0xfffdd637,0xfffcd436,
+ 0xfff9d134,0xfff6ce34,0xfff2cb32,0xffedc531,0xffe7c02f,0xffe0bb2d,0xffd8b32b,0xffcfab29,0xffece1b8,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffc7dbe4,0xff428aab,0xff3c8bae,0xffffffff,0xffffffff,0xffffffff,0xff75b2cf,0xff328db8,0xff328db8,0xff318cb6,
+ 0xff308ab5,0xff2f88b2,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffc5dbe6,0xffffffff,0xffffffff,0xfff6f9fb,0xff408cb2,0xff297fa9,0xffe5f0f5,0xffffffff,
+ 0xffffffff,0xff8dbbd3,0xff2880ac,0xff287fac,0xff8cbbd3,0xffffffff,0xffffffff,0xffe5eff5,0xff267da9,0xff267ca8,0xffffffff,0xffffffff,0xffffffff,0xff67a1c0,
+ 0xff2276a2,0xffffffff,0xffffffff,0xffffffff,0xff67a1c1,0xff2178a6,0xffe4eef4,0xffffffff,0xffffffff,0xff88b8d2,0xff217bac,0xff217cad,0xff88b9d3,0xffffffff,
+ 0xffffffff,0xffe4eff5,0xff1f7caf,0xff1f7caf,0xffffffff,0xffffffff,0xffffffff,0xff64a6ca,0xff1f7fb5,0xff65a8ce,0xffffffff,0xffffffff,0xffffffff,0xff2191d1,
+ 0xff2297d9,0xff229be0,0xff23a0e7,0xff23a4ed,0xff23a7f2,0xff24aaf6,0xff25acf9,0xff25adfb,0xff27b0fd,0xff27affe,0xff28b0fe,0xff28b1ff,0xff3ebaff,0xff29b2ff,
+ 0xff3fbdff,0xff40bfff,0xff40bfff,0xff41bfff,0xff41bfff,0xff42bfff,0xff44c1ff,0xff47c2ff,0xff6ccfff,0xff55c5fe,0xff61cafe,0xff71d0fe,0xff83d5fe,0xff99ddfe,
+ 0xffaee3fd,0xffdda13a,0xfff4b626,0xffffe348,0xffffe448,0xffffe548,0xffffe549,0xffffe549,0xffffe549,0xffffe649,0xffffe64a,0xffffe64a,0xffffe64a,0xffffe74b,
+ 0xffffed6d,0xfffee563,0xfffddb3e,0xfffcda3d,0xfff9d63c,0xfff6d43a,0xfff2cf38,0xffedcb37,0xffe7c535,0xffe0bf33,0xffd9b931,0xffd3b73e,0xfffdfcf9,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfff9fafb,0xff488eb4,0xff3183b0,0xffffffff,0xffffffff,0xffffffff,
+ 0xff6baace,0xff2886bb,0xff2886bb,0xff2783b9,0xff2683b8,0xff3e8ab5,0xffffffff,0xffffffff,0xffffffff,0xff95bdd5,0xff277aab,0xffe7f0f6,0xffffffff,0xffffffff,
+ 0xffaccbdf,0xff3881ab,0xff97bfd8,0xffffffff,0xffffffff,0xfff0f6f9,0xff77accd,0xff76accd,0xffeff5f9,0xffffffff,0xffffffff,0xff97bfd8,0xff1e75ad,0xff1d74ab,
+ 0xffffffff,0xffffffff,0xffffffff,0xff629dc3,0xff1b6fa6,0xffffffff,0xffffffff,0xffffffff,0xff619dc4,0xff1b70a9,0xff94bcd7,0xffffffff,0xffffffff,0xfff0f6f9,
+ 0xff74aace,0xff72a9cd,0xfff1f6f9,0xffffffff,0xffffffff,0xff95bedb,0xff1873b1,0xff1872b1,0xffffffff,0xffffffff,0xffffffff,0xff609fcc,0xff1774b6,0xff60a2d0,
+ 0xffffffff,0xffffffff,0xffffffff,0xff288cd2,0xff1a89d9,0xff1a8ee1,0xff1a91e7,0xff1a95ed,0xff1b98f2,0xff52b4f6,0xff1b9cf9,0xff1c9dfb,0xff2fa9fd,0xff41b1fe,
+ 0xff1ea1fe,0xff1ea1ff,0xff43b3ff,0xff1fa2ff,0xff4fcaff,0xff62cfff,0xff62cfff,0xff62d0ff,0xff51cbff,0xff76d6ff,0xff78d6ff,0xff58cdff,0xff7dd9ff,0xff63d2ff,
+ 0xff7dd9ff,0xff7bd8fe,0xffa2e3fe,0xffb1e7fe,0xffafe6fd,0xffda9e3a,0xffec9910,0xfffdd84f,0xffffe950,0xffffeb50,0xffffeb50,0xffffeb50,0xffffeb51,0xffffec51,
+ 0xffffec51,0xffffec52,0xffffec52,0xffffed52,0xfffff173,0xfffee968,0xfffde045,0xfffcdf44,0xfff9dc43,0xfff7d941,0xfff3d63f,0xffeed13e,0xffe9cc3c,0xffe1c53a,
+ 0xffdabe37,0xffe4d58b,0xffffffff,0xffffffff,0xffffffff,0xffc6b359,0xff9a6415,0xff763d1b,0xff5e7580,0xff97afba,0xffffffff,0xffffffff,0xffffffff,0xffa1c3d3,
+ 0xff4893b5,0xffffffff,0xffffffff,0xffffffff,0xff7eb7d2,0xff3594c0,0xff3494c0,0xff3492bf,0xff4095bd,0xff5b9cbb,0xffffffff,0xffffffff,0xffffffff,0xff81b1c9,
+ 0xff3a89af,0xff87b9d1,0xffffffff,0xffffffff,0xfffcfdfd,0xff69a2be,0xff4e92b4,0xffd6e6ef,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffd4e6ef,0xff3389b6,0xff438cb1,0xff3587b1,0xffffffff,0xffffffff,0xffffffff,0xff73aac7,0xff3283ad,0xffffffff,0xffffffff,0xffffffff,0xff72aac7,0xff4088af,
+ 0xff3b8ab4,0xffd1e4ef,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffd3e5ef,0xff4891b9,0xff3e8bb5,0xff2180b5,0xffffffff,0xffffffff,
+ 0xffffffff,0xff65a9ce,0xff1f83ba,0xff65abd2,0xffffffff,0xffffffff,0xffffffff,0xff2195d5,0xff2299dc,0xff49abe2,0xff4bafe9,0xff23a4ee,0xff23a7f3,0xff4eb9f6,
+ 0xff25acf9,0xff26aefc,0xff27b0fd,0xff52bffe,0xff27b1ff,0xff28b2ff,0xff3ebaff,0xff29b2ff,0xff3fbdff,0xff60ccff,0xff60cbff,0xff61ccff,0xff51c5ff,0xff42c0ff,
+ 0xff43c0ff,0xff67cdff,0xff6acfff,0xff6fcffe,0xff5cc8fe,0xff83d6fe,0xff79d3fe,0xff8dd9fe,0xffb1e5fe,0xffb5c9c2,0xffdc8d18,0xffe99511,0xfffacf49,0xffffed58,
+ 0xfffff158,0xfffff158,0xfffff158,0xfffff259,0xfffff259,0xfffff259,0xfffff25a,0xfffff25a,0xfffff678,0xfffeed6d,0xfffde64c,0xfffce54b,0xfffae24a,0xfff7df48,
+ 0xfff4dc46,0xffefd745,0xffead242,0xffe4cc41,0xffddc63e,0xfff6f2d7,0xffffffff,0xffffffff,0xfff9f7ed,0xffbda834,0xffa06a19,0xff7b3f1c,0xff5e7987,0xff6992a9,
+ 0xfff9fbfc,0xffffffff,0xffffffff,0xffdbeaf2,0xff4b95bc,0xffffffff,0xffffffff,0xffffffff,0xff6db1d7,0xff2a8dc5,0xff2a8dc5,0xff298cc5,0xff298bc4,0xff4393c1,
+ 0xffffffff,0xffffffff,0xffffffff,0xff69a8ce,0xff3d8ab6,0xff2b84b8,0xffebf3f8,0xffffffff,0xffffffff,0xffd0e2eb,0xff227fb6,0xff428eb9,0xff9bc3da,0xffd9e9f3,
+ 0xfff8fbfc,0xfff8fbfc,0xffd9e9f3,0xff8dbdda,0xff2983bc,0xff3a89b9,0xff207eb9,0xff2b82b8,0xffffffff,0xffffffff,0xffffffff,0xff75abcc,0xff3685b5,0xffffffff,
+ 0xffffffff,0xffffffff,0xff74aacc,0xff1d79b6,0xff3585b7,0xff247dba,0xff8abada,0xffd8e8f3,0xfff8fafc,0xfff8fafc,0xffdeebf3,0xff91bedc,0xff3c8abd,0xff1a7abb,
+ 0xff1a78bb,0xff3386bb,0xffffffff,0xffffffff,0xffffffff,0xff60a3d2,0xff187bc1,0xff61a5d6,0xffffffff,0xffffffff,0xffffffff,0xff1a8ad9,0xff2a94de,0xff1a91e5,
+ 0xff1a93ea,0xff3da8f0,0xff1b99f4,0xff3facf7,0xff1b9dfa,0xff1c9efc,0xff1c9ffd,0xff41b2fe,0xff1da1ff,0xff1ea2ff,0xff1ea1ff,0xff1fa2ff,0xff50caff,0xff73d5ff,
+ 0xff73d6ff,0xff74d6ff,0xff63d0ff,0xff75d6ff,0xff77d6ff,0xff79d8ff,0xff8bdcff,0xff7fdaff,0xff67d3ff,0xff8eddfe,0xff99e1fe,0xffa6e4fe,0xffa9e4fd,0xfface1f7,
+ 0xffb7cdd0,0xffd38922,0xffe28406,0xfff9cf4e,0xfffff25f,0xfffff760,0xfffff760,0xfffff860,0xfffff861,0xfffff861,0xfffff861,0xfffff962,0xfffffa7e,0xfffef173,
+ 0xfffdec53,0xfffcea52,0xfffae851,0xfff8e54f,0xfff5e24d,0xfff1de4c,0xffecd94a,0xffe7d348,0xffe1ce45,0xffdbc843,0xffd5c241,0xffcfbd3f,0xffcab63d,0xffc5ab3e,
+ 0xffa5651c,0xff80421d,0xff62808d,0xff6b98ad,0xff77a6bc,0xff589dbd,0xff65a2bf,0xff459ac1,0xff5aa1c2,0xff499ec5,0xff57a4c8,0xff56a5c9,0xff389dcc,0xff379ecd,
+ 0xff379dcd,0xff379dcd,0xff369bcb,0xff54a3c9,0xff3498c7,0xff3495c5,0xff4f9cc2,0xff3193c1,0xff4d9abf,0xff308fbe,0xff2f8ebd,0xff2f8ebd,0xff2f8ebd,0xff4c98be,
+ 0xff2f8ebe,0xff4b97be,0xff4b98bf,0xff4a99bf,0xff4b99c0,0xff3c94c0,0xff2c8ec0,0xff2c8fc1,0xff2c8fc1,0xff4a99c1,0xff2b8ec1,0xff2a8ec1,0xff4898c0,0xff4797bf,
+ 0xff298bbe,0xff4795be,0xff4694bd,0xff288abd,0xff2789bd,0xff4594be,0xff5499be,0xff4694bf,0xff4594bf,0xff258abf,0xff268ac0,0xff268bc0,0xff258ac1,0xff258bc1,
+ 0xff4495c1,0xff248ac1,0xff4395c2,0xff238ac2,0xff228ac3,0xff4395c3,0xff4395c3,0xff228ac4,0xff218bc5,0xff228ac5,0xff228cc8,0xff218eca,0xff2290ce,0xff2293d2,
+ 0xff2295d7,0xff2399dd,0xff37a4e2,0xff4bb0e8,0xff4cb3ed,0xff4eb5f1,0xff25a9f5,0xff4fbaf8,0xff24acfa,0xff26aefc,0xff27affd,0xff52bffe,0xff27b2ff,0xff29b1ff,
+ 0xff28b2ff,0xff29b2ff,0xff40bdff,0xff60cbff,0xff50c3ff,0xff61ccff,0xff50c5ff,0xff62ccff,0xff63ccff,0xff64ccfe,0xff67cdff,0xff4dc3ff,0xff71d1fe,0xff6ccefe,
+ 0xff86d8ff,0xff91dbfe,0xff95dcfe,0xff9dddfc,0xffb6e2f6,0xffabc7d0,0xffd38523,0xffdf8006,0xfff6c94a,0xfffff365,0xfffffd68,0xfffffd68,0xfffffd68,0xfffffe69,
+ 0xfffffe69,0xfffffe69,0xfffffe84,0xfffef362,0xfffdf15a,0xfffdf159,0xfffbee58,0xfff9ec56,0xfff6e854,0xfff3e553,0xffefe051,0xffeadc4f,0xffe5d74d,0xffe0d14b,
+ 0xffdbcb49,0xffd6bf47,0xffc79c3a,0xffa45511,0xff943600,0xff7c5137,0xff608497,0xff73a0b8,0xff78abc6,0xff59a1c7,0xff5ca3c9,0xff3d98ca,0xff50a1cc,0xff3f9bcd,
+ 0xff4ba2d0,0xff4aa2d1,0xff2e97d3,0xff2e96d4,0xff2d99d5,0xff2d97d5,0xff2c96d3,0xff3a9bd2,0xff479ed0,0xff3796cd,0xff459acc,0xff449aca,0xff4398c9,0xff288cc8,
+ 0xff278bc7,0xff278bc7,0xff268bc7,0xff509cc7,0xff4196c7,0xff4097c8,0xff3290c8,0xff4096c8,0xff4095c9,0xff3290c9,0xff2489c9,0xff2389c9,0xff2388c9,0xff3091ca,
+ 0xff3f96ca,0xff3e95c9,0xff3d94c9,0xff3d94c9,0xff3c94c9,0xff3c93c8,0xff3c93c8,0xff1f86c8,0xff1f85c8,0xff3b92c8,0xff3b92c8,0xff3b92c9,0xff3a92c9,0xff1e84c9,
+ 0xff1e84c9,0xff1d85c9,0xff1d84c9,0xff1d84c9,0xff3a92ca,0xff1d84ca,0xff2a8acb,0xff3992cb,0xff3992cc,0xff298acc,0xff3891cc,0xff1a83cc,0xff1b83cd,0xff1a84ce,
+ 0xff1a85d0,0xff1a86d2,0xff1b87d5,0xff1a8ad9,0xff1a8cdd,0xff1a8ee1,0xff2b99e6,0xff3ca5eb,0xff3da7ef,0xff3eabf3,0xff2ca3f6,0xff53b7f9,0xff40affb,0xff1c9ffd,
+ 0xff40b2fd,0xff56bafe,0xff2faaff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff4fc9ff,0xff50caff,0xff50cbff,0xff51cbff,0xff51cbff,0xff52cbff,0xff53ccff,0xff54ccfe,
+ 0xff56ccfe,0xff5acdfe,0xff61d0ff,0xff68d3ff,0xff72d5fe,0xff7dd9fe,0xff8cddfe,0xff9be1fe,0xffc2ebfd,0xffc1e8f7,0xffb2ccd2,0xffc38d47,0xffda7400,0xfff0b63e,
+ 0xfffff36c,0xffffff73,0xffffff74,0xffffff74,0xffffff75,0xffffff75,0xffffff8d,0xfffef861,0xfffef861,0xfffdf660,0xfffcf55f,0xfff9f15d,0xfff8f05d,0xfff5ec5b,
+ 0xfff1e858,0xffede357,0xffe9de54,0xffe5ce4f,0xffd9b043,0xffb86b1c,0xff9f3900,0xff904920,0xff726b64,0xff658492,0xff6b98ac,0xff6eabc6,0xff66afd0,0xff5aabd0,
+ 0xff4fa8d1,0xff49a8d3,0xff44a8d5,0xff4fabd6,0xff5eb2d8,0xff5cb1d9,0xff4daddb,0xff3ca9dc,0xff3caadd,0xff3ca9dc,0xff3aa7db,0xff39a6da,0xff39a6d9,0xff38a3d6,
+ 0xff37a1d5,0xff37a1d3,0xff369fd2,0xff359dd1,0xff349dd1,0xff349dd1,0xff349dd1,0xff349dd1,0xff339dd1,0xff339dd1,0xff329cd1,0xff329cd1,0xff319cd1,0xff319cd1,
+ 0xff319cd2,0xff319cd2,0xff309cd3,0xff2f9cd3,0xff2f9cd3,0xff2e9bd3,0xff2e9cd3,0xff2d99d2,0xff2d9ad2,0xff2c98d1,0xff2c98d1,0xff2b98d1,0xff2b98d1,0xff2b98d1,
+ 0xff2b98d1,0xff2a98d2,0xff2a98d2,0xff2a97d2,0xff2997d2,0xff2897d2,0xff2896d2,0xff2897d3,0xff2897d3,0xff2797d3,0xff2797d4,0xff2696d4,0xff2697d5,0xff2696d5,
+ 0xff2696d5,0xff2596d5,0xff2596d5,0xff2497d7,0xff2498d8,0xff2599da,0xff249bdd,0xff249ce0,0xff259ee3,0xff24a0e7,0xff25a3eb,0xff25a4ee,0xff24a7f2,0xff25a9f5,
+ 0xff25abf8,0xff24adfa,0xff25aefc,0xff26affd,0xff26affe,0xff28b0fe,0xff28b1ff,0xff28b2ff,0xff28b1ff,0xff29b2ff,0xff3fbdff,0xff41bdff,0xff40bfff,0xff41bdff,
+ 0xff41c0ff,0xff41bfff,0xff41c0ff,0xff43c0ff,0xff46c1ff,0xff49c3ff,0xff4ec4ff,0xff53c5fe,0xff5dc9ff,0xff68ccfe,0xff74d1fe,0xff83d5fe,0xff92dbfe,0xffa2e0fe,
+ 0xffacdef7,0xffadd2e3,0xffc28b49,0xffd66e00,0xffefb240,0xffffe971,0xffffff82,0xffffff83,0xffffff83,0xffffff84,0xffffff98,0xfffffe6a,0xfffefd68,0xfffdfb67,
+ 0xfffdfb67,0xfffbf965,0xfff9f664,0xfff7f462,0xfff4ee5f,0xfff1dc57,0xffe9c24c,0xffca8227,0xffa93d00,0xff9e4411,0xff816555,0xff6d8694,0xff7092a5,0xff71a0b9,
+ 0xff6fabcc,0xff66afd7,0xff59acd9,0xff4da8da,0xff44a5db,0xff3ea3dc,0xff37a1dc,0xff35a1de,0xff33a1e0,0xff32a3e1,0xff31a2e2,0xff31a3e3,0xff30a4e4,0xff2fa3e3,
+ 0xff2fa1e3,0xff2fa0e2,0xff2e9fe1,0xff2d9ddf,0xff2c9bdd,0xff2c9bdd,0xff2c9adb,0xff2b99db,0xff2b99da,0xff2b98da,0xff2b97d9,0xff2a97d9,0xff2997d9,0xff2896da,
+ 0xff2896da,0xff2896da,0xff2796da,0xff2895db,0xff2895db,0xff2795db,0xff2796dc,0xff2795dc,0xff2695dc,0xff2595dc,0xff2594dc,0xff2594dc,0xff2493db,0xff2393db,
+ 0xff2393db,0xff2392db,0xff2292db,0xff2292db,0xff2292db,0xff2292db,0xff2191db,0xff2190db,0xff2090db,0xff2090db,0xff2090db,0xff1f90dc,0xff1f90dc,0xff1f90dc,
+ 0xff1f8fdd,0xff1e8fdd,0xff1e8fdd,0xff1d8fdd,0xff1d8edd,0xff1d8edd,0xff1c8fde,0xff1d8fdf,0xff1c8fe0,0xff1c90e1,0xff1c90e3,0xff1c91e5,0xff1c93e9,0xff1c95ec,
+ 0xff1c97ef,0xff1b98f1,0xff1b9af5,0xff1b9bf7,0xff1b9bf9,0xff1b9dfb,0xff1c9efd,0xff1c9ffd,0xff1c9ffe,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,
+ 0xff4fcaff,0xff50caff,0xff50cbff,0xff51cbff,0xff52cbff,0xff52ccff,0xff52ccff,0xff54ccff,0xff66d1ff,0xff58ceff,0xff5acfff,0xff5fd1ff,0xff66d2ff,0xff6dd5fe,
+ 0xff76d7fe,0xff82dbfe,0xffb0e7fe,0xffb0e8fe,0xffaae5fd,0xffc3eafa,0xffbfdce8,0xffbb9463,0xffd26800,0xffe29028,0xffffe579,0xfffffc90,0xffffff93,0xffffff94,
+ 0xffffffa4,0xffffff75,0xfffefe73,0xfffdfd72,0xfffdfd71,0xfffcfc6f,0xfffaf76b,0xfff9e45f,0xfff2c84f,0xffd38729,0xffb44804,0xffac4309,0xff8d6951,0xff788f9a,
+ 0xff7d9ca9,0xff83abbd,0xff84b8cf,0xff81c0dc,0xff78c0e1,0xff6bbce1,0xff6ebde2,0xff56b6e2,0xff50b5e4,0xff4ab4e4,0xff46b2e5,0xff42b1e4,0xff41b3e7,0xff41b2e8,
+ 0xff40b4e9,0xff40b2e9,0xff3fb3ea,0xff3fb2e9,0xff3eb2e9,0xff3eb2e9,0xff3eb1e8,0xff4eb4e6,0xff3bade5,0xff4cb3e5,0xff3aade4,0xff3aabe3,0xff3aaae2,0xff39aae2,
+ 0xff38aae2,0xff38a9e2,0xff37a9e2,0xff37a9e2,0xff36a9e2,0xff35a8e2,0xff35a8e2,0xff35a8e3,0xff35a9e3,0xff45aee3,0xff34a8e4,0xff33a8e4,0xff33a7e4,0xff32a7e4,
+ 0xff32a7e4,0xff32a7e4,0xff31a6e3,0xff31a6e3,0xff30a6e3,0xff2fa6e3,0xff2fa5e3,0xff2fa5e3,0xff2ea5e3,0xff2da5e3,0xff2da4e3,0xff2da4e3,0xff3eaae3,0xff3fa9e3,
+ 0xff2ba3e3,0xff2ba4e4,0xff2aa3e4,0xff50b0e4,0xff3da9e4,0xff29a3e5,0xff29a3e5,0xff29a3e5,0xff28a2e5,0xff28a2e5,0xff28a2e5,0xff28a1e6,0xff27a2e7,0xff26a3e9,
+ 0xff26a3e9,0xff26a5ec,0xff26a5ed,0xff26a8f0,0xff26a8f2,0xff25aaf5,0xff26aaf7,0xff50bbf9,0xff25adfb,0xff25aefc,0xff3bb7fd,0xff26b0fe,0xff26affe,0xff28b1ff,
+ 0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff64ccff,0xff45c1ff,
+ 0xff48c2ff,0xff4bc3ff,0xff50c4fe,0xff57c8ff,0xff5fcbfe,0xff6acdfe,0xff8ddbfe,0xff83d6fe,0xffa5e2fe,0xffa1e0fe,0xffade0f9,0xffb8d9e8,0xffb39b7e,0xffcf6300,
+ 0xffe08b2a,0xffffdb7a,0xfffffca0,0xffffffa4,0xffffffb0,0xffffff82,0xffffff81,0xfffefe7f,0xfffdfd7e,0xfffdec6e,0xfffcd55c,0xffe19a36,0xffbf530a,0xffb54100,
+ 0xff96664a,0xff7d8c93,0xff7e9bab,0xff85acc1,0xff8abbd6,0xff86c2e2,0xff7dc3e8,0xff72c0ea,0xff66bbea,0xff5ab6e9,0xff5cb9ea,0xff47afe9,0xff41afeb,0xff3babea,
+ 0xff3aacec,0xff36aced,0xff35abed,0xff34acee,0xff34acef,0xff34acef,0xff33acf0,0xff33aaf0,0xff32aaef,0xff32a9ef,0xff31a8ee,0xff51b4ed,0xff2fa7ec,0xff3facec,
+ 0xff2fa5eb,0xff2ea4ea,0xff2ea3ea,0xff2ea3e9,0xff2da3e9,0xff2da2e9,0xff2ca2e9,0xff2ca1e9,0xff2ba1e9,0xff2ba1e9,0xff2aa2ea,0xff2aa0ea,0xff2aa0ea,0xff49adea,
+ 0xff299feb,0xff29a0eb,0xff299feb,0xff299feb,0xff289feb,0xff279feb,0xff279dea,0xff279dea,0xff269dea,0xff269dea,0xff259cea,0xff259cea,0xff259cea,0xff249cea,
+ 0xff249bea,0xff249bea,0xff239aea,0xff32a2ea,0xff229aea,0xff219beb,0xff219aeb,0xff42aaeb,0xff42aaeb,0xff2099ec,0xff2099ec,0xff2098ec,0xff1f99ec,0xff1f98ec,
+ 0xff1e98ed,0xff1e97ed,0xff1e97ed,0xff1e98ee,0xff1e98ef,0xff1d99f1,0xff1d9af2,0xff1d9af4,0xff1d9bf6,0xff1c9df8,0xff3faff9,0xff1c9dfb,0xff1b9efc,0xff1b9ffd,
+ 0xff40b1fd,0xff1ca0fe,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1ea2ff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff74d6ff,0xff73d5ff,0xff74d6ff,0xff62d0ff,0xff75d6ff,
+ 0xff76d6ff,0xff65d1ff,0xff76d6fe,0xff65d1fe,0xff68d3ff,0xff6ad3ff,0xff7cd9fe,0xff81dafe,0xff77d7ff,0xff6ed5fe,0xff93dffe,0xff81dafd,0xff8dddfd,0xff9be1fd,
+ 0xffb0e7fd,0xffb9e7f9,0xffb3dbeb,0xffb69d80,0xffcb5d00,0xffd47016,0xfffcd07a,0xfffff6a9,0xffffffbd,0xffffff91,0xffffff8f,0xfffeeb7b,0xfffed363,0xffecaa46,
+ 0xffc2550b,0xffb84300,0xffa35f38,0xff8b8c8b,0xff8ca3ac,0xff94b4c3,0xffa2c7d7,0xffa6d3e7,0xff98d4ee,0xff9cd7f1,0xff7bccf0,0xff8ad0f0,0xff67c5f0,0xff6ec8f0,
+ 0xff77caf0,0xff52c0f1,0xff7ecdf1,0xff6bc6f0,0xff6ac6f1,0xff55bff0,0xff67c5f2,0xff67c7f3,0xff55c1f4,0xff43bcf4,0xff42bbf4,0xff42bbf4,0xff53c0f4,0xff65c5f4,
+ 0xff64c4f3,0xff63c4f2,0xff3fb8f2,0xff73c7f1,0xff3db6f1,0xff61c2f1,0xff60c1f0,0xff60c1f0,0xff4dbaf0,0xff60c0f0,0xff5fc0f0,0xff5ebff0,0xff4bb9f0,0xff5ebff0,
+ 0xff5dbff0,0xff4bb9f0,0xff5ebff1,0xff6fc5f1,0xff4ab8f1,0xff49b9f1,0xff5cbff1,0xff5bbef1,0xff48b8f1,0xff6dc4f1,0xff5abef1,0xff59bdf1,0xff59bdf1,0xff32b0f1,
+ 0xff32aff1,0xff59bcf1,0xff31aff1,0xff31aef1,0xff30aef1,0xff30aef1,0xff2faef1,0xff2eadf1,0xff2eadf1,0xff2dadf1,0xff54baf1,0xff2dacf1,0xff54baf1,0xff54baf1,
+ 0xff53b9f1,0xff3eb2f1,0xff52b9f1,0xff52b8f1,0xff53b8f2,0xff29abf2,0xff66c0f2,0xff51b9f3,0xff3cb3f4,0xff51b9f5,0xff50baf6,0xff50bbf7,0xff26adf9,0xff26acf9,
+ 0xff51befb,0xff26aefc,0xff51befd,0xff50befd,0xff67c7fe,0xff3cb8ff,0xff52c0ff,0xff52c1ff,0xff3db9ff,0xff53c1ff,0xff29b2ff,0xff54c1ff,0xff3fbdff,0xff60cbff,
+ 0xff61ccff,0xff61ccff,0xff41bfff,0xff62ccff,0xff62ccff,0xff63ccff,0xff74d3ff,0xff63cbfe,0xff43c0fe,0xff66cfff,0xff68cfff,0xff6bcffe,0xff6fd0fe,0xff57c8fe,
+ 0xff7bd4fe,0xff68ccfd,0xff75d3fe,0xff82d6fe,0xffa3e1fe,0xff9dddfd,0xffabe1fc,0xffadd8ed,0xffb0b0a9,0xffc35c0b,0xffd16b17,0xfffbc578,0xfffff5bb,0xffffeb88,
+ 0xffffd06b,0xffeea94a,0xffcb6517,0xffba4300,0xffa95626,0xff888481,0xff8da2ad,0xff93b2c1,0xffa4c7d8,0xff92cbe9,0xff9ed6f3,0xff98d6f7,0xff8ed2f5,0xff78c9f4,
+ 0xff6fc6f4,0xff74c8f4,0xff54bdf5,0xff4bb8f4,0xff62c1f4,0xff40b4f4,0xff5cc0f5,0xff3bb3f5,0xff59bff5,0xff58bff6,0xff36b1f6,0xff57c0f7,0xff35b1f7,0xff35b2f8,
+ 0xff35b2f8,0xff35b0f8,0xff56bef8,0xff33aff7,0xff32aef7,0xff54bbf6,0xff31aef6,0xff53b9f5,0xff31acf5,0xff51b9f5,0xff30abf5,0xff30abf5,0xff3eb2f5,0xff61bff5,
+ 0xff50b8f5,0xff60bff5,0xff4fb8f5,0xff2da9f5,0xff2ca9f5,0xff2ca7f5,0xff2ca7f5,0xff4eb6f5,0xff2ba6f5,0xff4cb6f5,0xff2aa6f5,0xff29a6f5,0xff4bb5f5,0xff4ab5f5,
+ 0xff28a5f5,0xff38acf5,0xff49b4f5,0xff27a4f5,0xff26a4f5,0xff49b3f5,0xff26a3f5,0xff25a2f5,0xff25a2f5,0xff25a2f5,0xff25a2f5,0xff24a1f5,0xff24a1f5,0xff23a1f5,
+ 0xff46b1f5,0xff23a0f5,0xff45b0f5,0xff22a0f5,0xff229ff6,0xff44b1f6,0xff44aff6,0xff209ef6,0xff43aff6,0xff1f9df6,0xff42aef7,0xff42adf7,0xff41aff8,0xff55b8f9,
+ 0xff41aff9,0xff54b8fa,0xff1d9efb,0xff2ea7fc,0xff2fa8fd,0xff1c9ffd,0xff40b1fd,0xff1b9ffe,0xff41b1fe,0xff1ca0ff,0xff41b2ff,0xff41b3ff,0xff41b3ff,0xff30abff,
+ 0xff31abff,0xff43b3ff,0xff50caff,0xff73d5ff,0xff74d5ff,0xff74d6ff,0xff74d6ff,0xff52ccff,0xff53cbff,0xff76d6ff,0xff76d7ff,0xff66d1ff,0xff67d2ff,0xff77d6fe,
+ 0xff57cfff,0xff5bcfff,0xff6dd6ff,0xff61d1fe,0xff85dcfe,0xff6dd4fe,0xff76d8fe,0xff9ae1fe,0xff8cddfe,0xff98e0fe,0xffa3e3fd,0xffafe5fb,0xffbfe1ef,0xffadb3ad,
+ 0xffc0560b,0xffca5f10,0xfff3af69,0xfff7b65c,0xffd26f20,0xffbb4500,0xffb1521c,0xff8f8076,0xff859faa,0xff8eb0be,0xffa4c7d6,0xff9cd2ea,0xffa2dbf4,0xffa7e1fa,
+ 0xff88d6f9,0xff7ed3f8,0xff90d8f8,0xff6dccf7,0xff82d3f7,0xff6dccf7,0xff58c6f7,0xff54c5f8,0xff73cff9,0xff4dc3f9,0xff6fcef9,0xff49c2f9,0xff6cccf9,0xff46c0f9,
+ 0xff7bd1f9,0xff58c5f9,0xff45c0fa,0xff45c0fa,0xff44c0fa,0xff44bffa,0xff68cbfa,0xff43befa,0xff54c4fa,0xff67c9f9,0xff40bcf9,0xff66c8f9,0xff40bcf9,0xff65c8f9,
+ 0xff3fbbf9,0xff3ebbf9,0xff3ebbf9,0xff64c8f9,0xff3dbbf9,0xff4ec0f9,0xff62c6f9,0xff3bbaf9,0xff3bbaf9,0xff4dbff9,0xff3ab9f9,0xff60c5f9,0xff4cbef9,0xff60c5f9,
+ 0xff38b8f9,0xff37b8f9,0xff5ec4f9,0xff5dc4f9,0xff36b7f9,0xff35b6f9,0xff47bcf9,0xff5cc3f9,0xff5cc3f9,0xff5bc2f9,0xff33b5f9,0xff32b4f9,0xff32b4f9,0xff31b4f9,
+ 0xff31b4f9,0xff30b3f9,0xff30b3f9,0xff43baf9,0xff42b9f9,0xff2fb2f9,0xff57bff9,0xff2db1f9,0xff2db1f9,0xff56bff9,0xff55bff9,0xff2cb0f9,0xff55bef9,0xff2aaff9,
+ 0xff53bdf9,0xff53bdfa,0xff53bdfa,0xff53befb,0xff28aefb,0xff3db8fc,0xff28b0fd,0xff51befd,0xff26b0fd,0xff26affe,0xff52bffe,0xff25affe,0xff67c8ff,0xff52c0ff,
+ 0xff27b0ff,0xff27b1ff,0xff53c1ff,0xff28b2ff,0xff53c1ff,0xff3fbaff,0xff3fbdff,0xff50c3ff,0xff40bfff,0xff50c5ff,0xff41bfff,0xff62ccff,0xff63ccff,0xff52c7ff,
+ 0xff52c7ff,0xff44c1ff,0xff54c7ff,0xff44c0fe,0xff64cdfe,0xff67cfff,0xff48c2fe,0xff4cc4fe,0xff70d0fe,0xff57c9fe,0xff6dd1fe,0xff81d5fd,0xff89d8fd,0xff88d7fd,
+ 0xff8ad7fd,0xff97dbfd,0xffb3e5fc,0xffaadaf2,0xffa6afaf,0xffb75d21,0xffc35208,0xffbd4700,0xffb44d13,0xff927462,0xff839da9,0xff92b0be,0xff9cc2d4,0xff9dcfe9,
+ 0xff9ad7f4,0xff9edcfa,0xff8bd5fb,0xff77cefc,0xff85d3fb,0xff7fd2fc,0xff6ac9fb,0xff55c0fa,0xff5ec4fb,0xff4abdfb,0xff45bafa,0xff60c5fa,0xff5ec4fa,0xff4cbefb,
+ 0xff49bdfb,0xff3ab6fb,0xff48bcfb,0xff5ac4fc,0xff48bdfc,0xff59c3fc,0xff47bbfc,0xff36b5fc,0xff36b5fc,0xff36b4fd,0xff34b3fc,0xff57c1fc,0xff44b9fc,0xff43b9fc,
+ 0xff43b8fc,0xff54c0fc,0xff54befb,0xff42b6fb,0xff31affb,0xff30affb,0xff30affb,0xff40b6fb,0xff52bdfb,0xff3fb5fb,0xff2eaefb,0xff50bcfb,0xff50bcfb,0xff2dabfb,
+ 0xff2dabfb,0xff3db4fb,0xff3db4fb,0xff2babfb,0xff4eb9fb,0xff4ebafb,0xff2aaafb,0xff3bb1fb,0xff29a8fb,0xff29a9fb,0xff39b0fb,0xff27a8fb,0xff27a8fb,0xff4bb7fb,
+ 0xff27a7fb,0xff27a6fb,0xff26a6fb,0xff26a6fb,0xff25a6fb,0xff24a5fb,0xff24a4fb,0xff48b5fb,0xff23a4fb,0xff23a4fb,0xff34acfc,0xff23a3fc,0xff22a3fc,0xff32abfc,
+ 0xff32abfc,0xff45b3fc,0xff32abfc,0xff20a2fc,0xff31aafc,0xff20a1fc,0xff30aafc,0xff31aafd,0xff41b2fd,0xff30aafd,0xff30a9fd,0xff2fa9fd,0xff1c9ffe,0xff1ca0fe,
+ 0xff2ea9ff,0xff41b1ff,0xff2ea9ff,0xff1ca1ff,0xff41b2ff,0xff42b3ff,0xff2faaff,0xff1ea1ff,0xff31abff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff50caff,0xff51caff,
+ 0xff51ccff,0xff52cbff,0xff53ccff,0xff53ccff,0xff54cdff,0xff54ccff,0xff54cdff,0xff55cdff,0xff56ccfe,0xff57ceff,0xff58cfff,0xff5bcffe,0xff7edaff,0xff82dafe,
+ 0xff65d2fe,0xff6dd5fe,0xff75d7fe,0xff7dd9fe,0xff92dffd,0xffa7e5fd,0xffa7e5fe,0xffa7e3fc,0xffa9ddf2,0xff9fc0cc,0xffae663a,0xff9d7053,0xff7d9ba8,0xff87aab9,
+ 0xff92bed0,0xff9acfe6,0xff9ddaf5,0xff96ddfb,0xff8edafc,0xff85d8fb,0xff7cd5fc,0xff74d3fd,0xff6cd0fc,0xff65cdfb,0xff5fcbfb,0xff5bcafc,0xff56c9fc,0xff53c8fc,
+ 0xff4fc6fc,0xff4ec6fc,0xff4cc5fd,0xff4ac4fc,0xff4ac5fd,0xff48c3fd,0xff47c4fd,0xff47c3fd,0xff6ccefd,0xff6bcefd,0xff45c2fd,0xff44c2fd,0xff44c2fd,0xff44c1fd,
+ 0xff43c1fd,0xff43c1fd,0xff42c0fd,0xff42c0fd,0xff41c0fd,0xff40c0fd,0xff40bffd,0xff40bffd,0xff40befd,0xff40befd,0xff3fbefd,0xff3fbefd,0xff3ebefd,0xff3dbdfd,
+ 0xff3dbdfd,0xff3dbdfd,0xff3cbdfd,0xff3cbdfd,0xff3bbcfd,0xff3bbcfd,0xff3abbfd,0xff3abbfd,0xff39bbfd,0xff38bbfd,0xff38bafd,0xff38bafd,0xff37b9fd,0xff36b9fd,
+ 0xff35b9fd,0xff5dc6fd,0xff5dc5fd,0xff34b8fd,0xff34b8fd,0xff33b7fd,0xff33b7fd,0xff32b7fd,0xff32b7fd,0xff32b6fd,0xff31b6fd,0xff45bdfd,0xff2fb5fd,0xff2fb5fd,
+ 0xff2eb5fd,0xff2eb4fd,0xff2eb4fd,0xff2db3fd,0xff2db3fd,0xff2cb3fd,0xff2bb3fd,0xff2bb2fd,0xff2ab2fd,0xff2ab1fd,0xff2ab1fd,0xff29b1fd,0xff29b0fe,0xff28b0fe,
+ 0xff3eb8fe,0xff27b0fe,0xff27b1ff,0xff26b0ff,0xff25b0ff,0xff25b0ff,0xff26b0ff,0xff26b1ff,0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,
+ 0xff40bdff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff42bfff,0xff42c0ff,0xff43c1ff,0xff43c0ff,0xff43c1ff,0xff45c2ff,0xff44c1ff,0xff45c2ff,
+ 0xff47c3ff,0xff48c3ff,0xff4bc4ff,0xff4dc4fe,0xff51c5fe,0xff56c9fe,0xff5dc9fe,0xff65cdfe,0xff6ecffe,0xff78d2fe,0xff82d5fd,0xff8dd9fe,0xff95dafc,0xff98d7f6,
+ 0xff90c6e1,0xff83b4cc,0xff84b6cf,0xff8cc5e2,0xff90d2f4,0xff8dd6fb,0xff85d4fd,0xff7cd2fe,0xff73cefe,0xff6acbfe,0xff61c8fe,0xff5bc5fe,0xff53c2fd,0xff4ec0fd,
+ 0xff49bffd,0xff46bdfd,0xff42bcfd,0xff3ebafd,0xff3eb9fd,0xff3cbafe,0xff3cbafe,0xff3ab8fd,0xff3ab8fe,0xff3ab8fe,0xff3ab8fe,0xff39b7fe,0xff38b6fe,0xff38b6fe,
+ 0xff37b6fe,0xff36b6fe,0xff36b4fe,0xff36b4fe,0xff36b4fe,0xff35b4fe,0xff34b4fe,0xff34b3fe,0xff33b3fe,0xff33b3fe,0xff33b2fe,0xff32b1fe,0xff32b1fe,0xff32b1fe,
+ 0xff31b1fe,0xff31b1fe,0xff30b1fe,0xff2faffe,0xff2faffe,0xff2faffe,0xff2eaffe,0xff2eaffe,0xff2eadfe,0xff2eadfe,0xff2dacfe,0xff2cacfe,0xff2cacfe,0xff2babfe,
+ 0xff2babfe,0xff2babfe,0xff2aaafe,0xff2aabfe,0xff29aafe,0xff28aafe,0xff28a9fe,0xff28a9fe,0xff28a9fe,0xff27a8fe,0xff26a8fe,0xff26a8fe,0xff26a7fe,0xff26a7fe,
+ 0xff24a6fe,0xff24a7fe,0xff24a6fe,0xff24a6fe,0xff24a6fe,0xff24a4fe,0xff23a4fe,0xff22a4fe,0xff21a3fe,0xff21a3fe,0xff21a3fe,0xff20a2fe,0xff20a2fe,0xff20a1fe,
+ 0xff1fa1fe,0xff1fa1fe,0xff1fa0fe,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1ca1ff,0xff1da1ff,
+ 0xff1da1ff,0xff1ea2ff,0xff1fa2ff,0xff1fa3ff,0xff4fcaff,0xff84daff,0xff51cbff,0xff86daff,0xff52ccff,0xff52ccff,0xff52ccff,0xff53ccff,0xff76d6ff,0xff54ccff,
+ 0xff54cdff,0xff55cdff,0xff56ceff,0xff78d8ff,0xff56cfff,0xff58ceff,0xff59cffe,0xff5bd0ff,0xff5ed1ff,0xff61d2ff,0xff65d2fe,0xff6bd4fe,0xff70d5fe,0xff78d8fe,
+ 0xff7ed9fd,0xff87dbfe,0xff8eddfe,0xff93defd,0xff93dbf8,0xff90d5f2,0xffaedff3,0xff90dafa,0xff8cdcfd,0xff92ddfd,0xff99e0fe,0xff77d5fd,0xff70d3fd,0xff69d0fd,
+ 0xff63cffe,0xff5fcefe,0xff5accfe,0xff79d5fe,0xff54c9fe,0xff51c9fe,0xff4fc8fe,0xff4dc8fe,0xff4cc7fe,0xff4bc6fe,0xff4ac7ff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,
+ 0xff48c5ff,0xff48c5ff,0xff47c4ff,0xff47c5ff,0xff47c4ff,0xff46c4ff,0xff45c3ff,0xff44c3ff,0xff45c3ff,0xff43c3ff,0xff43c2ff,0xff43c1ff,0xff42c2ff,0xff41c1ff,
+ 0xff42c1ff,0xff40c0ff,0xff40c1ff,0xff3fc0ff,0xff3fc0ff,0xff3ec0ff,0xff3ebfff,0xff3ebeff,0xff3dbfff,0xff3cbfff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3abcff,
+ 0xff3abdff,0xff3abcff,0xff39bcff,0xff38bbff,0xff38bcff,0xff37bbff,0xff37baff,0xff36bbff,0xff36baff,0xff35baff,0xff34baff,0xff34b9ff,0xff34b9ff,0xff34b9ff,
+ 0xff33b8ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff31b6ff,0xff30b6ff,0xff30b6ff,0xff30b6ff,0xff2eb6ff,0xff2eb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2cb4ff,
+ 0xff2bb3ff,0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff29b2ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff25b0ff,0xff25b0ff,
+ 0xff25b0ff,0xff26b0ff,0xff27b0ff,0xff27b0ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff3fbcff,0xff71d0ff,0xff60ccff,0xff72d0ff,0xff41c0ff,0xff62ccff,
+ 0xff63ccff,0xff42c0ff,0xff63ccff,0xff44c0ff,0xff54c7ff,0xff45c2ff,0xff55c8ff,0xff55c8ff,0xff45c2ff,0xff56c9ff,0xff68cfff,0xff58cbff,0xff4bc5fe,0xff6cd0fe,
+ 0xff5fccff,0xff63ccfe,0xff59c8fe,0xff5ec9fe,0xff65ccfe,0xff6bcdfd,0xff8ad8fd,0xff8dd9fd,0xff79d1fd,0xff7ad2fe,0xff8fdafd,0xff75d0fe,0xff70cffe,0xff6acdfe,
+ 0xff7ed4fe,0xff5dc5fd,0xff57c4fe,0xff52c2fe,0xff4cc0fe,0xff48bffe,0xff55c3fe,0xff52c3fe,0xff40bbfe,0xff4ec2fe,0xff5ec7fe,0xff4dc1ff,0xff3bbaff,0xff3bbaff,
+ 0xff3abaff,0xff3abaff,0xff49c0ff,0xff5bc6ff,0xff49c0ff,0xff49bfff,0xff38b8ff,0xff37b8ff,0xff48bdff,0xff47bdff,0xff58c5ff,0xff47bcff,0xff35b5ff,0xff35b5ff,
+ 0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff31b2ff,0xff31b2ff,0xff30b1ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,
+ 0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2daeff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2bacff,0xff2aacff,0xff29abff,0xff29abff,0xff29aaff,
+ 0xff28abff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff24a5ff,
+ 0xff23a4ff,0xff22a5ff,0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea2ff,0xff1ea2ff,0xff1ea1ff,0xff1da0ff,
+ 0xff1da0ff,0xff1ca1ff,0xff1c9fff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff73d5ff,
+ 0xff74d5ff,0xff74d6ff,0xff62d0ff,0xff52cbff,0xff52cbff,0xff76d6ff,0xff76d7ff,0xff76d6ff,0xff54cdff,0xff55ceff,0xff55ceff,0xff79d8ff,0xff57cfff,0xff8addff,
+ 0xff58cfff,0xff7bd9ff,0xff7cd9ff,0xff5cd1ff,0xff7fdaff,0xff5ed0fe,0xff62d2ff,0xff65d2fe,0xff69d3fd,0xff7bd7fd,0xff71d5fe,0xff74d4fd,0xff90ddfd,0xff75d5fd,
+ 0xff90ddfd,0xff72d4fe,0xff6fd4fe,0xff6ad2fe,0xff84dafe,0xff61cffe,0xff5dccfd,0xff59ccfe,0xff56cbfe,0xff54cbfe,0xff51c9fe,0xff74d5ff,0xff4ec8fe,0xff82d9ff,
+ 0xff4cc8ff,0xff6fd3ff,0xff4cc8ff,0xff4bc7ff,0xff4ac6ff,0xff4ac6ff,0xff6ed1ff,0xff49c6ff,0xff5accff,0xff6dd1ff,0xff48c5ff,0xff47c4ff,0xff6cd0ff,0xff6bd0ff,
+ 0xff45c4ff,0xff58c9ff,0xff45c3ff,0xff43c3ff,0xff43c2ff,0xff43c2ff,0xff42c2ff,0xff42c2ff,0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff3fc0ff,0xff3fc0ff,0xff3fbfff,
+ 0xff3ebfff,0xff3dbfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff39bcff,0xff39bcff,0xff39bcff,0xff38bcff,0xff38bbff,
+ 0xff37baff,0xff36baff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff33b9ff,0xff33b8ff,0xff33b7ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,
+ 0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb5ff,0xff2db5ff,0xff2db4ff,0xff2db4ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,
+ 0xff29b2ff,0xff28b1ff,0xff28b1ff,0xff27b0ff,0xff26b1ff,0xff26b1ff,0xff26b0ff,0xff25b0ff,0xff25b0ff,0xff26b1ff,0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,
+ 0xff28b1ff,0xff29b2ff,0xff40bdff,0xff60cbff,0xff41bfff,0xff61ccff,0xff51c5ff,0xff62ccff,0xff63ccff,0xff63ccff,0xff74d3ff,0xff63cdff,0xff44c1ff,0xff44c1ff,
+ 0xff45c2ff,0xff65ceff,0xff46c2ff,0xff66ceff,0xff47c3ff,0xff67cfff,0xff59cbff,0xff69cfff,0xff69cffe,0xff4bc4ff,0xff4dc4fe,0xff4fc5fe,0xff52c5fe,0xff63ccfe,
+ 0xff75d2fe,0xff76d3fe,0xff77d3fe,0xff5bc8fe,0xff76d2fe,0xff58c7fe,0xff54c5fe,0xff51c4fe,0xff6ccffe,0xff4bc2fe,0xff48bffe,0xff45befe,0xff43befe,0xff41bcfe,
+ 0xff40beff,0xff60c9ff,0xff3dbbfe,0xff5ec8ff,0xff3cbbff,0xff5dc8ff,0xff3cbaff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,0xff5bc6ff,0xff49c0ff,0xff5bc6ff,
+ 0xff38b7ff,0xff49bfff,0xff59c5ff,0xff37b7ff,0xff59c3ff,0xff47bcff,0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff34b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,
+ 0xff33b2ff,0xff32b2ff,0xff31b1ff,0xff31b2ff,0xff30b1ff,0xff2fb1ff,0xff2fb1ff,0xff2eb1ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2daeff,0xff2daeff,0xff2dadff,
+ 0xff2cadff,0xff2cadff,0xff2badff,0xff2bacff,0xff2aabff,0xff2aabff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27a9ff,
+ 0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a7ff,0xff23a5ff,0xff23a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff21a3ff,
+ 0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea2ff,0xff1da1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,
+ 0xff1da0ff,0xff1da0ff,0xff1ea1ff,0xff1fa2ff,0xff1ea2ff,0xff1fa2ff,0xff50caff,0xff73d6ff,0xff51caff,0xff74d6ff,0xff63d1ff,0xff75d6ff,0xff76d6ff,0xff76d6ff,
+ 0xff76d7ff,0xff54cdff,0xff77d7ff,0xff56cdff,0xff78d8ff,0xff89ddff,0xff68d4ff,0xff79d9ff,0xff58cfff,0xff7ad9ff,0xff6ad4ff,0xff7cd9ff,0xff7bd8fe,0xff5ad0ff,
+ 0xff5acffe,0xff5bcffe,0xff5dd0fe,0xff6ed5fe,0xff7fd9fe,0xff7fd8fd,0xff81d9fe,0xff70d5fe,0xff8edcfd,0xff7fd8fe,0xff5dcefe,0xff7bd7fe,0xff8adafe,0xff67d0fe,
+ 0xff54cafe,0xff52cafe,0xff50caff,0xff50caff,0xff72d3fe,0xff83d9ff,0xff60ceff,0xff71d3ff,0xff4cc8ff,0xff70d3ff,0xff4cc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,
+ 0xff6fd2ff,0xff6ed1ff,0xff6dd1ff,0xff47c5ff,0xff6dd1ff,0xff59cbff,0xff6cd0ff,0xff6bd0ff,0xff6ad0ff,0xff6ad0ff,0xff45c3ff,0xff44c2ff,0xff44c2ff,0xff42c2ff,
+ 0xff42c2ff,0xff42c2ff,0xff42c1ff,0xff40c1ff,0xff40c0ff,0xff3fc0ff,0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3dbfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,
+ 0xff3bbdff,0xff3abdff,0xff3abdff,0xff39bdff,0xff39bcff,0xff38bcff,0xff38bcff,0xff37bbff,0xff37bbff,0xff37baff,0xff36baff,0xff35b9ff,0xff35baff,0xff34b9ff,
+ 0xff34b9ff,0xff33b9ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,
+ 0xff2cb4ff,0xff2cb3ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff2ab2ff,0xff2ab2ff,0xff29b2ff,0xff29b1ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,
+ 0xff26b0ff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff27b2ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff41bdff,0xff41bfff,
+ 0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff43c0ff,0xff43c1ff,0xff44c1ff,0xff44c2ff,0xff45c1ff,0xff46c2ff,0xff46c2ff,0xff46c3ff,0xff46c3ff,0xff47c5ff,
+ 0xff58c9ff,0xff68cfff,0xff67cefe,0xff59c9ff,0xff48c3ff,0xff48c3fe,0xff49c2fe,0xff49c3fe,0xff4bc3fe,0xff4ac2fe,0xff4bc3fe,0xff4ac3fe,0xff48c2fd,0xff48c0fd,
+ 0xff47c0fe,0xff45c1fe,0xff44c0fe,0xff43bffe,0xff42beff,0xff41bdff,0xff40bcfe,0xff3fbcff,0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff3dbcff,0xff3cbbff,0xff3cbbff,
+ 0xff3bbaff,0xff3bbbff,0xff3abaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff39b8ff,0xff49bfff,0xff5bc6ff,0xff59c5ff,0xff48bdff,0xff37b5ff,0xff36b7ff,0xff36b5ff,
+ 0xff36b5ff,0xff35b5ff,0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff33b2ff,0xff33b3ff,0xff32b2ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff2fb0ff,
+ 0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2dadff,0xff2dadff,0xff2cadff,0xff2bacff,0xff2badff,0xff2aacff,0xff2aacff,0xff2aacff,
+ 0xff29abff,0xff29aaff,0xff28abff,0xff28aaff,0xff28a9ff,0xff27aaff,0xff27aaff,0xff26a9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,
+ 0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff22a5ff,0xff21a5ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,
+ 0xff1da1ff,0xff1ea1ff,0xff1da0ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,0xff1ca0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,
+ 0xff4fc9ff,0xff50caff,0xff50cbff,0xff51caff,0xff51cbff,0xff53ccff,0xff53ccff,0xff53ccff,0xff54ccff,0xff54ccff,0xff55cdff,0xff56cdff,0xff56ceff,0xff56ceff,
+ 0xff56cfff,0xff57ceff,0xff58cfff,0xff58d0ff,0xff59d0ff,0xff59d0ff,0xff58d0ff,0xff58cfff,0xff58cefe,0xff58cfff,0xff58cfff,0xff57cefe,0xff58cefe,0xff57cdfe,
+ 0xff57cdfe,0xff57ccfe,0xff56cdfe,0xff55cdfe,0xff55ccfe,0xff54cbfe,0xff52cafe,0xff52cbff,0xff50cafe,0xff50caff,0xff4fcaff,0xff4fcaff,0xff4ecaff,0xff4ec9ff,
+ 0xff4dc9ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,0xff4cc7ff,0xff4bc7ff,0xff4ac6ff,0xff4ac7ff,0xff4ac6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,0xff47c5ff,0xff47c4ff,
+ 0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff45c3ff,0xff44c3ff,0xff43c2ff,0xff43c2ff,0xff43c1ff,0xff42c1ff,0xff41c1ff,0xff41c1ff,0xff41c1ff,0xff40c0ff,
+ 0xff3fc0ff,0xff3fbfff,0xff3fbfff,0xff3ebfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff3abcff,0xff3abcff,0xff39bcff,0xff38bcff,
+ 0xff38bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff34b9ff,0xff34b8ff,0xff33b8ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff31b7ff,
+ 0xff31b7ff,0xff30b7ff,0xff30b6ff,0xff30b6ff,0xff2eb6ff,0xff2eb5ff,0xff2db5ff,0xff2db5ff,0xff2cb4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,
+ 0xff2ab2ff,0xff29b3ff,0xff29b1ff,0xff28b2ff,0xff28b1ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff26b0ff,0xff25afff,0xff26b0ff,0xff26b0ff,0xff26b0ff,0xff27b1ff,
+ 0xff28b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42c0ff,0xff42c0ff,0xff53c7ff,0xff43c1ff,
+ 0xff43c1ff,0xff45c1ff,0xff44c2ff,0xff45c2ff,0xff46c2ff,0xff46c3ff,0xff76d4ff,0xff67cfff,0xff48c3ff,0xff68cfff,0xff68cfff,0xff47c3ff,0xff56c9ff,0xff66cfff,
+ 0xff66cdfe,0xff45c1fe,0xff46c1ff,0xff44c0fe,0xff43c0fe,0xff43c0fe,0xff43bffe,0xff43c0ff,0xff52c5fe,0xff63cbfe,0xff61ccff,0xff50c5ff,0xff40bdff,0xff40bdff,
+ 0xff40bdff,0xff3fbcff,0xff4ec3ff,0xff3ebcff,0xff3dbbff,0xff3dbbff,0xff3cbbff,0xff3bbbff,0xff3bbbff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff49bfff,
+ 0xff39b8ff,0xff39b8ff,0xff39b7ff,0xff38b7ff,0xff37b7ff,0xff37b7ff,0xff37b5ff,0xff36b5ff,0xff35b5ff,0xff35b5ff,0xff34b5ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,
+ 0xff43baff,0xff32b3ff,0xff32b2ff,0xff42b9ff,0xff31b1ff,0xff31b1ff,0xff30b1ff,0xff2fb0ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eb0ff,0xff2eaeff,
+ 0xff2daeff,0xff2cadff,0xff3db5ff,0xff2cacff,0xff2aacff,0xff2bacff,0xff2aabff,0xff2aacff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27aaff,
+ 0xff26a9ff,0xff27a9ff,0xff26a8ff,0xff26a8ff,0xff25a8ff,0xff24a7ff,0xff49b8ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff46b7ff,0xff33adff,0xff21a4ff,
+ 0xff21a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,
+ 0xff41b2ff,0xff1ca0ff,0xff1da0ff,0xff1da0ff,0xff30aaff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff51caff,0xff51cbff,0xff52cbff,0xff52cbff,
+ 0xff52ccff,0xff53ccff,0xff76d6ff,0xff54cdff,0xff55cdff,0xff55ceff,0xff56cdff,0xff56ceff,0xff56ceff,0xff57cfff,0xff7ad9ff,0xff58cfff,0xff7ad9ff,0xff5ad0ff,
+ 0xff58cfff,0xff7ad9ff,0xff58cfff,0xff57cfff,0xff78d8ff,0xff56ceff,0xff56ceff,0xff66d2ff,0xff54cdff,0xff54ccff,0xff53ccff,0xff53cdff,0xff76d6ff,0xff52ccff,
+ 0xff51ccff,0xff51cbff,0xff51cbff,0xff50caff,0xff50caff,0xff4fcaff,0xff72d5ff,0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,0xff4bc8ff,0xff4cc8ff,0xff4bc7ff,
+ 0xff4bc7ff,0xff4ac6ff,0xff4ac6ff,0xff5bcbff,0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff47c5ff,0xff46c4ff,0xff46c4ff,0xff46c3ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,
+ 0xff43c2ff,0xff43c2ff,0xff42c1ff,0xff42c1ff,0xff68cdff,0xff40c1ff,0xff41c0ff,0xff53c6ff,0xff3fc0ff,0xff3ebfff,0xff3fbfff,0xff3dbfff,0xff3dbeff,0xff3dbeff,
+ 0xff3cbeff,0xff3bbeff,0xff3bbeff,0xff3abdff,0xff3abcff,0xff39bcff,0xff61caff,0xff39bcff,0xff37bcff,0xff37bbff,0xff37bbff,0xff37baff,0xff36baff,0xff35baff,
+ 0xff35baff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff32b7ff,0xff31b6ff,0xff31b6ff,0xff30b7ff,0xff44bdff,0xff2fb6ff,0xff2eb5ff,
+ 0xff57c4ff,0xff2db4ff,0xff57c3ff,0xff2cb4ff,0xff2bb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff29b3ff,0xff29b2ff,0xff29b1ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,
+ 0xff26b0ff,0xff26b0ff,0xff26afff,0xff25b0ff,0xff51c0ff,0xff26b0ff,0xff27b1ff,0xff27b0ff,0xff52c1ff,0xff29b1ff,0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff60ccff,
+ 0xff61ccff,0xff61cbff,0xff50c5ff,0xff62ccff,0xff63ccff,0xff52c6ff,0xff63cdff,0xff53c7ff,0xff54c7ff,0xff54c7ff,0xff65cdff,0xff65ceff,0xff56c8ff,0xff46c3ff,
+ 0xff66cfff,0xff47c3ff,0xff47c3ff,0xff48c5ff,0xff58c9ff,0xff58cbff,0xff46c3ff,0xff46c3ff,0xff65ceff,0xff45c2ff,0xff55c7ff,0xff75d3ff,0xff44c1ff,0xff43c1ff,
+ 0xff42c1ff,0xff42c0ff,0xff63ccff,0xff62ccff,0xff50c6ff,0xff41bfff,0xff71d0ff,0xff60cbff,0xff60cbff,0xff4fc2ff,0xff71d0ff,0xff5fc9ff,0xff3dbcff,0xff5ec8ff,
+ 0xff5ec8ff,0xff5dc8ff,0xff5dc7ff,0xff5cc7ff,0xff5cc7ff,0xff4ac1ff,0xff3abaff,0xff6dccff,0xff39b8ff,0xff5bc6ff,0xff5ac6ff,0xff5ac5ff,0xff48bdff,0xff59c5ff,
+ 0xff58c3ff,0xff58c3ff,0xff36b5ff,0xff34b5ff,0xff35b5ff,0xff34b4ff,0xff56c1ff,0xff56c1ff,0xff67c8ff,0xff33b2ff,0xff42baff,0xff54c1ff,0xff31b2ff,0xff65c8ff,
+ 0xff53c0ff,0xff52c0ff,0xff40b8ff,0xff51bfff,0xff51bdff,0xff3fb7ff,0xff51bdff,0xff50bdff,0xff50bdff,0xff3eb5ff,0xff61c5ff,0xff4ebcff,0xff2badff,0xff4ebcff,
+ 0xff4dbbff,0xff4dbbff,0xff4cbbff,0xff4cbbff,0xff4cbaff,0xff39b2ff,0xff4abaff,0xff27a9ff,0xff4ab9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,
+ 0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff47b5ff,0xff22a5ff,0xff5abfff,0xff46b5ff,0xff46b4ff,0xff32acff,0xff44b4ff,0xff44b3ff,0xff31abff,0xff43b3ff,
+ 0xff43b3ff,0xff42b3ff,0xff2faaff,0xff41b3ff,0xff41b2ff,0xff2ea9ff,0xff1c9fff,0xff41b2ff,0xff1ba0ff,0xff2ea9ff,0xff41b2ff,0xff41b3ff,0xff42b3ff,0xff42b3ff,
+ 0xff43b3ff,0xff43b3ff,0xff50caff,0xff73d5ff,0xff74d5ff,0xff74d6ff,0xff51cbff,0xff75d6ff,0xff75d6ff,0xff76d7ff,0xff87dbff,0xff76d7ff,0xff55cdff,0xff77d7ff,
+ 0xff77d7ff,0xff78d8ff,0xff78d8ff,0xff57cfff,0xff7ad9ff,0xff58cfff,0xff59cfff,0xff59d0ff,0xff7bd9ff,0xff58cfff,0xff57cfff,0xff57cfff,0xff79d8ff,0xff56ceff,
+ 0xff56ceff,0xff55ceff,0xff55cdff,0xff54cdff,0xff54cdff,0xff53ccff,0xff75d6ff,0xff52cbff,0xff51ccff,0xff51cbff,0xff73d6ff,0xff50caff,0xff72d5ff,0xff4fc9ff,
+ 0xff72d5ff,0xff4ec9ff,0xff4dc8ff,0xff82d9ff,0xff70d3ff,0xff81d8ff,0xff70d3ff,0xff4bc7ff,0xff4ac7ff,0xff5ccdff,0xff49c6ff,0xff6ed1ff,0xff48c6ff,0xff6dd1ff,
+ 0xff47c5ff,0xff46c4ff,0xff6bd1ff,0xff6bd0ff,0xff45c3ff,0xff6acfff,0xff45c3ff,0xff44c3ff,0xff43c2ff,0xff43c2ff,0xff69cdff,0xff41c1ff,0xff67cdff,0xff41c0ff,
+ 0xff40c0ff,0xff66cdff,0xff3fc0ff,0xff65cdff,0xff3fbfff,0xff51c5ff,0xff64ccff,0xff63cbff,0xff63cbff,0xff63cbff,0xff63caff,0xff3abdff,0xff3abcff,0xff39bcff,
+ 0xff61caff,0xff38bbff,0xff38bbff,0xff5fc9ff,0xff36bbff,0xff5ec8ff,0xff5ec8ff,0xff36baff,0xff35b9ff,0xff48c0ff,0xff5dc7ff,0xff33b8ff,0xff5bc6ff,0xff32b8ff,
+ 0xff32b7ff,0xff31b7ff,0xff31b6ff,0xff30b7ff,0xff30b6ff,0xff2fb5ff,0xff2eb6ff,0xff43bcff,0xff43bcff,0xff2db5ff,0xff57c4ff,0xff2cb4ff,0xff57c2ff,0xff56c3ff,
+ 0xff2bb3ff,0xff2ab3ff,0xff55c1ff,0xff55c1ff,0xff54c1ff,0xff53c1ff,0xff53c1ff,0xff52c1ff,0xff52c1ff,0xff52c0ff,0xff25b0ff,0xff51bfff,0xff25b0ff,0xff52c1ff,
+ 0xff27b0ff,0xff27b1ff,0xff52c1ff,0xff3fbaff,0xff54c1ff,0xff69c9ff,0xff3fbdff,0xff60cbff,0xff61ccff,0xff61ccff,0xff61ccff,0xff41c0ff,0xff42c0ff,0xff63ccff,
+ 0xff63ccff,0xff54c6ff,0xff54c7ff,0xff64cdff,0xff45c2ff,0xff45c3ff,0xff55c9ff,0xff46c3ff,0xff66cfff,0xff48c5ff,0xff48c3ff,0xff68cfff,0xff47c3ff,0xff47c5ff,
+ 0xff47c3ff,0xff46c3ff,0xff66ceff,0xff45c2ff,0xff55c8ff,0xff76d3ff,0xff44c1ff,0xff43c1ff,0xff42c0ff,0xff42c0ff,0xff63ccff,0xff41c0ff,0xff41bfff,0xff41bfff,
+ 0xff60ccff,0xff40bfff,0xff60c9ff,0xff3fbcff,0xff5fc9ff,0xff3ebcff,0xff4ec1ff,0xff5ec9ff,0xff3dbbff,0xff4cc1ff,0xff5dc7ff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,
+ 0xff3ab9ff,0xff5bc6ff,0xff39b9ff,0xff5ac6ff,0xff38b7ff,0xff38b8ff,0xff59c6ff,0xff59c5ff,0xff58c3ff,0xff36b5ff,0xff35b5ff,0xff35b5ff,0xff35b4ff,0xff34b4ff,
+ 0xff56c2ff,0xff33b3ff,0xff67c8ff,0xff33b3ff,0xff32b3ff,0xff54c1ff,0xff32b2ff,0xff54c0ff,0xff30b1ff,0xff30b1ff,0xff52bfff,0xff2fb0ff,0xff2eb0ff,0xff40b7ff,
+ 0xff51bdff,0xff2eaeff,0xff3eb5ff,0xff2dadff,0xff4fbdff,0xff2badff,0xff3cb4ff,0xff4dbcff,0xff2aacff,0xff4cbbff,0xff4cbbff,0xff28abff,0xff28aaff,0xff28aaff,
+ 0xff4bbaff,0xff4bb9ff,0xff5cc1ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff47b7ff,0xff23a5ff,0xff23a5ff,
+ 0xff46b5ff,0xff21a4ff,0xff46b5ff,0xff46b4ff,0xff20a3ff,0xff20a3ff,0xff44b3ff,0xff43b3ff,0xff43b3ff,0xff42b3ff,0xff42b3ff,0xff1da1ff,0xff1da0ff,0xff2ea9ff,
+ 0xff2ea9ff,0xff2ea8ff,0xff1b9fff,0xff41b2ff,0xff1ca0ff,0xff2faaff,0xff41b3ff,0xff42b3ff,0xff1fa2ff,0xff43b3ff,0xff50caff,0xff62cfff,0xff51cbff,0xff63d0ff,
+ 0xff52cbff,0xff75d6ff,0xff76d6ff,0xff64d1ff,0xff65d1ff,0xff54cdff,0xff66d2ff,0xff55ceff,0xff77d8ff,0xff78d8ff,0xff57ceff,0xff57ceff,0xff7ad9ff,0xff58cfff,
+ 0xff6ad5ff,0xff7bd9ff,0xff7bd9ff,0xff69d5ff,0xff58cfff,0xff57ceff,0xff79d8ff,0xff56ceff,0xff56ceff,0xff66d2ff,0xff55cdff,0xff54ccff,0xff54ccff,0xff53ccff,
+ 0xff64d1ff,0xff75d6ff,0xff75d6ff,0xff62d0ff,0xff62cfff,0xff50cbff,0xff61cfff,0xff4fc9ff,0xff4ec9ff,0xff72d4ff,0xff4dc9ff,0xff5fcdff,0xff70d3ff,0xff5ecdff,
+ 0xff5dcdff,0xff4bc7ff,0xff4bc7ff,0xff4ac7ff,0xff5bccff,0xff6ed1ff,0xff6ed1ff,0xff5acbff,0xff48c5ff,0xff47c4ff,0xff59cbff,0xff6bcfff,0xff6acfff,0xff6acfff,
+ 0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff43c2ff,0xff55c7ff,0xff67cdff,0xff54c7ff,0xff40c0ff,0xff66cdff,0xff66cdff,0xff52c5ff,0xff52c5ff,0xff3fbfff,0xff3ebfff,
+ 0xff3dbeff,0xff64cbff,0xff63cbff,0xff3bbeff,0xff4fc4ff,0xff63caff,0xff4ec3ff,0xff39bdff,0xff39bbff,0xff60c9ff,0xff38bbff,0xff4bc2ff,0xff5fc9ff,0xff4ac2ff,
+ 0xff4ac1ff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff48c0ff,0xff34b9ff,0xff5cc7ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff2fb6ff,0xff30b6ff,
+ 0xff44bdff,0xff43bcff,0xff2eb5ff,0xff2db5ff,0xff42bcff,0xff2cb4ff,0xff41bcff,0xff2bb3ff,0xff56c2ff,0xff55c2ff,0xff29b2ff,0xff3fbaff,0xff28b2ff,0xff3eb9ff,
+ 0xff27b1ff,0xff53c0ff,0xff52c0ff,0xff26b0ff,0xff52c0ff,0xff25b0ff,0xff25b0ff,0xff26b0ff,0xff52c0ff,0xff3db9ff,0xff3db9ff,0xff3ebaff,0xff54c1ff,0xff54c1ff,
+ 0xff3fbcff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42c0ff,0xff43c0ff,0xff42c0ff,0xff43c0ff,0xff44c1ff,0xff45c1ff,0xff44c2ff,0xff45c2ff,
+ 0xff46c3ff,0xff46c3ff,0xff67cfff,0xff67cfff,0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff47c3ff,0xff56c9ff,0xff66ceff,0xff56c9ff,0xff45c2ff,0xff45c2ff,0xff44c1ff,
+ 0xff44c1ff,0xff43c0ff,0xff43c0ff,0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff40bdff,0xff40bcff,0xff3fbdff,0xff3ebcff,0xff3ebcff,
+ 0xff3ebbff,0xff3dbcff,0xff3cbbff,0xff3cbaff,0xff3bbbff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff3ab9ff,0xff39b9ff,0xff38b8ff,0xff38b7ff,
+ 0xff37b7ff,0xff48bcff,0xff58c3ff,0xff47bcff,0xff35b5ff,0xff35b4ff,0xff35b5ff,0xff33b4ff,0xff33b4ff,0xff33b4ff,0xff33b3ff,0xff32b3ff,0xff32b2ff,0xff32b2ff,
+ 0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2eb0ff,0xff2eaeff,0xff2eb0ff,0xff2eaeff,0xff2eadff,0xff2dadff,0xff2dadff,0xff2cadff,0xff2cadff,
+ 0xff2badff,0xff2aacff,0xff2aacff,0xff29abff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff39b1ff,0xff4bb9ff,0xff38b1ff,0xff26a8ff,0xff26a9ff,0xff26a8ff,
+ 0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff35adff,0xff23a5ff,0xff23a5ff,0xff22a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,
+ 0xff1fa2ff,0xff1fa2ff,0xff1ea2ff,0xff1ea2ff,0xff1da1ff,0xff1da0ff,0xff1ca0ff,0xff1ca0ff,0xff2ea9ff,0xff1b9fff,0xff1ca0ff,0xff1ca0ff,0xff1ca0ff,0xff1da1ff,
+ 0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff20a2ff,0xff50caff,0xff50caff,0xff51caff,0xff51cbff,0xff51cbff,0xff52ccff,0xff53ccff,0xff53cdff,0xff53cdff,0xff54ccff,
+ 0xff54cdff,0xff55ceff,0xff56cdff,0xff56ceff,0xff57cfff,0xff57cfff,0xff7ad9ff,0xff7bd9ff,0xff59cfff,0xff5ad0ff,0xff58d0ff,0xff59d0ff,0xff69d4ff,0xff79d9ff,
+ 0xff68d3ff,0xff56ceff,0xff56ceff,0xff55ceff,0xff54cdff,0xff55cdff,0xff54cdff,0xff53ccff,0xff52cbff,0xff52cbff,0xff51cbff,0xff51cbff,0xff50cbff,0xff50caff,
+ 0xff4fc9ff,0xff4fcaff,0xff4fc9ff,0xff4ec9ff,0xff4dc9ff,0xff4dc9ff,0xff4dc8ff,0xff4cc8ff,0xff4bc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac7ff,0xff49c6ff,0xff48c5ff,
+ 0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff43c2ff,0xff42c1ff,0xff42c1ff,
+ 0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3abdff,
+ 0xff3abdff,0xff3abcff,0xff39bcff,0xff39bcff,0xff38bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff36baff,0xff36b9ff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff34b8ff,
+ 0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff30b7ff,0xff2fb5ff,0xff2fb6ff,0xff2fb5ff,0xff2db5ff,0xff2db4ff,0xff2db4ff,0xff2cb4ff,
+ 0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,0xff29b2ff,0xff3ebaff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff27b1ff,0xff26b1ff,0xff25b0ff,0xff25b0ff,
+ 0xff25afff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff3ebaff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,
+ 0xff41c0ff,0xff42c0ff,0xff63ccff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff46c2ff,0xff66cfff,0xff48c3ff,0xff57cbff,0xff68cfff,
+ 0xff68cfff,0xff57c9ff,0xff47c3ff,0xff46c3ff,0xff66cfff,0xff45c2ff,0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,0xff43c1ff,0xff42c0ff,0xff63ccff,0xff41c0ff,
+ 0xff41bfff,0xff61ccff,0xff40bfff,0xff40bdff,0xff3fbcff,0xff3fbdff,0xff5fc9ff,0xff3ebcff,0xff3dbcff,0xff5ec8ff,0xff3cbbff,0xff3cbbff,0xff3bbaff,0xff3abaff,
+ 0xff5cc7ff,0xff3abaff,0xff3ab9ff,0xff3ab8ff,0xff39b8ff,0xff39b8ff,0xff38b8ff,0xff38b7ff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff36b7ff,0xff35b5ff,0xff58c2ff,
+ 0xff34b4ff,0xff33b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff31b2ff,0xff31b1ff,0xff53c0ff,0xff30b1ff,0xff2fb1ff,0xff2fb1ff,0xff2fb0ff,
+ 0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2daeff,0xff2dadff,0xff2cacff,0xff2cadff,0xff4ebcff,0xff2bacff,0xff2aabff,0xff29abff,0xff29abff,0xff28abff,
+ 0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a9ff,0xff25a8ff,0xff24a8ff,0xff24a8ff,0xff49b8ff,0xff48b8ff,0xff23a5ff,0xff23a7ff,
+ 0xff23a5ff,0xff23a4ff,0xff22a5ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff31abff,0xff30aaff,0xff1da1ff,0xff1da1ff,
+ 0xff1ca1ff,0xff1ca0ff,0xff1ca0ff,0xff55bbff,0xff1b9fff,0xff1ca0ff,0xff2ea9ff,0xff41b2ff,0xff1da1ff,0xff1ea1ff,0xff42b3ff,0xff1fa2ff,0xff50caff,0xff62cfff,
+ 0xff62d0ff,0xff62d0ff,0xff52cbff,0xff75d6ff,0xff75d6ff,0xff53ccff,0xff76d7ff,0xff54cdff,0xff66d2ff,0xff56cdff,0xff78d8ff,0xff78d8ff,0xff57ceff,0xff57ceff,
+ 0xff7ad9ff,0xff59cfff,0xff6ad5ff,0xff5ad0ff,0xff59d0ff,0xff7ad9ff,0xff58cfff,0xff58ceff,0xff79d8ff,0xff56ceff,0xff67d3ff,0xff88dcff,0xff55cdff,0xff54cdff,
+ 0xff54ccff,0xff53ccff,0xff76d6ff,0xff75d6ff,0xff52cbff,0xff74d6ff,0xff62d0ff,0xff73d5ff,0xff61cfff,0xff61ceff,0xff83d9ff,0xff72d4ff,0xff4dc8ff,0xff71d3ff,
+ 0xff71d3ff,0xff5ecdff,0xff4cc7ff,0xff5dcdff,0xff5dcdff,0xff49c6ff,0xff5bccff,0xff6ed1ff,0xff5accff,0xff47c5ff,0xff6cd0ff,0xff5acaff,0xff5acaff,0xff46c4ff,
+ 0xff45c4ff,0xff45c3ff,0xff58c8ff,0xff7cd5ff,0xff69ceff,0xff43c2ff,0xff55c7ff,0xff67cdff,0xff55c7ff,0xff41c1ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff66ccff,
+ 0xff65ccff,0xff50c5ff,0xff3dbfff,0xff63cbff,0xff63cbff,0xff3cbdff,0xff3bbdff,0xff3abdff,0xff3abdff,0xff39bcff,0xff61caff,0xff4cc3ff,0xff60c9ff,0xff4cc2ff,
+ 0xff5fc9ff,0xff4ac1ff,0xff4ac1ff,0xff4ac0ff,0xff5dc8ff,0xff34b9ff,0xff48c0ff,0xff5dc6ff,0xff47bfff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,
+ 0xff5ac5ff,0xff30b6ff,0xff2fb6ff,0xff58c4ff,0xff58c4ff,0xff2db4ff,0xff42bcff,0xff57c3ff,0xff41bbff,0xff2bb3ff,0xff2bb3ff,0xff2bb3ff,0xff2ab2ff,0xff29b2ff,
+ 0xff28b2ff,0xff28b2ff,0xff27b1ff,0xff52c1ff,0xff52c1ff,0xff26b0ff,0xff26b0ff,0xff51c0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff52c0ff,0xff28b1ff,0xff28b1ff,
+ 0xff3fb9ff,0xff2ab3ff,0xff40bdff,0xff60cbff,0xff60cbff,0xff61ccff,0xff51c6ff,0xff41c0ff,0xff42c0ff,0xff63cdff,0xff63ccff,0xff63cdff,0xff44c1ff,0xff64cdff,
+ 0xff45c2ff,0xff45c2ff,0xff66ceff,0xff46c3ff,0xff67cfff,0xff48c3ff,0xff48c5ff,0xff48c5ff,0xff68cfff,0xff47c5ff,0xff47c3ff,0xff46c2ff,0xff66cfff,0xff45c2ff,
+ 0xff44c2ff,0xff54c7ff,0xff44c1ff,0xff43c0ff,0xff43c0ff,0xff42c0ff,0xff63ccff,0xff51c6ff,0xff50c5ff,0xff61ccff,0xff61cbff,0xff40bdff,0xff60cbff,0xff3fbdff,
+ 0xff5fcbff,0xff3ebcff,0xff3dbbff,0xff6fcfff,0xff3cbbff,0xff5dc7ff,0xff3bbbff,0xff3bbaff,0xff5cc6ff,0xff3ab9ff,0xff6dcdff,0xff3ab9ff,0xff5bc6ff,0xff5bc6ff,
+ 0xff39b8ff,0xff5ac5ff,0xff38b7ff,0xff36b7ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,0xff57c3ff,0xff34b4ff,0xff34b4ff,0xff56c1ff,0xff33b4ff,0xff55c1ff,0xff33b3ff,
+ 0xff33b2ff,0xff32b2ff,0xff31b2ff,0xff66c7ff,0xff30b1ff,0xff53c0ff,0xff52c0ff,0xff2fb0ff,0xff2eb0ff,0xff51bdff,0xff2eaeff,0xff2daeff,0xff2daeff,0xff4fbdff,
+ 0xff2cadff,0xff3db5ff,0xff4ebdff,0xff4dbcff,0xff2aacff,0xff4dbbff,0xff4cbbff,0xff3ab3ff,0xff28aaff,0xff4bbaff,0xff4bb9ff,0xff28aaff,0xff4ab9ff,0xff26a9ff,
+ 0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff49b8ff,0xff5bc0ff,0xff35aeff,0xff47b7ff,0xff23a5ff,0xff23a5ff,0xff46b7ff,0xff5abfff,0xff21a4ff,0xff46b5ff,0xff20a3ff,
+ 0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1ea2ff,0xff1ea2ff,0xff30aaff,0xff1da0ff,0xff1ca0ff,0xff41b2ff,0xff1ba0ff,0xff41b1ff,0xff1ba0ff,0xff1ca0ff,
+ 0xff1ca1ff,0xff41b2ff,0xff1ea1ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff4fcaff,0xff73d5ff,0xff73d5ff,0xff74d6ff,0xff63d0ff,0xff75d6ff,0xff76d6ff,0xff76d7ff,
+ 0xff87dcff,0xff76d7ff,0xff55cdff,0xff77d8ff,0xff77d8ff,0xff78d8ff,0xff67d3ff,0xff57ceff,0xff79d9ff,0xff58d0ff,0xff59d0ff,0xff6ad5ff,0xff69d5ff,0xff58cfff,
+ 0xff58cfff,0xff58cfff,0xff79d9ff,0xff56ceff,0xff55ceff,0xff66d2ff,0xff55ceff,0xff54cdff,0xff54ccff,0xff53ccff,0xff76d6ff,0xff52ccff,0xff74d6ff,0xff74d6ff,
+ 0xff73d5ff,0xff50caff,0xff72d5ff,0xff4fc9ff,0xff72d4ff,0xff4ec8ff,0xff4ec8ff,0xff71d4ff,0xff4cc8ff,0xff6fd2ff,0xff4cc8ff,0xff4bc7ff,0xff6fd2ff,0xff4ac6ff,
+ 0xff6ed2ff,0xff49c6ff,0xff6dd1ff,0xff5acbff,0xff6cd1ff,0xff6cd0ff,0xff47c4ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff6acfff,0xff43c2ff,0xff43c2ff,
+ 0xff69ceff,0xff42c1ff,0xff67cdff,0xff40c1ff,0xff40c1ff,0xff3fc0ff,0xff3fc0ff,0xff66ccff,0xff3ebfff,0xff64ccff,0xff65cbff,0xff64cbff,0xff63cbff,0xff4fc4ff,
+ 0xff3bbdff,0xff3abdff,0xff3abdff,0xff62caff,0xff39bbff,0xff39bcff,0xff60caff,0xff60c9ff,0xff37baff,0xff5ec8ff,0xff5ec8ff,0xff36b9ff,0xff35b9ff,0xff5dc7ff,
+ 0xff71cdff,0xff5dc6ff,0xff5cc6ff,0xff32b7ff,0xff31b7ff,0xff32b7ff,0xff30b7ff,0xff30b7ff,0xff59c5ff,0xff2fb5ff,0xff59c5ff,0xff2eb5ff,0xff2eb5ff,0xff57c4ff,
+ 0xff57c3ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2bb3ff,0xff2ab2ff,0xff29b3ff,0xff29b2ff,0xff29b1ff,0xff28b2ff,0xff3eb9ff,0xff52c0ff,0xff52c1ff,0xff52c0ff,
+ 0xff25b0ff,0xff51c0ff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff52c0ff,0xff27b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff40bcff,0xff60cbff,0xff50c5ff,0xff61ccff,
+ 0xff51c5ff,0xff62ccff,0xff62ccff,0xff63ccff,0xff63ccff,0xff43c0ff,0xff64cdff,0xff54c7ff,0xff65ceff,0xff65ceff,0xff55c9ff,0xff46c3ff,0xff67cfff,0xff47c3ff,
+ 0xff58cbff,0xff78d5ff,0xff67cfff,0xff58c9ff,0xff47c3ff,0xff47c3ff,0xff66ceff,0xff45c2ff,0xff54c8ff,0xff75d3ff,0xff44c1ff,0xff43c1ff,0xff43c0ff,0xff42c1ff,
+ 0xff63ccff,0xff41bfff,0xff41c0ff,0xff61ccff,0xff61cbff,0xff60ccff,0xff60cbff,0xff3fbdff,0xff4fc2ff,0xff5fc9ff,0xff4dc2ff,0xff5ec8ff,0xff3dbbff,0xff5dc8ff,
+ 0xff3cbbff,0xff5cc7ff,0xff6dcdff,0xff4ac1ff,0xff5bc6ff,0xff39b8ff,0xff5bc6ff,0xff49bfff,0xff5bc6ff,0xff5ac5ff,0xff38b7ff,0xff37b7ff,0xff36b7ff,0xff36b5ff,
+ 0xff35b5ff,0xff46bcff,0xff57c2ff,0xff45baff,0xff57c2ff,0xff56c1ff,0xff55c1ff,0xff32b2ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff66c8ff,0xff53c0ff,0xff52c0ff,
+ 0xff40b8ff,0xff52bfff,0xff51bfff,0xff40b7ff,0xff2eaeff,0xff2eaeff,0xff2dadff,0xff3eb7ff,0xff4fbdff,0xff4fbdff,0xff4ebdff,0xff4ebcff,0xff4dbbff,0xff4cbbff,
+ 0xff4cbbff,0xff28abff,0xff28aaff,0xff4bbaff,0xff4bbaff,0xff4ab9ff,0xff49b9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff25a8ff,0xff49b8ff,0xff24a7ff,
+ 0xff35aeff,0xff47b7ff,0xff47b7ff,0xff33adff,0xff46b5ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa3ff,0xff1fa2ff,0xff1ea2ff,0xff1ea2ff,
+ 0xff30abff,0xff41b3ff,0xff41b2ff,0xff41b2ff,0xff2ea9ff,0xff55baff,0xff41b2ff,0xff1ca0ff,0xff41b3ff,0xff56bbff,0xff2faaff,0xff1ea2ff,0xff1fa1ff,0xff1fa2ff,
+ 0xff4fc9ff,0xff50caff,0xff50caff,0xff51cbff,0xff52ccff,0xff52cbff,0xff52cbff,0xff53ccff,0xff54ccff,0xff54cdff,0xff55cdff,0xff55ceff,0xff56ceff,0xff56ceff,
+ 0xff57ceff,0xff58cfff,0xff8addff,0xff7ad9ff,0xff59cfff,0xff5ad0ff,0xff59d0ff,0xff58cfff,0xff69d4ff,0xff79d9ff,0xff79d9ff,0xff57ceff,0xff56ceff,0xff56ceff,
+ 0xff55cdff,0xff54cdff,0xff54cdff,0xff53ccff,0xff53ccff,0xff53ccff,0xff52cbff,0xff51cbff,0xff51caff,0xff50caff,0xff50caff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,
+ 0xff4dc9ff,0xff4dc9ff,0xff4dc8ff,0xff4cc8ff,0xff4bc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,0xff4ac6ff,0xff49c6ff,0xff48c6ff,0xff5acbff,0xff6cd1ff,0xff6cd0ff,
+ 0xff59caff,0xff46c4ff,0xff45c3ff,0xff44c3ff,0xff44c2ff,0xff44c3ff,0xff44c2ff,0xff43c1ff,0xff42c1ff,0xff41c1ff,0xff41c1ff,0xff41c0ff,0xff40c1ff,0xff40c0ff,
+ 0xff40bfff,0xff3fbfff,0xff3fbfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff3abdff,0xff3abdff,0xff39bcff,0xff39bcff,0xff39bbff,
+ 0xff38bcff,0xff37bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff36baff,0xff34baff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,
+ 0xff31b7ff,0xff30b7ff,0xff2fb6ff,0xff30b6ff,0xff2fb6ff,0xff2eb5ff,0xff2db5ff,0xff2db5ff,0xff2db5ff,0xff2cb4ff,0xff2bb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab2ff,
+ 0xff29b3ff,0xff2ab2ff,0xff28b2ff,0xff28b2ff,0xff27b1ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff25b0ff,0xff26b0ff,0xff27b0ff,0xff27b0ff,
+ 0xff27b1ff,0xff29b1ff,0xff29b2ff,0xff29b3ff,0xff40bdff,0xff40bdff,0xff41bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42c0ff,0xff42c1ff,0xff43c0ff,0xff43c0ff,
+ 0xff43c1ff,0xff44c2ff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff46c2ff,0xff47c3ff,0xff47c5ff,0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff47c3ff,0xff46c3ff,0xff46c2ff,
+ 0xff46c2ff,0xff45c2ff,0xff45c2ff,0xff44c2ff,0xff43c1ff,0xff43c1ff,0xff43c0ff,0xff42c1ff,0xff42bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff40bfff,0xff40bfff,
+ 0xff40bcff,0xff3fbcff,0xff3fbcff,0xff3ebcff,0xff3dbcff,0xff3dbbff,0xff3cbbff,0xff3bbbff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,0xff3abaff,0xff3ab9ff,0xff3ab8ff,
+ 0xff39b9ff,0xff39b8ff,0xff39b8ff,0xff38b7ff,0xff38b7ff,0xff37b5ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff34b4ff,0xff35b5ff,0xff34b4ff,0xff33b3ff,0xff33b4ff,
+ 0xff33b3ff,0xff33b2ff,0xff32b2ff,0xff32b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,0xff2fb0ff,0xff2fb1ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2eaeff,
+ 0xff2dadff,0xff2dadff,0xff2cacff,0xff2bacff,0xff2bacff,0xff2aacff,0xff2aabff,0xff2aacff,0xff29abff,0xff29abff,0xff28aaff,0xff28aaff,0xff28a9ff,0xff28aaff,
+ 0xff27a9ff,0xff26a9ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a8ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff23a4ff,0xff22a5ff,0xff22a4ff,0xff21a4ff,
+ 0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea2ff,0xff1da1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,
+ 0xff1ca0ff,0xff1ca0ff,0xff1ca1ff,0xff1da1ff,0xff1da1ff,0xff1ea2ff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff51caff,0xff51cbff,0xff51ccff,0xff52cbff,
+ 0xff52ccff,0xff53ccff,0xff65d2ff,0xff54cdff,0xff55cdff,0xff55ceff,0xff55cdff,0xff56ceff,0xff57cfff,0xff57ceff,0xff8addff,0xff7ad9ff,0xff59d0ff,0xff7bd9ff,
+ 0xff7ad9ff,0xff58cfff,0xff69d4ff,0xff79d8ff,0xff78d8ff,0xff57ceff,0xff56ceff,0xff55cdff,0xff55cdff,0xff55cdff,0xff54ccff,0xff53ccff,0xff63d1ff,0xff53ccff,
+ 0xff51cbff,0xff51cbff,0xff50cbff,0xff50caff,0xff50caff,0xff4fc9ff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,0xff4dc9ff,0xff4cc8ff,0xff4cc8ff,0xff4bc8ff,0xff4bc7ff,
+ 0xff5dccff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,0xff47c5ff,0xff47c4ff,0xff46c4ff,0xff46c4ff,0xff45c3ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,
+ 0xff43c3ff,0xff55c8ff,0xff42c1ff,0xff54c7ff,0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff3fc0ff,0xff40c0ff,0xff3fc0ff,0xff3ec0ff,0xff3dbfff,0xff3dbfff,0xff3dbeff,
+ 0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff4fc4ff,0xff3abdff,0xff39bcff,0xff39bcff,0xff38bbff,0xff37bbff,0xff37bbff,0xff37baff,0xff37baff,0xff36baff,0xff36baff,
+ 0xff35b9ff,0xff34b9ff,0xff34b8ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff46bfff,0xff47bfff,0xff31b7ff,0xff30b7ff,0xff2fb6ff,0xff59c5ff,0xff44bdff,0xff2fb5ff,
+ 0xff2eb5ff,0xff2db5ff,0xff2cb4ff,0xff2db4ff,0xff2bb4ff,0xff2bb3ff,0xff2bb3ff,0xff2ab3ff,0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff28b1ff,0xff27b0ff,
+ 0xff27b0ff,0xff52c0ff,0xff26b0ff,0xff25b0ff,0xff3cb8ff,0xff26b0ff,0xff26b1ff,0xff27b0ff,0xff28b1ff,0xff29b1ff,0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff40bfff,
+ 0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42c0ff,0xff43c0ff,0xff63ccff,0xff43c1ff,0xff44c1ff,0xff44c2ff,0xff44c2ff,0xff45c2ff,0xff45c2ff,0xff46c2ff,
+ 0xff67ceff,0xff48c3ff,0xff68cfff,0xff49c5ff,0xff47c5ff,0xff67cfff,0xff47c3ff,0xff46c3ff,0xff65ceff,0xff45c2ff,0xff44c1ff,0xff54c7ff,0xff43c1ff,0xff43c1ff,
+ 0xff43c0ff,0xff42c1ff,0xff63ccff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bdff,0xff40bdff,0xff40bdff,0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff3ebbff,0xff3dbbff,
+ 0xff3dbbff,0xff3cbbff,0xff3bbaff,0xff3bbaff,0xff4bc1ff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff39b8ff,0xff38b8ff,0xff38b8ff,0xff38b7ff,0xff37b7ff,0xff37b5ff,
+ 0xff36b5ff,0xff35b5ff,0xff35b5ff,0xff34b5ff,0xff35b4ff,0xff56c2ff,0xff33b4ff,0xff44bbff,0xff33b3ff,0xff32b3ff,0xff32b3ff,0xff32b2ff,0xff31b2ff,0xff31b2ff,
+ 0xff30b1ff,0xff30b1ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff51bdff,0xff2dadff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2badff,0xff2aacff,
+ 0xff2aacff,0xff2aabff,0xff29abff,0xff29abff,0xff28abff,0xff28aaff,0xff27aaff,0xff28a9ff,0xff27a9ff,0xff27a9ff,0xff26a8ff,0xff37b0ff,0xff25a7ff,0xff24a7ff,
+ 0xff24a7ff,0xff48b8ff,0xff48b7ff,0xff23a5ff,0xff23a5ff,0xff22a5ff,0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff1fa2ff,
+ 0xff1fa2ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff41b3ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,0xff41b2ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1ea1ff,0xff1fa2ff,
+ 0xff1ea2ff,0xff1fa2ff,0xff50caff,0xff73d5ff,0xff74d5ff,0xff74d6ff,0xff63d0ff,0xff75d6ff,0xff75d6ff,0xff64d1ff,0xff76d6ff,0xff65d2ff,0xff66d2ff,0xff66d2ff,
+ 0xff78d8ff,0xff79d8ff,0xff68d3ff,0xff57cfff,0xff79d9ff,0xff58d0ff,0xff59d0ff,0xff59d0ff,0xff69d4ff,0xff69d4ff,0xff57cfff,0xff57cfff,0xff79d9ff,0xff57ceff,
+ 0xff67d2ff,0xff88dcff,0xff55cdff,0xff54cdff,0xff53ccff,0xff53ccff,0xff76d6ff,0xff52cbff,0xff51cbff,0xff51caff,0xff74d6ff,0xff74d5ff,0xff72d5ff,0xff61cfff,
+ 0xff72d4ff,0xff72d4ff,0xff5fceff,0xff71d3ff,0xff4dc8ff,0xff70d3ff,0xff4cc7ff,0xff5dcdff,0xff6fd2ff,0xff4ac7ff,0xff80d7ff,0xff6ed1ff,0xff6ed1ff,0xff5acbff,
+ 0xff6cd0ff,0xff6cd0ff,0xff59caff,0xff45c4ff,0xff45c3ff,0xff45c3ff,0xff57c9ff,0xff6aceff,0xff69ceff,0xff69ceff,0xff42c2ff,0xff7ad4ff,0xff41c1ff,0xff67cdff,
+ 0xff66cdff,0xff66cdff,0xff52c6ff,0xff66cdff,0xff65ccff,0xff64ccff,0xff50c5ff,0xff63cbff,0xff63cbff,0xff4fc5ff,0xff63caff,0xff75d0ff,0xff4ec3ff,0xff4dc3ff,
+ 0xff61caff,0xff61caff,0xff4cc3ff,0xff73cfff,0xff5fc8ff,0xff5ec9ff,0xff5ec8ff,0xff35baff,0xff35baff,0xff5dc7ff,0xff33b9ff,0xff33b8ff,0xff32b8ff,0xff33b8ff,
+ 0xff31b7ff,0xff31b7ff,0xff31b7ff,0xff31b6ff,0xff5ac5ff,0xff2fb6ff,0xff59c4ff,0xff58c4ff,0xff58c4ff,0xff42bcff,0xff57c3ff,0xff57c3ff,0xff57c3ff,0xff2bb4ff,
+ 0xff6bcaff,0xff55c2ff,0xff3fbaff,0xff54c1ff,0xff54c1ff,0xff53c1ff,0xff28b1ff,0xff27b1ff,0xff52c0ff,0xff26b1ff,0xff52c0ff,0xff51bfff,0xff67c7ff,0xff3cb8ff,
+ 0xff52c1ff,0xff52c1ff,0xff3db9ff,0xff53c1ff,0xff29b2ff,0xff54c1ff,0xff40bdff,0xff60cbff,0xff60cbff,0xff61cbff,0xff41bfff,0xff62ccff,0xff63ccff,0xff63ccff,
+ 0xff74d3ff,0xff63cdff,0xff43c2ff,0xff64cdff,0xff65cdff,0xff66ceff,0xff66ceff,0xff46c3ff,0xff67cfff,0xff47c3ff,0xff48c5ff,0xff48c5ff,0xff68cfff,0xff48c3ff,
+ 0xff47c3ff,0xff47c3ff,0xff66cfff,0xff45c2ff,0xff45c2ff,0xff44c2ff,0xff44c1ff,0xff43c1ff,0xff42c0ff,0xff42c0ff,0xff63ccff,0xff41c0ff,0xff41bfff,0xff41bfff,
+ 0xff71d0ff,0xff60ccff,0xff71cfff,0xff3fbdff,0xff5fcbff,0xff5fc9ff,0xff5ec9ff,0xff4dc1ff,0xff4dc1ff,0xff5dc8ff,0xff3bbaff,0xff3abaff,0xff5cc7ff,0xff3ab9ff,
+ 0xff5bc6ff,0xff3ab8ff,0xff5bc6ff,0xff5ac6ff,0xff39b7ff,0xff5ac6ff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,0xff58c3ff,0xff35b5ff,0xff34b4ff,0xff57c2ff,
+ 0xff33b4ff,0xff56c1ff,0xff33b3ff,0xff55c1ff,0xff32b2ff,0xff31b2ff,0xff41b9ff,0xff66c8ff,0xff53c0ff,0xff65c7ff,0xff52bfff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,
+ 0xff2eaeff,0xff50bdff,0xff2dadff,0xff50bdff,0xff2cadff,0xff2cacff,0xff4ebdff,0xff4ebcff,0xff2aacff,0xff3ab3ff,0xff4cbbff,0xff28abff,0xff28abff,0xff4bbaff,
+ 0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff48b8ff,0xff24a7ff,0xff48b8ff,0xff23a7ff,0xff23a5ff,0xff47b7ff,
+ 0xff46b5ff,0xff22a4ff,0xff46b5ff,0xff20a3ff,0xff44b4ff,0xff44b4ff,0xff43b4ff,0xff57bcff,0xff43b3ff,0xff56bbff,0xff1ea2ff,0xff2faaff,0xff2faaff,0xff1ca0ff,
+ 0xff41b2ff,0xff1ba0ff,0xff41b2ff,0xff1ca1ff,0xff41b2ff,0xff42b3ff,0xff41b3ff,0xff30aaff,0xff30abff,0xff43b3ff,0xff50caff,0xff73d6ff,0xff74d6ff,0xff74d6ff,
+ 0xff75d6ff,0xff52cbff,0xff53ccff,0xff76d6ff,0xff76d6ff,0xff65d2ff,0xff65d2ff,0xff77d7ff,0xff56ceff,0xff56ceff,0xff68d3ff,0xff57cfff,0xff79d9ff,0xff58cfff,
+ 0xff59cfff,0xff7bd9ff,0xff59d0ff,0xff58cfff,0xff57cfff,0xff57cfff,0xff79d9ff,0xff56ceff,0xff67d3ff,0xff89dcff,0xff54cdff,0xff54ccff,0xff53cdff,0xff53ccff,
+ 0xff75d6ff,0xff52ccff,0xff51cbff,0xff51caff,0xff74d6ff,0xff50caff,0xff62cfff,0xff72d4ff,0xff4ec9ff,0xff4ec9ff,0xff72d4ff,0xff4dc8ff,0xff71d3ff,0xff5ecdff,
+ 0xff4bc7ff,0xff4bc7ff,0xff6fd2ff,0xff4ac6ff,0xff6fd1ff,0xff49c6ff,0xff6ed1ff,0xff48c5ff,0xff7fd6ff,0xff5acaff,0xff46c5ff,0xff46c4ff,0xff45c3ff,0xff45c3ff,
+ 0xff6acfff,0xff44c3ff,0xff56c8ff,0xff69cdff,0xff42c1ff,0xff68cdff,0xff42c1ff,0xff66cdff,0xff40c1ff,0xff40c0ff,0xff3fc0ff,0xff65ccff,0xff3ebfff,0xff51c5ff,
+ 0xff64cbff,0xff3dbfff,0xff3cbeff,0xff50c4ff,0xff3bbdff,0xff62caff,0xff4ec4ff,0xff62caff,0xff39bbff,0xff39bcff,0xff60c9ff,0xff60c9ff,0xff36bbff,0xff36baff,
+ 0xff4ac1ff,0xff5ec8ff,0xff5ec7ff,0xff5dc7ff,0xff34b9ff,0xff34b9ff,0xff32b8ff,0xff33b7ff,0xff32b7ff,0xff32b7ff,0xff30b7ff,0xff45beff,0xff45bdff,0xff2fb6ff,
+ 0xff59c5ff,0xff2eb5ff,0xff2eb5ff,0xff58c4ff,0xff57c3ff,0xff2cb4ff,0xff57c3ff,0xff2bb4ff,0xff56c2ff,0xff55c2ff,0xff55c2ff,0xff54c1ff,0xff28b2ff,0xff3fb9ff,
+ 0xff27b1ff,0xff52c1ff,0xff26b0ff,0xff26b0ff,0xff51c0ff,0xff25afff,0xff67c7ff,0xff52c1ff,0xff26b0ff,0xff27b1ff,0xff52c1ff,0xff28b1ff,0xff53c1ff,0xff3fbaff,
+ 0xff40bdff,0xff50c5ff,0xff41bdff,0xff50c5ff,0xff41bfff,0xff62ccff,0xff63ccff,0xff52c6ff,0xff53c6ff,0xff43c1ff,0xff53c7ff,0xff45c2ff,0xff64ceff,0xff65ceff,
+ 0xff46c3ff,0xff47c2ff,0xff67cfff,0xff47c3ff,0xff57c9ff,0xff68cfff,0xff67cfff,0xff57cbff,0xff47c3ff,0xff46c3ff,0xff66ceff,0xff45c2ff,0xff45c2ff,0xff55c8ff,
+ 0xff44c1ff,0xff43c1ff,0xff42c1ff,0xff42c0ff,0xff52c6ff,0xff62ccff,0xff62ccff,0xff50c5ff,0xff50c5ff,0xff60cbff,0xff50c3ff,0xff3fbdff,0xff5fc9ff,0xff5fc8ff,
+ 0xff4dc2ff,0xff3dbbff,0xff4cc1ff,0xff3cbbff,0xff3cbaff,0xff5cc7ff,0xff5cc7ff,0xff49c0ff,0xff49c1ff,0xff3ab9ff,0xff49bfff,0xff5bc6ff,0xff49bdff,0xff5ac6ff,
+ 0xff48bdff,0xff37b7ff,0xff36b7ff,0xff35b7ff,0xff35b5ff,0xff58c2ff,0xff45bbff,0xff45bbff,0xff44bbff,0xff56c1ff,0xff55c1ff,0xff42b9ff,0xff33b3ff,0xff31b2ff,
+ 0xff31b2ff,0xff41b8ff,0xff53c0ff,0xff41b8ff,0xff2fb1ff,0xff52bfff,0xff51bfff,0xff2eb0ff,0xff2eaeff,0xff3eb7ff,0xff3eb7ff,0xff2dadff,0xff4fbdff,0xff4fbcff,
+ 0xff2bacff,0xff3bb4ff,0xff2aabff,0xff29abff,0xff3ab3ff,0xff29abff,0xff28abff,0xff4cbaff,0xff28aaff,0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff26a9ff,0xff25a9ff,
+ 0xff25a7ff,0xff49b8ff,0xff24a7ff,0xff24a7ff,0xff34aeff,0xff23a5ff,0xff22a4ff,0xff33adff,0xff33adff,0xff46b5ff,0xff33adff,0xff20a3ff,0xff32abff,0xff20a3ff,
+ 0xff31acff,0xff31abff,0xff42b3ff,0xff30abff,0xff2faaff,0xff2faaff,0xff1ca1ff,0xff1ca0ff,0xff2ea9ff,0xff41b2ff,0xff2ea8ff,0xff1ca0ff,0xff41b3ff,0xff41b3ff,
+ 0xff2faaff,0xff1ea2ff,0xff31abff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff51caff,0xff51cbff,0xff51cbff,0xff52cbff,0xff52ccff,0xff53ccff,0xff54ccff,0xff54ccff,
+ 0xff54cdff,0xff55cdff,0xff55ceff,0xff56ceff,0xff57cfff,0xff57cfff,0xff7ad9ff,0xff7ad9ff,0xff59cfff,0xff59d0ff,0xff59d0ff,0xff58cfff,0xff69d4ff,0xff79d9ff,
+ 0xff68d4ff,0xff56ceff,0xff56cdff,0xff55ceff,0xff55cdff,0xff55cdff,0xff54cdff,0xff53cdff,0xff52cbff,0xff52ccff,0xff52cbff,0xff51cbff,0xff50cbff,0xff50caff,
+ 0xff50caff,0xff4fcaff,0xff4fc9ff,0xff4ec9ff,0xff4ec9ff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff4cc7ff,0xff4bc8ff,0xff4ac6ff,0xff4ac7ff,0xff49c6ff,0xff49c6ff,
+ 0xff48c6ff,0xff48c6ff,0xff6cd1ff,0xff6cd0ff,0xff46c5ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,0xff43c3ff,0xff42c2ff,0xff43c2ff,0xff42c2ff,
+ 0xff41c1ff,0xff41c0ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff3fbfff,0xff3ebfff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3abcff,
+ 0xff3abcff,0xff3abcff,0xff39bcff,0xff39bcff,0xff38bbff,0xff37bbff,0xff37bbff,0xff37baff,0xff35baff,0xff5ec8ff,0xff5dc8ff,0xff34b9ff,0xff34b8ff,0xff33b8ff,
+ 0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff31b6ff,0xff45bdff,0xff30b6ff,0xff2fb6ff,0xff2eb5ff,0xff2eb5ff,0xff2eb5ff,0xff2eb5ff,0xff2cb4ff,0xff2cb4ff,
+ 0xff2cb3ff,0xff2bb3ff,0xff2bb3ff,0xff2bb3ff,0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff3db9ff,0xff27b0ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff25afff,
+ 0xff26b0ff,0xff26b1ff,0xff26b0ff,0xff27b0ff,0xff27b2ff,0xff28b2ff,0xff28b2ff,0xff29b2ff,0xff40bcff,0xff40bdff,0xff41bfff,0xff41bdff,0xff41c0ff,0xff41bfff,
+ 0xff41c0ff,0xff42c0ff,0xff43c0ff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff44c2ff,0xff45c2ff,0xff46c2ff,0xff47c2ff,0xff67cfff,0xff67cfff,0xff47c3ff,0xff49c3ff,
+ 0xff48c5ff,0xff47c3ff,0xff57c9ff,0xff66cfff,0xff55c8ff,0xff46c2ff,0xff45c2ff,0xff44c1ff,0xff43c1ff,0xff43c0ff,0xff42c1ff,0xff42c1ff,0xff41c0ff,0xff41bfff,
+ 0xff41c0ff,0xff41bfff,0xff41bdff,0xff40bdff,0xff40bdff,0xff3fbcff,0xff3fbcff,0xff3ebcff,0xff3dbbff,0xff3cbcff,0xff3cbbff,0xff3cbbff,0xff3cbaff,0xff3bbaff,
+ 0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab8ff,0xff39b8ff,0xff39b8ff,0xff39b8ff,0xff38b8ff,0xff38b8ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff35b5ff,
+ 0xff34b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff32b3ff,0xff31b2ff,0xff31b1ff,0xff31b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2eb0ff,
+ 0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2eaeff,0xff2dadff,0xff2dadff,0xff2cadff,0xff2badff,0xff2bacff,0xff2aabff,0xff2aabff,0xff29abff,0xff29abff,0xff29abff,
+ 0xff28abff,0xff28aaff,0xff28aaff,0xff27aaff,0xff27a9ff,0xff26a8ff,0xff37b0ff,0xff25a8ff,0xff25a8ff,0xff25a7ff,0xff24a7ff,0xff35adff,0xff24a5ff,0xff23a5ff,
+ 0xff23a5ff,0xff23a4ff,0xff21a5ff,0xff21a4ff,0xff21a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff1fa2ff,0xff1fa2ff,0xff1ea2ff,0xff1da1ff,0xff1da1ff,
+ 0xff1da0ff,0xff2ea9ff,0xff1ba0ff,0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1da0ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff50caff,
+ 0xff51caff,0xff51cbff,0xff51ccff,0xff52cbff,0xff52ccff,0xff53ccff,0xff76d7ff,0xff54cdff,0xff55cdff,0xff55ceff,0xff56ceff,0xff57ceff,0xff57ceff,0xff57cfff,
+ 0xff7ad9ff,0xff58d0ff,0xff59d0ff,0xff6bd5ff,0xff7ad9ff,0xff58d0ff,0xff58cfff,0xff57ceff,0xff79d9ff,0xff56ceff,0xff56ceff,0xff56cdff,0xff54cdff,0xff55cdff,
+ 0xff53ccff,0xff53ccff,0xff76d6ff,0xff52cbff,0xff52cbff,0xff51cbff,0xff51cbff,0xff50caff,0xff50caff,0xff4fcaff,0xff4fc9ff,0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,
+ 0xff4dc8ff,0xff4cc8ff,0xff4bc8ff,0xff4bc7ff,0xff6fd2ff,0xff4ac7ff,0xff49c6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,0xff48c4ff,0xff47c4ff,0xff46c4ff,0xff45c4ff,
+ 0xff45c4ff,0xff45c4ff,0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff69ceff,0xff42c2ff,0xff67cdff,0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff40c0ff,0xff40c0ff,0xff3ebfff,
+ 0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3cbfff,0xff3cbdff,0xff3cbeff,0xff3cbdff,0xff63caff,0xff3abdff,0xff3abcff,0xff39bcff,0xff38bcff,0xff38bbff,0xff37bbff,
+ 0xff37bbff,0xff36bbff,0xff36baff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff5ac5ff,0xff31b6ff,0xff30b6ff,
+ 0xff30b6ff,0xff5ac5ff,0xff59c4ff,0xff2eb6ff,0xff2eb5ff,0xff2eb4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2bb3ff,0xff2ab2ff,0xff29b3ff,0xff29b2ff,
+ 0xff29b2ff,0xff28b1ff,0xff27b1ff,0xff27b0ff,0xff3db9ff,0xff3cb8ff,0xff26afff,0xff25afff,0xff52c0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,
+ 0xff28b2ff,0xff29b2ff,0xff3fbcff,0xff50c5ff,0xff50c3ff,0xff50c5ff,0xff41bfff,0xff62ccff,0xff63ccff,0xff42c0ff,0xff63ccff,0xff44c1ff,0xff53c7ff,0xff44c1ff,
+ 0xff65ceff,0xff65ceff,0xff46c2ff,0xff47c3ff,0xff67cfff,0xff47c3ff,0xff48c5ff,0xff58cbff,0xff68cfff,0xff47c5ff,0xff46c3ff,0xff46c2ff,0xff66cfff,0xff46c2ff,
+ 0xff54c8ff,0xff75d3ff,0xff44c1ff,0xff43c1ff,0xff43c0ff,0xff42c0ff,0xff63ccff,0xff41bfff,0xff41bfff,0xff41bfff,0xff50c5ff,0xff60cbff,0xff4fc3ff,0xff3fbdff,
+ 0xff5fc9ff,0xff5fc9ff,0xff3ebcff,0xff4dc1ff,0xff3cbbff,0xff4cc1ff,0xff3cbbff,0xff4bc1ff,0xff4bc0ff,0xff3abaff,0xff49c0ff,0xff5bc6ff,0xff49bfff,0xff39b9ff,
+ 0xff5ac6ff,0xff49bfff,0xff49bdff,0xff37b7ff,0xff36b7ff,0xff36b5ff,0xff36b5ff,0xff58c3ff,0xff45bbff,0xff56c2ff,0xff34b3ff,0xff55c2ff,0xff33b3ff,0xff43b9ff,
+ 0xff42b9ff,0xff54c1ff,0xff31b2ff,0xff41b8ff,0xff53c0ff,0xff40b8ff,0xff2fb1ff,0xff51bfff,0xff51bdff,0xff2eb0ff,0xff51bdff,0xff62c6ff,0xff3eb7ff,0xff2dadff,
+ 0xff4fbdff,0xff4fbcff,0xff2bacff,0xff3bb4ff,0xff4dbbff,0xff3bb3ff,0xff3ab3ff,0xff28aaff,0xff28aaff,0xff39b2ff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff27a8ff,
+ 0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff36aeff,0xff35aeff,0xff48b8ff,0xff34adff,0xff47b7ff,0xff22a4ff,0xff33adff,0xff46b5ff,0xff32adff,0xff20a3ff,
+ 0xff45b4ff,0xff31acff,0xff1fa2ff,0xff31acff,0xff42b3ff,0xff30aaff,0xff1da1ff,0xff1da1ff,0xff41b3ff,0xff1ca0ff,0xff2ea9ff,0xff41b1ff,0xff41b2ff,0xff1ca0ff,
+ 0xff41b2ff,0xff41b3ff,0xff1ea1ff,0xff30aaff,0xff1ea1ff,0xff31abff,0xff4fcaff,0xff73d5ff,0xff74d5ff,0xff74d6ff,0xff63d1ff,0xff52cbff,0xff53ccff,0xff76d6ff,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff27b1ff,0xff53c1ff,0xff53c1ff,0xff28b2ff,0xff54c1ff,0xff40bdff,0xff60cbff,0xff60cbff,0xff61ccff,
+ 0xff51c6ff,0xff62ccff,0xff63ccff,0xff63cdff,0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff41b3ff,0xff41b3ff,0xff1fa2ff,0xff43b3ff,0xff43b3ff,
+ 0xff4fcaff,0xff73d5ff,0xff62d0ff,0xff74d6ff,0xff63d1ff,0xff75d6ff,0xff76d6ff,0xff76d6ff,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff52c1ff,
+ 0xff52c1ff,0xff28b2ff,0xff54c1ff,0xff2ab2ff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bdff,0xff41c0ff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff43c0ff,0xff43c1ff,
+ 0xff43c1ff,0xff44c2ff,0xff45c2ff,0xff45c2ff,0xff46c3ff,0xff46c2ff,0xff76d4ff,0xff67cfff,0xff48c3ff,0xff48c5ff,0xff48c3ff,0xff48c3ff,0xff57c9ff,0xff66cfff,
+ 0xff66ceff,0xff45c2ff,0xff45c2ff,0xff44c1ff,0xff43c1ff,0xff43c1ff,0xff43c0ff,0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bdff,0xff40bdff,
+ 0xff3fbdff,0xff3fbdff,0xff3ebcff,0xff3ebcff,0xff3ebbff,0xff3dbcff,0xff3cbbff,0xff3cbaff,0xff3cbaff,0xff3bbaff,0xff3abaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,
+ 0xff3ab8ff,0xff49bfff,0xff5bc5ff,0xff5ac5ff,0xff48bfff,0xff36b5ff,0xff36b7ff,0xff36b5ff,0xff35b5ff,0xff34b4ff,0xff35b4ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,
+ 0xff33b3ff,0xff33b2ff,0xff32b3ff,0xff32b2ff,0xff31b2ff,0xff30b2ff,0xff30b2ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,
+ 0xff2daeff,0xff2dadff,0xff2cadff,0xff2badff,0xff2bacff,0xff2bacff,0xff2aacff,0xff2aabff,0xff3ab3ff,0xff4cbaff,0xff4cbaff,0xff39b2ff,0xff28aaff,0xff27aaff,
+ 0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff25a8ff,0xff25a7ff,0xff49b8ff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff23a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,
+ 0xff21a4ff,0xff21a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff41b3ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,
+ 0xff1ba0ff,0xff1ca0ff,0xff1da0ff,0xff1da0ff,0xff1da2ff,0xff1ea2ff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff51cbff,0xff51cbff,0xff52cbff,0xff52ccff,
+ 0xff53cbff,0xff53ccff,0xff53ccff,0xff54cdff,0xff54cdff,0xff56ceff,0xff56ceff,0xff56ceff,0xff56ceff,0xff58cfff,0xff58cfff,0xff58d0ff,0xff58d0ff,0xff5ad0ff,
+ 0xff59d0ff,0xff58cfff,0xff58cfff,0xff57cfff,0xff57ceff,0xff56ceff,0xff56cdff,0xff56ceff,0xff54ceff,0xff55cdff,0xff53ccff,0xff53ccff,0xff53ccff,0xff52ccff,
+ 0xff52cbff,0xff51caff,0xff51caff,0xff50caff,0xff50caff,0xff4fc9ff,0xff4ec9ff,0xff4ec9ff,0xff4dc9ff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff4cc7ff,0xff4ac7ff,
+ 0xff4ac7ff,0xff4ac6ff,0xff49c6ff,0xff49c5ff,0xff48c6ff,0xff47c6ff,0xff48c5ff,0xff47c4ff,0xff46c5ff,0xff45c4ff,0xff45c3ff,0xff45c3ff,0xff44c2ff,0xff44c3ff,
+ 0xff43c2ff,0xff42c2ff,0xff42c2ff,0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff40c1ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3dbfff,0xff3dbfff,0xff3dbeff,
+ 0xff3cbdff,0xff3cbdff,0xff3bbdff,0xff3bbdff,0xff3abcff,0xff3abdff,0xff39bcff,0xff38bcff,0xff38bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff36baff,0xff35baff,
+ 0xff35b9ff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff32b8ff,0xff31b8ff,0xff31b8ff,0xff31b7ff,0xff30b7ff,0xff30b6ff,0xff2fb5ff,0xff2fb5ff,0xff2eb5ff,
+ 0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,0xff2ab3ff,0xff29b3ff,0xff29b2ff,0xff29b2ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,
+ 0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff25b0ff,0xff26afff,0xff26b1ff,0xff26b0ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff50c3ff,
+ 0xff41bdff,0xff50c5ff,0xff41bfff,0xff41c0ff,0xff41c0ff,0xff42c0ff,0xff53c7ff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff45c2ff,0xff55c8ff,0xff45c3ff,0xff46c2ff,
+ 0xff47c3ff,0xff47c3ff,0xff48c3ff,0xff48c5ff,0xff48c3ff,0xff47c5ff,0xff47c3ff,0xff46c2ff,0xff46c3ff,0xff45c2ff,0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,
+ 0xff63ccff,0xff42c0ff,0xff41c0ff,0xff51c6ff,0xff51c5ff,0xff41bfff,0xff41bfff,0xff40bfff,0xff40bdff,0xff3fbcff,0xff3fbcff,0xff4dc2ff,0xff3dbcff,0xff3dbbff,
+ 0xff3cbbff,0xff3cbbff,0xff3bbbff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,0xff3abaff,0xff5bc6ff,0xff39b8ff,0xff39b8ff,0xff38b8ff,0xff48bdff,0xff38b7ff,0xff48bdff,
+ 0xff36b7ff,0xff35b5ff,0xff35b5ff,0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff33b4ff,0xff33b4ff,0xff33b3ff,0xff33b2ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff31b1ff,
+ 0xff31b1ff,0xff30b1ff,0xff2fb1ff,0xff2eb0ff,0xff2faeff,0xff2eaeff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2bacff,
+ 0xff29abff,0xff2aabff,0xff28abff,0xff28aaff,0xff28abff,0xff28aaff,0xff28a9ff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a9ff,0xff25a9ff,0xff25a7ff,0xff24a7ff,
+ 0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff22a5ff,0xff22a5ff,0xff22a5ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa3ff,0xff20a2ff,
+ 0xff1fa1ff,0xff1ea1ff,0xff1da2ff,0xff1da1ff,0xff1da0ff,0xff1ca0ff,0xff1ba0ff,0xff1b9fff,0xff1ca0ff,0xff1ca1ff,0xff1da0ff,0xff1da0ff,0xff1da1ff,0xff1ea2ff,
+ 0xff1ea2ff,0xff1fa2ff,0xff50caff,0xff97dfff,0xff50caff,0xff97dfff,0xff52cbff,0xff52cbff,0xff52ccff,0xff53ccff,0xff76d6ff,0xff55cdff,0xff55cdff,0xff55cdff,
+ 0xff55cdff,0xff68d3ff,0xff56cfff,0xff57ceff,0xff58cfff,0xff58cfff,0xff59cfff,0xff59d0ff,0xff58d0ff,0xff58cfff,0xff58cfff,0xff57cfff,0xff57cfff,0xff56ceff,
+ 0xff56ceff,0xff55ceff,0xff54cdff,0xff54cdff,0xff76d6ff,0xff53ccff,0xff52ccff,0xff52cbff,0xff75d6ff,0xff51cbff,0xff50caff,0xff50cbff,0xff50caff,0xff4fcaff,
+ 0xff4fc9ff,0xff60ceff,0xff4ec8ff,0xff4dc8ff,0xff4dc8ff,0xff4cc7ff,0xff4bc7ff,0xff4bc7ff,0xff4ac7ff,0xff4ac7ff,0xff49c6ff,0xff6ed1ff,0xff49c5ff,0xff48c5ff,
+ 0xff47c5ff,0xff5acaff,0xff46c4ff,0xff6ad0ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff43c3ff,0xff44c2ff,0xff43c2ff,0xff42c1ff,0xff42c1ff,0xff41c1ff,0xff41c1ff,
+ 0xff40c0ff,0xff3fc0ff,0xff40c0ff,0xff3fbfff,0xff3fbfff,0xff3ebfff,0xff3dbfff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff39bdff,
+ 0xff39bcff,0xff38bbff,0xff38bbff,0xff38bbff,0xff37bbff,0xff37baff,0xff36baff,0xff36baff,0xff34b9ff,0xff35b9ff,0xff33b9ff,0xff33b9ff,0xff33b8ff,0xff33b8ff,
+ 0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff30b7ff,0xff30b6ff,0xff2fb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,
+ 0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff29b1ff,0xff29b2ff,0xff27b1ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff25b0ff,0xff25afff,0xff26b0ff,0xff26b0ff,
+ 0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff28b2ff,0xff29b2ff,0xff40bdff,0xff60cbff,0xff84d7ff,0xff61ccff,0xff51c5ff,0xff62ccff,0xff63ccff,0xff53c6ff,
+ 0xff63ccff,0xff53c6ff,0xff53c8ff,0xff44c2ff,0xff54c8ff,0xff65ceff,0xff45c2ff,0xff76d4ff,0xff67cfff,0xff67cfff,0xff58cbff,0xff68cfff,0xff67cfff,0xff57cbff,
+ 0xff46c3ff,0xff46c3ff,0xff46c2ff,0xff55c8ff,0xff65ceff,0xff64ceff,0xff54c7ff,0xff43c1ff,0xff63ccff,0xff42c0ff,0xff41c0ff,0xff42bfff,0xff62ccff,0xff41bdff,
+ 0xff41bfff,0xff40bdff,0xff3fbdff,0xff3fbcff,0xff4ec2ff,0xff5fc8ff,0xff3dbbff,0xff6fcfff,0xff5dc8ff,0xff5dc8ff,0xff3cbbff,0xff3abaff,0xff3abaff,0xff3ab9ff,
+ 0xff3ab9ff,0xff5bc6ff,0xff39b9ff,0xff39b8ff,0xff49bfff,0xff59c5ff,0xff37b8ff,0xff6acbff,0xff58c5ff,0xff58c3ff,0xff46bcff,0xff58c3ff,0xff57c3ff,0xff45bbff,
+ 0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff33b2ff,0xff32b3ff,0xff32b1ff,0xff31b2ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,
+ 0xff2eaeff,0xff2daeff,0xff2dadff,0xff2daeff,0xff2cadff,0xff2bacff,0xff2badff,0xff2bacff,0xff2aabff,0xff2aabff,0xff28aaff,0xff28abff,0xff28abff,0xff28aaff,
+ 0xff28aaff,0xff27a9ff,0xff27a9ff,0xff27a9ff,0xff25a9ff,0xff26a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff23a7ff,0xff23a5ff,0xff22a5ff,
+ 0xff22a4ff,0xff21a4ff,0xff21a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,
+ 0xff1ca0ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1ca1ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff73d5ff,0xff50cbff,0xff74d6ff,
+ 0xff51cbff,0xff75d6ff,0xff76d6ff,0xff76d6ff,0xff87dbff,0xff76d7ff,0xff55cdff,0xff55cdff,0xff55ceff,0xff78d8ff,0xff57ceff,0xff79d9ff,0xff58cfff,0xff7ad9ff,
+ 0xff7ad9ff,0xff5ad0ff,0xff7bd9ff,0xff58cfff,0xff57cfff,0xff57cfff,0xff57ceff,0xff56ceff,0xff77d7ff,0xff77d8ff,0xff77d7ff,0xff55ccff,0xff76d6ff,0xff53ccff,
+ 0xff53ccff,0xff52cbff,0xff75d6ff,0xff51cbff,0xff51cbff,0xff50cbff,0xff4fcaff,0xff4fcaff,0xff4fc9ff,0xff72d4ff,0xff4dc9ff,0xff71d3ff,0xff4cc8ff,0xff70d3ff,
+ 0xff4cc7ff,0xff4bc7ff,0xff4bc6ff,0xff4ac7ff,0xff49c6ff,0xff6ed1ff,0xff48c6ff,0xff48c5ff,0xff47c5ff,0xff6bd1ff,0xff46c4ff,0xff6ad0ff,0xff46c3ff,0xff6acfff,
+ 0xff6acfff,0xff44c2ff,0xff43c2ff,0xff42c2ff,0xff42c2ff,0xff41c1ff,0xff42c1ff,0xff41c0ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3dbfff,
+ 0xff3dbfff,0xff3cbeff,0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff3abdff,0xff3abcff,0xff3abcff,0xff39bcff,0xff38bcff,0xff38bbff,0xff37baff,0xff37bbff,0xff36baff,
+ 0xff36baff,0xff35baff,0xff35baff,0xff34b9ff,0xff34b8ff,0xff34b8ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff32b7ff,0xff31b6ff,0xff31b6ff,0xff2fb6ff,0xff2fb6ff,
+ 0xff2fb6ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2db5ff,0xff2cb3ff,0xff2cb3ff,0xff2bb4ff,0xff2bb3ff,0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff28b1ff,
+ 0xff27b1ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff25afff,0xff25b0ff,0xff25b0ff,0xff26b1ff,0xff27b0ff,0xff27b1ff,0xff27b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,
+ 0xff40bdff,0xff60cbff,0xff41bfff,0xff61ccff,0xff62ccff,0xff42bfff,0xff42c0ff,0xff63ccff,0xff63ccff,0xff53c7ff,0xff54c7ff,0xff44c1ff,0xff45c1ff,0xff65ceff,
+ 0xff46c3ff,0xff67cfff,0xff47c3ff,0xff68cfff,0xff47c5ff,0xff78d5ff,0xff57c9ff,0xff47c3ff,0xff47c3ff,0xff46c3ff,0xff45c2ff,0xff65ceff,0xff44c1ff,0xff44c1ff,
+ 0xff63cdff,0xff44c1ff,0xff63ccff,0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff61ccff,0xff41bfff,0xff40bfff,0xff40bdff,0xff3fbdff,0xff3fbdff,0xff3fbcff,0xff5fc9ff,
+ 0xff3dbbff,0xff5ec8ff,0xff3cbbff,0xff5cc7ff,0xff3cbaff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff5bc6ff,0xff39b9ff,0xff39b8ff,0xff38b8ff,0xff59c5ff,
+ 0xff37b7ff,0xff6acbff,0xff36b7ff,0xff58c3ff,0xff58c3ff,0xff35b5ff,0xff34b4ff,0xff45bbff,0xff33b3ff,0xff33b4ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,
+ 0xff31b2ff,0xff30b2ff,0xff30b1ff,0xff30b1ff,0xff30b1ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eb0ff,0xff2eaeff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2cacff,
+ 0xff2aacff,0xff2bacff,0xff2aabff,0xff29acff,0xff29abff,0xff29aaff,0xff28aaff,0xff28aaff,0xff28a9ff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a8ff,0xff25a8ff,
+ 0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff22a5ff,0xff22a5ff,0xff21a4ff,0xff20a3ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,
+ 0xff1fa2ff,0xff1fa2ff,0xff1fa1ff,0xff1ea2ff,0xff1ea1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,0xff1b9fff,0xff1ba0ff,0xff1ca1ff,0xff1da1ff,0xff1da1ff,
+ 0xff1da1ff,0xff1fa1ff,0xff1fa1ff,0xff1fa3ff,0xff4fcaff,0xff62cfff,0xff51caff,0xff62d0ff,0xff51ccff,0xff75d6ff,0xff76d6ff,0xff64d1ff,0xff397790,0xff307390,
+ 0xff3a7790,0xff307490,0xff447a90,0xff447a90,0xff3b7890,0xff3b7790,0xff327590,0xff3b7890,0xff457b90,0xff3c7890,0xff457b90,0xff3c7890,0xff439dc2,0xff57cfff,
+ 0xff57ceff,0xff56ceff,0xff77d8ff,0xff77d8ff,0xff65d2ff,0xff66d2ff,0xff76d6ff,0xff76d6ff,0xff52ccff,0xff75d6ff,0xff75d6ff,0xff62d0ff,0xff50caff,0xff50caff,
+ 0xff50caff,0xff4fc9ff,0xff72d4ff,0xff72d4ff,0xff60ceff,0xff54b6e2,0xff358cb2,0xff387a98,0xff2b7191,0xff2b7191,0xff2b7191,0xff2d789a,0xff4192b7,0xff65c1eb,
+ 0xff6ed1ff,0xff48c5ff,0xff6cd1ff,0xff6cd0ff,0xff59caff,0xff59caff,0xff6acfff,0xff58caff,0xff44c2ff,0xff6acfff,0xff69ceff,0xff43c2ff,0xff42c2ff,0xff42c1ff,
+ 0xff41c1ff,0xff41c1ff,0xff40c1ff,0xff3fc0ff,0xff3fc0ff,0xff3ec0ff,0xff3ebfff,0xff3ebeff,0xff3dbeff,0xff226c90,0xff226b90,0xff226b90,0xff216b90,0xff2c90c2,
+ 0xff3abcff,0xff3abcff,0xff39bcff,0xff39bcff,0xff38bbff,0xff38bbff,0xff36bbff,0xff36baff,0xff36baff,0xff35baff,0xff35b9ff,0xff2fa4e2,0xff2481b2,0xff1e6e98,
+ 0xff1d6991,0xff1c6991,0xff1c6891,0xff1e6f9a,0xff2383b7,0xff2ca9eb,0xff30b6ff,0xff30b6ff,0xff2fb5ff,0xff2eb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db4ff,0xff2cb4ff,
+ 0xff2cb3ff,0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,0xff2ab2ff,0xff29b2ff,0xff1f87c2,0xff176490,0xff176490,0xff166490,0xff166390,0xff26b0ff,0xff26b0ff,0xff25afff,
+ 0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,
+ 0xff42c0ff,0xff42c0ff,0xff256d90,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff286f90,0xffffffff,
+ 0xffffffff,0xffc6d8e1,0xff3694c2,0xff46c3ff,0xff46c2ff,0xff45c2ff,0xff44c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,0xff43c0ff,0xff42c0ff,0xff42c0ff,0xff41bfff,
+ 0xff41bfff,0xff41bfff,0xff40bdff,0xff40bdff,0xff40bdff,0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff2b83b2,0xff2e7196,0xff93b6c9,0xffdae6ec,0xfff6f9fa,0xfffeffff,
+ 0xfff4f7f9,0xffd3e1e9,0xff7ea8bf,0xff216990,0xff33a5e4,0xff39b8ff,0xff38b8ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,0xff37b5ff,0xff36b5ff,0xff35b5ff,0xff35b5ff,
+ 0xff35b4ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff31b1ff,0xff31b1ff,0xff30b2ff,0xff30b1ff,0xff2fb1ff,0xff1b6390,
+ 0xffffffff,0xffffffff,0xffc2d5e1,0xff2384c2,0xff2daeff,0xff2dadff,0xff2cadff,0xff2badff,0xff2badff,0xff2bacff,0xff2aacff,0xff2aabff,0xff29abff,0xff28abff,
+ 0xff1c77b2,0xff226896,0xff8db1c9,0xffd8e4ec,0xfff6f8fa,0xfffeffff,0xfff3f7f9,0xffd1dfe9,0xff77a2bf,0xff165f90,0xff2095e4,0xff24a7ff,0xff23a5ff,0xff23a5ff,
+ 0xff23a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff20a2ff,0xff177bc2,0xffc0d3e1,0xffffffff,0xffffffff,
+ 0xff105a90,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,0xff1c9fff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1ea2ff,0xff1ea1ff,0xff1fa1ff,0xff1fa2ff,0xff4fcaff,0xff50caff,
+ 0xff51caff,0xff51caff,0xff52ccff,0xff52cbff,0xff53cbff,0xff53ccff,0xff2f7390,0xffcfdee5,0xffcfdee5,0xffcfdfe5,0xfff2f6f7,0xffffffff,0xffffffff,0xffcfdfe5,
+ 0xffd4e0e5,0xffd4e0e5,0xff327590,0xffffffff,0xffffffff,0xffc8dae1,0xff4288a3,0xff487f96,0xff3d7d96,0xff337996,0xff43a1c8,0xff55ceff,0xff4fc2f1,0xff3c93b7,
+ 0xff317896,0xff317896,0xff307896,0xff307896,0xff398fb4,0xff4cbdee,0xff50caff,0xff50caff,0xff50caff,0xff4fc9ff,0xff4ec9ff,0xff43acda,0xff397a97,0xffdce8ed,
+ 0xffffffff,0xffffffff,0xffdde9ee,0xffd6e4ea,0xfffbfcfc,0xffffffff,0xffffffff,0xff92b6c6,0xff40b0e4,0xff296f90,0xff286f90,0xff286f90,0xff286f90,0xff297294,
+ 0xff287294,0xff277194,0xff318cb7,0xff287396,0xff277296,0xff277296,0xff277296,0xff2f89b4,0xff3db4ee,0xff3db5f1,0xff2e8ab7,0xff257196,0xff267196,0xff247096,
+ 0xff247096,0xff2b87b4,0xff39b1ee,0xff226b90,0xffffffff,0xffffffff,0xffc4d8e1,0xff2c90c2,0xff216a90,0xff206a90,0xff206a90,0xff206a90,0xff2f9ed7,0xff37bbff,
+ 0xff37bbff,0xff36baff,0xff36baff,0xff2d9fda,0xff2c7297,0xffdae6ed,0xffffffff,0xffffffff,0xffdbe7ee,0xffd4e2ea,0xfffafbfc,0xffffffff,0xffffffff,0xff8bb1c6,
+ 0xff3da9e4,0xff2daef5,0xff2387bd,0xff1b6c98,0xff1b6b98,0xff277098,0xff1b6b98,0xff2083ba,0xff29acf3,0xff2bb3ff,0xff2397d7,0xff1a6d9c,0xff196d9b,0xff196c9b,
+ 0xff196c9b,0xffc1d6e1,0xffffffff,0xffffffff,0xff156490,0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff3bb8ff,0xff26b1ff,0xff26b1ff,0xff27b1ff,0xff27b2ff,0xff28b1ff,
+ 0xff28b1ff,0xff29b2ff,0xff3fbcff,0xff41bdff,0xff40bfff,0xff41bfff,0xff41bfff,0xff42bfff,0xff41c0ff,0xff43c0ff,0xff4997bd,0xff328fbd,0xff328fbd,0xff2a779d,
+ 0xffc5d8e1,0xffffffff,0xffffffff,0xff286e90,0xff4c99bd,0xff3591bd,0xff296f90,0xffffffff,0xffffffff,0xffcbdbe3,0xff9abbcb,0xffebf2f5,0xfff9fafb,0xffbfd4de,
+ 0xff347797,0xff3ba9de,0xff266d90,0xff72a0b7,0xffd4e2e9,0xfff8fafb,0xfff9fafb,0xffdbe5ea,0xff86aabc,0xff2d6f90,0xff3bafec,0xff40bdff,0xff3fbdff,0xff3fbdff,
+ 0xff5fc9ff,0xff287aa5,0xffa2c0d0,0xffffffff,0xffffffff,0xff719fb8,0xff226a90,0xff226b93,0xff4b85a5,0xff83abc1,0xff6a9ab5,0xff5889a4,0xff2b88bd,0xff206890,
+ 0xffffffff,0xffffffff,0xffcddde6,0xffc8dae3,0xfffafbfc,0xff98b9cc,0xff6d9cb7,0xffd3e1e9,0xfff8fafb,0xfff8fafb,0xffd6e3ea,0xff76a2bc,0xff316d90,0xff1d6590,
+ 0xff6c9ab7,0xffd6e2e9,0xfff8fafb,0xfff8fafb,0xffd6e3ea,0xff75a1bc,0xff1b6390,0xff1a6390,0xffffffff,0xffffffff,0xffc2d5e1,0xff1b6290,0xffb2cada,0xffffffff,
+ 0xffffffff,0xffa3c0d3,0xff2592d7,0xff2aacff,0xff29acff,0xff2aabff,0xff29abff,0xff1a6ea5,0xff9cbbd0,0xffffffff,0xffffffff,0xff6998b8,0xff165f90,0xff166193,
+ 0xff417da5,0xff7ca5c1,0xff6294b5,0xff3f7ba4,0xff2881bd,0xff1e6290,0xff5a8db0,0xffc9dae6,0xfff6f8fa,0xfff6f8fa,0xffd1dee6,0xff6193b5,0xff135c90,0xff1b8ddb,
+ 0xff1a6194,0xffa0bed3,0xfff1f5f8,0xfff2f6f8,0xffacc6d8,0xffd4e1ea,0xffffffff,0xffffffff,0xff105a90,0xff1ca0ff,0xff1c9fff,0xff1ba0ff,0xff41b2ff,0xff1ca0ff,
+ 0xff1ca0ff,0xff1da0ff,0xff42b3ff,0xff1fa1ff,0xff1ea2ff,0xff1fa3ff,0xff50caff,0xff62cfff,0xff62cfff,0xff62d0ff,0xff51ccff,0xff75d6ff,0xff75d6ff,0xff53ccff,
+ 0xff76d7ff,0xff54ccff,0xff66d2ff,0xff419dc2,0xffcddbe1,0xffffffff,0xffffffff,0xff317490,0xff7ad9ff,0xff58d0ff,0xff327590,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffa5c1cd,0xff5d96ae,0xff7fa9bb,0xffffffff,0xfffeffff,0xffd9e5ea,0xffdce6ea,0xfffeffff,0xffffffff,0xff84acbe,
+ 0xff4490b1,0xff73d6ff,0xff62cfff,0xff61cfff,0xff83d9ff,0xff427a93,0xffe9f1f4,0xffffffff,0xffe1eaee,0xff357490,0xff4698bd,0xffabc5d1,0xffd2dfe5,0xffcddee5,
+ 0xffcddee5,0xffd2dfe5,0xff297090,0xff337390,0xffffffff,0xffffffff,0xffffffff,0xfff0f4f6,0xffe0e9ee,0xffa2bfcc,0xffffffff,0xfffeffff,0xffd7e4ea,0xffd7e4ea,
+ 0xfffeffff,0xffffffff,0xff8badbe,0xff78a5bb,0xffffffff,0xfffeffff,0xffd7e4ea,0xffd8e4ea,0xfffeffff,0xffffffff,0xff7da8be,0xff387390,0xffffffff,0xffffffff,
+ 0xffc7d8e1,0xffa5c0cd,0xffffffff,0xffffffff,0xffacc3cf,0xff377290,0xff2f9fd7,0xff4cc2ff,0xff5fc8ff,0xff4bc1ff,0xff4ac1ff,0xff2a6f93,0xffeaf0f4,0xffffffff,
+ 0xffdee8ee,0xff1d6890,0xff358ebd,0xffa2c0d1,0xffcadce5,0xffcadce5,0xffcadce5,0xffcadbe5,0xff1b6790,0xff679ab5,0xffffffff,0xffffffff,0xffebf1f5,0xffe7eff4,
+ 0xffffffff,0xffffffff,0xff77a2ba,0xff1c72a3,0xffa5c0cf,0xffffffff,0xffffffff,0xffe7eef3,0xffebf1f5,0xffffffff,0xffffffff,0xffffffff,0xff2e6c90,0xff26b1ff,
+ 0xff26b0ff,0xff3bb8ff,0xff3cb8ff,0xff26b0ff,0xff52c1ff,0xff3db9ff,0xff52c1ff,0xff3ebaff,0xff54c1ff,0xff3fbaff,0xff40bdff,0xff60cbff,0xff61ccff,0xff61ccff,
+ 0xff51c5ff,0xff41bfff,0xff42c0ff,0xff63cdff,0xff63ccff,0xff63cdff,0xff44c1ff,0xff4d9cc2,0xffc5d8e1,0xffffffff,0xffffffff,0xff286e90,0xff67cfff,0xff47c3ff,
+ 0xff286f90,0xffffffff,0xffffffff,0xfff1f5f7,0xff4783a0,0xff598faa,0xffffffff,0xffffffff,0xffc3d6e0,0xff307393,0xffdfe9ee,0xffffffff,0xfff3f6f8,0xffccdde5,
+ 0xffd1dee5,0xfff4f7f8,0xffffffff,0xffdce7ed,0xff437a95,0xff40bdff,0xff5fcbff,0xff3fbdff,0xff5fc9ff,0xff246c93,0xfffbfcfd,0xffffffff,0xffc7d9e3,0xff3f88ae,
+ 0xff4493bd,0xffcedde5,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff216890,0xff337090,0xffffffff,0xffffffff,0xfff9fafb,0xff497f9c,0xff206993,0xffe1eaee,
+ 0xffffffff,0xfff3f6f8,0xffcbdbe5,0xffcadbe5,0xfff4f6f8,0xffffffff,0xffdfe8ed,0xffdee8ee,0xffffffff,0xfff3f6f8,0xffcadbe5,0xffd1dee5,0xfff3f6f8,0xffffffff,
+ 0xffdde7ed,0xff1b6390,0xffffffff,0xffffffff,0xfff5f8f9,0xffffffff,0xffffffff,0xffcadbe6,0xff2d6b90,0xff2694dc,0xff2badff,0xff4dbcff,0xff2aacff,0xff4dbcff,
+ 0xff4cbbff,0xff216793,0xfffbfcfd,0xffffffff,0xffc9d9e3,0xff1b73ae,0xff3689bd,0xffc9dae5,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff145e90,0xffd9e5ed,
+ 0xffffffff,0xffecf2f5,0xff336f96,0xff1e6495,0xffeef2f5,0xffffffff,0xffdfe8ee,0xff286893,0xffe9f0f5,0xffffffff,0xffe9eff4,0xff2d6a94,0xff316d96,0xffedf2f5,
+ 0xffffffff,0xffffffff,0xff105b90,0xff41b2ff,0xff1ba0ff,0xff41b2ff,0xff1ba0ff,0xff41b2ff,0xff1da1ff,0xff2faaff,0xff42b3ff,0xff30aaff,0xff1ea1ff,0xff43b3ff,
+ 0xff50caff,0xff73d5ff,0xff74d5ff,0xff74d6ff,0xff63d1ff,0xff75d6ff,0xff76d6ff,0xff76d6ff,0xff87dcff,0xff76d7ff,0xff55cdff,0xff5ba4c2,0xffcddbe1,0xffffffff,
+ 0xffffffff,0xff317590,0xff7ad9ff,0xff58cfff,0xff327590,0xffffffff,0xffffffff,0xffcbdce3,0xff367f9d,0xff317490,0xffffffff,0xffffffff,0xffc8dae1,0xff3b7a93,
+ 0xfffbfcfc,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfff9fafb,0xff437c95,0xff50cbff,0xff73d5ff,0xff4fcaff,0xff72d4ff,0xff2d7493,
+ 0xffe9f0f4,0xffffffff,0xffe2eaee,0xff3f7790,0xff529cbd,0xff2a7090,0xff2a7090,0xffc6d9e1,0xffffffff,0xffffffff,0xff297090,0xff3e7690,0xffffffff,0xffffffff,
+ 0xffd9e4e9,0xff3f7a95,0xff3e7793,0xfffbfcfc,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfff9fafb,0xfffbfcfc,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfff9fafb,0xff387390,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffcfdfd,0xff5f8fa7,0xff2988ba,
+ 0xff38bcff,0xff60c9ff,0xff37baff,0xff5fc9ff,0xff5ec8ff,0xff1f6b93,0xffe8f0f4,0xffffffff,0xffe0e9ee,0xff1d6890,0xff5398bd,0xff1d6890,0xff1c6890,0xffc3d6e1,
+ 0xffffffff,0xffffffff,0xff1b6790,0xfffafbfc,0xffffffff,0xffcfdde5,0xff1d72a1,0xff1c72a1,0xffccdbe3,0xffffffff,0xfffafbfc,0xff327093,0xfffbfcfd,0xffffffff,
+ 0xffccdbe3,0xff357ba2,0xff347aa1,0xffccdbe3,0xffffffff,0xffffffff,0xff2e6c90,0xff3cb8ff,0xff25b0ff,0xff51bfff,0xff26afff,0xff52c0ff,0xff27b1ff,0xff27b1ff,
+ 0xff52c1ff,0xff53c1ff,0xff54c1ff,0xff69c9ff,0xff40bdff,0xff60cbff,0xff50c5ff,0xff61cbff,0xff50c5ff,0xff62ccff,0xff62ccff,0xff63ccff,0xff63cdff,0xff43c1ff,
+ 0xff64cdff,0xff4097c2,0xffcadae1,0xffffffff,0xffffffff,0xff286e90,0xff67cfff,0xff48c5ff,0xff296f90,0xffffffff,0xffffffff,0xffc8d9e1,0xff3594c1,0xff286e90,
+ 0xffffffff,0xffffffff,0xffc8d9e1,0xff437a93,0xffe1ebef,0xffffffff,0xffdee8ee,0xff2a7093,0xff387390,0xff6d99ae,0xff6391a8,0xff45809d,0xff387795,0xff40bdff,
+ 0xff5fcbff,0xff3fbcff,0xff4fc2ff,0xff3d82a5,0xffa6c1d0,0xffffffff,0xffffffff,0xff7aa1b6,0xff357090,0xff226a92,0xff4984a4,0xffe7eff3,0xffffffff,0xffffffff,
+ 0xff337090,0xff337090,0xffffffff,0xffffffff,0xffcadae2,0xff408db7,0xff337293,0xffe1eaef,0xffffffff,0xffdde7ee,0xff236a93,0xff1e6690,0xff6894ae,0xff5d8ca8,
+ 0xff51819d,0xffe0eaef,0xffffffff,0xffe1e9ee,0xff2a6c93,0xff2f6d90,0xff598eae,0xff4d85a8,0xff3e799d,0xff2e6c90,0xffffffff,0xffffffff,0xffffffff,0xff9bb8c9,
+ 0xfff8fafb,0xffffffff,0xffcfdee6,0xff2d6b90,0xff38a8ee,0xff4dbcff,0xff4cbcff,0xff4cbbff,0xff4cbbff,0xff1a6fa5,0xff9dbcd0,0xffffffff,0xffffffff,0xff739cb6,
+ 0xff2a6890,0xff166192,0xff3f7ba4,0xffe6eef3,0xffffffff,0xffffffff,0xff145e90,0xffdbe6ee,0xffffffff,0xffedf2f5,0xff1e6495,0xff1c6394,0xffeaf1f5,0xffffffff,
+ 0xffdee7ee,0xff1d6493,0xffe3ebf0,0xffffffff,0xffebf1f5,0xff2f6b95,0xff256795,0xffebf1f5,0xffffffff,0xffffffff,0xff256590,0xff2ea9ff,0xff41b1ff,0xff1ba0ff,
+ 0xff1ba0ff,0xff2ea9ff,0xff41b3ff,0xff41b2ff,0xff42b3ff,0xff42b3ff,0xff43b3ff,0xff57bcff,0xff4fcaff,0xff50caff,0xff51cbff,0xff51cbff,0xff51cbff,0xff52ccff,
+ 0xff52ccff,0xff53ccff,0xff54cdff,0xff54ccff,0xff55cdff,0xff419cc2,0xffc8dae1,0xffffffff,0xffffffff,0xff327590,0xff8addff,0xff7ad9ff,0xff327590,0xffffffff,
+ 0xffffffff,0xffc8dae1,0xff4fa1c2,0xff447a90,0xffffffff,0xffffffff,0xffc8dae1,0xff3989ab,0xff83acbd,0xffffffff,0xffffffff,0xffe9f0f3,0xffe2ebef,0xffffffff,
+ 0xffffffff,0xff8ab0c1,0xff49b9e9,0xff50caff,0xff4fcaff,0xff4fc9ff,0xff4fc9ff,0xff43acda,0xff3c7c99,0xffe1ebef,0xffffffff,0xffffffff,0xffdee9ee,0xffd7e5ea,
+ 0xfffcfdfd,0xffffffff,0xffffffff,0xffecf2f5,0xff296f90,0xff296f90,0xffffffff,0xffffffff,0xffc6d8e1,0xff519dc2,0xff478bab,0xff8aadbd,0xffffffff,0xffffffff,
+ 0xffe8eff3,0xffe1ebef,0xffffffff,0xffffffff,0xff85adc1,0xff7da8bd,0xffffffff,0xffffffff,0xffe7eff3,0xffe0eaef,0xffffffff,0xffffffff,0xff84acc1,0xff226c90,
+ 0xffffffff,0xffffffff,0xffc8dae4,0xff216b90,0xff9ebfcf,0xffffffff,0xffffffff,0xff76a4bb,0xff2377a1,0xff38bbff,0xff37bbff,0xff36baff,0xff36baff,0xff2e9fda,
+ 0xff2f7599,0xffdfeaef,0xffffffff,0xffffffff,0xffdfe9ee,0xffd5e3ea,0xfffcfdfd,0xffffffff,0xffffffff,0xffebf1f5,0xff1b6790,0xff6a9bb6,0xffffffff,0xffffffff,
+ 0xffe8f0f4,0xffe7eff4,0xffffffff,0xffffffff,0xff6a9bb7,0xff1d77aa,0xff8cb2c8,0xffffffff,0xffffffff,0xffe6eef3,0xffe8eff4,0xffffffff,0xffffffff,0xffffffff,
+ 0xff156390,0xff26b0ff,0xff52c0ff,0xff25afff,0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff28b2ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff40bdff,
+ 0xff40bdff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42bfff,0xff42c0ff,0xff43c0ff,0xff44c1ff,0xff44c1ff,0xff3494c2,0xffc5d8e1,0xffffffff,0xffffffff,0xff286e90,
+ 0xff47c3ff,0xff47c5ff,0xff296f90,0xffffffff,0xffffffff,0xffc6d8e1,0xff3594c2,0xff286e90,0xffffffff,0xffffffff,0xffc5d8e1,0xff3494c2,0xff266d90,0xff7da8bd,
+ 0xffdde8ee,0xfffafbfc,0xfffafbfc,0xffdbe7ed,0xff7fa9be,0xff256c90,0xff3bafe9,0xff40bdff,0xff3fbdff,0xff3fbcff,0xff3fbdff,0xff3ebbfe,0xff2a7fac,0xff327498,
+ 0xff9abbcd,0xffdce7ee,0xfff8fafb,0xfffafbfc,0xffedf2f5,0xffc6d9e3,0xff7da7be,0xff296e94,0xff2475a2,0xff206890,0xffffffff,0xffffffff,0xffc3d7e1,0xff2a8ac2,
+ 0xff32aaed,0xff1e6690,0xff79a4bd,0xffdbe7ee,0xfffafbfc,0xfffafbfc,0xffdae6ed,0xff7ba5be,0xff1d6590,0xff1d6590,0xff78a3bd,0xffdbe7ee,0xfffafbfc,0xfffafbfc,
+ 0xffd9e6ed,0xff7aa4be,0xff1b6490,0xff1b6390,0xffffffff,0xffffffff,0xffc2d5e1,0xff2383c0,0xff2e709a,0xfff5f8fa,0xffffffff,0xffecf2f5,0xff2976a7,0xff2bacff,
+ 0xff2aabff,0xff29acff,0xff29abff,0xff29aafe,0xff1b73ac,0xff276b98,0xff95b7cd,0xffdae6ee,0xfff8fafb,0xfffafbfc,0xffecf2f5,0xffc3d6e3,0xff76a1be,0xff1d6594,
+ 0xff176ba2,0xff145d90,0xff5d90b2,0xffcbdbe7,0xfff7f9fb,0xfff7f9fb,0xffccdce6,0xff5f91b4,0xff135d90,0xff1d92e3,0xff175f92,0xff9fbcd1,0xfff1f5f8,0xfff4f7f9,
+ 0xffaac4d7,0xffc8d9e5,0xffffffff,0xffffffff,0xff105b90,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1ca0ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,
+ 0xff1fa2ff,0xff1fa2ff,0xff4fc9ff,0xff62cfff,0xff51cbff,0xff63d0ff,0xff52cbff,0xff53cbff,0xff53ccff,0xff53cdff,0xff64d1ff,0xff54cdff,0xff55cdff,0xff419dc2,
+ 0xff307490,0xff3a7790,0xff317490,0xff327490,0xff58cfff,0xff58d0ff,0xff327590,0xff337590,0xff327590,0xff327590,0xff439dc2,0xff317490,0xff317590,0xff317490,
+ 0xff317490,0xff419cc2,0xff4fbfed,0xff3a8db0,0xff447d94,0xff307694,0xff307694,0xff397994,0xff4591b2,0xff4bbcec,0xff50caff,0xff50caff,0xff50caff,0xff4fc9ff,
+ 0xff4fc9ff,0xff60ceff,0xff4ec8ff,0xff43afde,0xff348ab0,0xff2d7596,0xff2c7393,0xff2b7393,0xff2b7393,0xff2f7da1,0xff3896c1,0xff44b7ec,0xff48c6ff,0xff286f90,
+ 0xff337390,0xff286f90,0xff286f90,0xff3595c2,0xff45c4ff,0xff40b5ed,0xff2f87b0,0xff277194,0xff277194,0xff267194,0xff267194,0xff2e87b2,0xff3cb3ec,0xff3cb3ed,
+ 0xff2d85b0,0xff256f94,0xff256f94,0xff256f94,0xff246f94,0xff2b85b2,0xff38b0ec,0xff226c90,0xff226b90,0xff216b90,0xff216b90,0xff2c90c2,0xff237199,0xff216a90,
+ 0xff206a90,0xff206a90,0xff2376a1,0xff38bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff36baff,0xff35b9ff,0xff2da1de,0xff2480b0,0xff1f6c96,0xff1d6a93,0xff1d6a93,
+ 0xff1d6993,0xff2074a1,0xff258ac1,0xff2da9ec,0xff2fb6ff,0xff2daff5,0xff2285bc,0xff1b6c97,0xff1b6b97,0xff1b6b97,0xff1b6b97,0xff2083ba,0xff29abf4,0xff2bb4ff,
+ 0xff2497d7,0xff1a6e9c,0xff196c9a,0xff196c9a,0xff186b9a,0xff176490,0xff166490,0xff166490,0xff166390,0xff26b1ff,0xff26b0ff,0xff25afff,0xff26afff,0xff26b0ff,
+ 0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff85d7ff,0xff40bdff,0xff85d8ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42c1ff,
+ 0xff63ccff,0xff43c1ff,0xff44c1ff,0xff45c1ff,0xff45c2ff,0xff56c8ff,0xff46c2ff,0xff46c3ff,0xff47c3ff,0xff47c5ff,0xff47c5ff,0xff49c5ff,0xff47c3ff,0xff47c3ff,
+ 0xff47c3ff,0xff46c3ff,0xff45c3ff,0xff45c2ff,0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,0xff63ccff,0xff42c0ff,0xff41c0ff,0xff41c0ff,0xff61ccff,0xff41bfff,
+ 0xff40bfff,0xff40bdff,0xff40bdff,0xff3fbdff,0xff3ebcff,0xff4ec2ff,0xff3ebbff,0xff3dbcff,0xff3dbbff,0xff3cbbff,0xff3cbbff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,
+ 0xff3ab9ff,0xff3ab9ff,0xff39b8ff,0xff39b9ff,0xff5ac6ff,0xff38b8ff,0xff37b7ff,0xff37b5ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff35b5ff,0xff34b4ff,0xff34b4ff,
+ 0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb1ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,
+ 0xff2eaeff,0xff2eadff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2aacff,0xff2aacff,0xff29acff,0xff29abff,0xff29aaff,0xff28abff,0xff28aaff,
+ 0xff28aaff,0xff27aaff,0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff23a4ff,
+ 0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff21a4ff,0xff20a3ff,0xff20a2ff,0xff1fa3ff,0xff1fa2ff,0xff1ea1ff,0xff1ea2ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca0ff,
+ 0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff4fcaff,0xff73d5ff,0xff96dfff,0xff74d6ff,
+ 0xff62d0ff,0xff75d6ff,0xff75d6ff,0xff64d1ff,0xff76d7ff,0xff65d2ff,0xff66d2ff,0xff55ceff,0xff66d2ff,0xff78d8ff,0xff57ceff,0xff8addff,0xff79d9ff,0xff7ad9ff,
+ 0xff6ad5ff,0xff7bd9ff,0xff7ad9ff,0xff69d4ff,0xff57cfff,0xff57cfff,0xff57ceff,0xff67d3ff,0xff78d8ff,0xff78d7ff,0xff65d2ff,0xff54ccff,0xff76d6ff,0xff53ccff,
+ 0xff53ccff,0xff52ccff,0xff74d6ff,0xff51cbff,0xff50caff,0xff50cbff,0xff4fcaff,0xff4fcaff,0xff60ceff,0xff72d4ff,0xff4ec9ff,0xff82d9ff,0xff71d3ff,0xff70d3ff,
+ 0xff4bc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,0xff6ed1ff,0xff6dd1ff,0xff6dd1ff,0xff5acbff,0xff7ed6ff,0xff6cd1ff,0xff47c4ff,0xff6ad0ff,0xff45c3ff,0xff6acfff,
+ 0xff6acfff,0xff6acfff,0xff69cfff,0xff55c8ff,0xff68ceff,0xff68cdff,0xff67cdff,0xff41c1ff,0xff40c0ff,0xff3fc0ff,0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3dbfff,
+ 0xff3dbfff,0xff3dbeff,0xff3cbdff,0xff3bbeff,0xff3bbdff,0xff3abdff,0xff3abcff,0xff3abcff,0xff39bcff,0xff38bbff,0xff38bcff,0xff38bbff,0xff37bbff,0xff37baff,
+ 0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff33b9ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb6ff,
+ 0xff2fb5ff,0xff2eb5ff,0xff2db5ff,0xff2db4ff,0xff2db4ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,0xff2bb3ff,0xff2bb2ff,0xff29b2ff,0xff29b3ff,0xff29b2ff,0xff29b2ff,
+ 0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,0xff26afff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff27b1ff,0xff27b0ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,
+ 0xff40bdff,0xff60cbff,0xff41bfff,0xff61ccff,0xff41c0ff,0xff62ccff,0xff63ccff,0xff63ccff,0xff74d2ff,0xff63ccff,0xff43c1ff,0xff44c1ff,0xff45c1ff,0xff65ceff,
+ 0xff46c2ff,0xff67cfff,0xff46c3ff,0xff67cfff,0xff68cfff,0xff48c5ff,0xff67cfff,0xff47c3ff,0xff47c3ff,0xff47c3ff,0xff45c2ff,0xff46c2ff,0xff65ceff,0xff64cdff,
+ 0xff63cdff,0xff44c1ff,0xff63ccff,0xff42c0ff,0xff42c0ff,0xff41bfff,0xff61ccff,0xff41bfff,0xff41bfff,0xff40bdff,0xff3fbdff,0xff3fbcff,0xff3ebcff,0xff5fc9ff,
+ 0xff3dbbff,0xff5ec8ff,0xff3dbbff,0xff5dc7ff,0xff3cbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff5cc6ff,0xff3ab9ff,0xff39b8ff,0xff39b8ff,0xff5bc6ff,0xff38b7ff,
+ 0xff37b7ff,0xff58c5ff,0xff36b7ff,0xff58c5ff,0xff58c3ff,0xff35b5ff,0xff35b4ff,0xff57c2ff,0xff67c8ff,0xff56c2ff,0xff67c8ff,0xff33b3ff,0xff32b2ff,0xff31b2ff,
+ 0xff31b2ff,0xff30b2ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2eb0ff,0xff2eaeff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2dadff,0xff2dadff,0xff2cadff,0xff2bacff,
+ 0xff2bacff,0xff2bacff,0xff2aabff,0xff29abff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27aaff,0xff27aaff,0xff26a9ff,0xff25a9ff,0xff25a8ff,
+ 0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff21a5ff,0xff21a4ff,0xff21a4ff,0xff20a3ff,0xff20a2ff,0xff20a2ff,
+ 0xff20a2ff,0xff1fa3ff,0xff1fa1ff,0xff1ea1ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1ca0ff,0xff1c9fff,0xff1b9fff,0xff1ca0ff,0xff1ca0ff,0xff1da1ff,0xff1da1ff,
+ 0xff1da1ff,0xff1fa2ff,0xff1ea2ff,0xff1fa2ff,0xff4fc9ff,0xff73d5ff,0xff50caff,0xff74d6ff,0xff74d6ff,0xff52cbff,0xff53ccff,0xff76d6ff,0xff76d6ff,0xff65d2ff,
+ 0xff65d2ff,0xff56cdff,0xff55cdff,0xff78d8ff,0xff56ceff,0xff79d8ff,0xff58cfff,0xff7bd9ff,0xff59d0ff,0xff8bdeff,0xff6ad4ff,0xff58cfff,0xff58cfff,0xff57cfff,
+ 0xff57ceff,0xff79d8ff,0xff55ceff,0xff56ceff,0xff76d7ff,0xff54ccff,0xff76d6ff,0xff53ccff,0xff53ccff,0xff52ccff,0xff75d6ff,0xff51cbff,0xff50caff,0xff50caff,
+ 0xff50c9ff,0xff4fcaff,0xff4ecaff,0xff72d4ff,0xff4ec9ff,0xff71d3ff,0xff4dc8ff,0xff70d3ff,0xff4bc7ff,0xff4bc7ff,0xff4bc7ff,0xff4ac7ff,0xff6fd1ff,0xff49c6ff,
+ 0xff5acbff,0xff47c6ff,0xff6dd1ff,0xff47c4ff,0xff5acbff,0xff6bcfff,0xff6acfff,0xff7dd5ff,0xff6acfff,0xff57c8ff,0xff43c2ff,0xff69ceff,0xff68ceff,0xff42c2ff,
+ 0xff54c7ff,0xff41c0ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3ebfff,0xff3fbfff,0xff3ebeff,0xff3dbeff,0xff3cbeff,0xff3dbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,
+ 0xff3abcff,0xff3abcff,0xff39bcff,0xff38bbff,0xff38bbff,0xff37bbff,0xff37bbff,0xff37baff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,
+ 0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb6ff,0xff2fb6ff,0xff2eb5ff,0xff2eb4ff,0xff2db4ff,0xff2db5ff,0xff2cb4ff,
+ 0xff2cb3ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,
+ 0xff25b0ff,0xff26b0ff,0xff26b1ff,0xff27b1ff,0xff27b1ff,0xff28b2ff,0xff28b2ff,0xff29b2ff,0xff40bdff,0xff50c3ff,0xff41bdff,0xff50c5ff,0xff41bfff,0xff62ccff,
+ 0xff63ccff,0xff52c6ff,0xff52c6ff,0xff43c0ff,0xff54c7ff,0xff44c2ff,0xff65cdff,0xff66ceff,0xff55c8ff,0xff56c8ff,0xff46c3ff,0xff58cbff,0xff68cfff,0xff59cbff,
+ 0xff68cfff,0xff57c9ff,0xff46c3ff,0xff46c3ff,0xff46c2ff,0xff45c2ff,0xff65cdff,0xff64cdff,0xff54c7ff,0xff53c7ff,0xff63ccff,0xff63ccff,0xff42bfff,0xff62ccff,
+ 0xff61ccff,0xff50c5ff,0xff40bfff,0xff40bdff,0xff3fbdff,0xff3fbdff,0xff5fcbff,0xff5fc9ff,0xff4dc2ff,0xff4dc2ff,0xff3cbbff,0xff4cc1ff,0xff3bbaff,0xff3bbaff,
+ 0xff3abaff,0xff3ab9ff,0xff49c0ff,0xff5bc6ff,0xff49c0ff,0xff39b8ff,0xff38b7ff,0xff5ac5ff,0xff37b8ff,0xff47bdff,0xff36b7ff,0xff58c3ff,0xff58c3ff,0xff46bbff,
+ 0xff57c2ff,0xff34b4ff,0xff44baff,0xff56c1ff,0xff43baff,0xff33b3ff,0xff32b3ff,0xff32b2ff,0xff31b2ff,0xff30b2ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2fb1ff,
+ 0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2daeff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2badff,0xff2bacff,0xff2bacff,0xff2aacff,0xff29abff,0xff29abff,0xff29abff,
+ 0xff28aaff,0xff28aaff,0xff27aaff,0xff27a9ff,0xff27a9ff,0xff27a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff24a7ff,0xff23a5ff,
+ 0xff23a4ff,0xff22a4ff,0xff22a5ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1fa2ff,0xff1ea2ff,0xff1ea1ff,0xff1da1ff,
+ 0xff1ca1ff,0xff1ca0ff,0xff1ba0ff,0xff1b9fff,0xff1c9fff,0xff1ca0ff,0xff1ca1ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff50caff,
+ 0xff51caff,0xff51cbff,0xff52cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff53ccff,0xff54cdff,0xff55cdff,0xff55ceff,0xff55cdff,0xff56ceff,0xff56ceff,0xff57cfff,
+ 0xff58cfff,0xff58cfff,0xff59d0ff,0xff7bd9ff,0xff7bd9ff,0xff58d0ff,0xff58cfff,0xff57cfff,0xff56cfff,0xff57ceff,0xff56ceff,0xff55ceff,0xff55ceff,0xff54ccff,
+ 0xff54ccff,0xff53ccff,0xff53ccff,0xff52cbff,0xff51ccff,0xff51cbff,0xff50cbff,0xff50caff,0xff4fcaff,0xff4fcaff,0xff4ecaff,0xff4ec9ff,0xff4dc9ff,0xff4dc8ff,
+ 0xff4dc8ff,0xff4cc7ff,0xff4bc7ff,0xff4bc7ff,0xff4ac6ff,0xff49c6ff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,0xff47c6ff,0xff48c5ff,0xff47c4ff,0xff47c4ff,0xff59caff,
+ 0xff6bcfff,0xff58c9ff,0xff57c9ff,0xff44c2ff,0xff43c2ff,0xff42c2ff,0xff42c2ff,0xff42c2ff,0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff3fc0ff,0xff40c0ff,0xff3ec0ff,
+ 0xff3ec0ff,0xff3ebfff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3bbeff,0xff3bbdff,0xff3abdff,0xff3abdff,0xff39bcff,0xff39bcff,0xff39bbff,0xff38bcff,0xff37bbff,
+ 0xff37baff,0xff37baff,0xff36baff,0xff36baff,0xff34b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,
+ 0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb6ff,0xff2eb5ff,0xff2db5ff,0xff2cb4ff,0xff2db4ff,0xff2bb4ff,0xff2bb3ff,0xff2bb3ff,0xff2ab3ff,0xff29b3ff,0xff29b2ff,
+ 0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff27b0ff,0xff26b1ff,0xff26afff,0xff25afff,0xff26b0ff,0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,
+ 0xff28b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42bfff,0xff42c0ff,0xff42c0ff,0xff43c0ff,0xff43c1ff,0xff44c1ff,0xff44c2ff,
+ 0xff45c1ff,0xff45c2ff,0xff45c2ff,0xff46c3ff,0xff67cfff,0xff67cfff,0xff48c5ff,0xff48c5ff,0xff48c3ff,0xff48c5ff,0xff56c9ff,0xff66cfff,0xff56c8ff,0xff46c2ff,
+ 0xff44c2ff,0xff44c1ff,0xff43c1ff,0xff44c0ff,0xff42c0ff,0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff40bfff,0xff40bdff,0xff3fbdff,
+ 0xff3ebcff,0xff3ebcff,0xff3ebcff,0xff3dbbff,0xff3cbbff,0xff3cbbff,0xff3bbbff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff39b8ff,
+ 0xff38b8ff,0xff38b7ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,0xff35b5ff,0xff36b5ff,0xff35b5ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff2fa9f1,
+ 0xff2175a7,0xff1c6793,0xff1c6693,0xff1c6793,0xff1d6c9c,0xff2ba3eb,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2daeff,
+ 0xff2cadff,0xff2cacff,0xff2bacff,0xff2babff,0xff29acff,0xff29acff,0xff29abff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff26a9ff,0xff26a8ff,
+ 0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff36aeff,0xff24a7ff,0xff23a7ff,0xff23a7ff,0xff22a5ff,0xff33adff,0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff20a3ff,
+ 0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1da2ff,0xff1da1ff,0xff1ca0ff,0xff1ca1ff,0xff1ca0ff,0xff1ba0ff,0xff2ea9ff,0xff1ca0ff,
+ 0xff1ca0ff,0xff1da0ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff50cbff,0xff51cbff,0xff51cbff,0xff52cbff,0xff53cbff,0xff53ccff,
+ 0xff76d6ff,0xff54cdff,0xff54cdff,0xff56cdff,0xff56ceff,0xff56ceff,0xff57ceff,0xff57cfff,0xff7ad9ff,0xff59cfff,0xff6ad5ff,0xff7bd9ff,0xff7bd9ff,0xff69d5ff,
+ 0xff57cfff,0xff57ceff,0xff79d8ff,0xff56ceff,0xff55ceff,0xff55ceff,0xff54cdff,0xff54cdff,0xff53cdff,0xff53ccff,0xff75d6ff,0xff75d6ff,0xff74d6ff,0xff62d0ff,
+ 0xff50cbff,0xff50caff,0xff4fcaff,0xff4fc9ff,0xff72d4ff,0xff4ec9ff,0xff4ec9ff,0xff4dc9ff,0xff4dc8ff,0xff4cc7ff,0xff4bc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,
+ 0xff49c6ff,0xff6ed1ff,0xff48c5ff,0xff47c5ff,0xff47c5ff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c4ff,0xff45c3ff,0xff44c2ff,0xff43c3ff,0xff44c2ff,0xff43c2ff,
+ 0xff42c1ff,0xff42c1ff,0xff67cdff,0xff297aa1,0xff71a0b7,0xffe9f0f3,0xfffcfdfd,0xfff2f6f8,0xff83b0c6,0xff39b0eb,0xff3dbfff,0xff3dbeff,0xff3cbdff,0xff3cbeff,
+ 0xff3bbdff,0xff3bbdff,0xff3abdff,0xff39bcff,0xff61caff,0xff38bcff,0xff38bbff,0xff37bbff,0xff37baff,0xff36baff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,
+ 0xff34b9ff,0xff34b8ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff32b7ff,0xff30b7ff,0xff30b7ff,0xff45bdff,0xff44bdff,0xff2eb6ff,0xff2eb5ff,0xff43bcff,0xff42bcff,
+ 0xff57c3ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,
+ 0xff25afff,0xff25b0ff,0xff52c0ff,0xff26b0ff,0xff27b1ff,0xff27b0ff,0xff53c1ff,0xff29b2ff,0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff50c3ff,0xff50c5ff,0xff51c5ff,
+ 0xff41bfff,0xff62ccff,0xff62ccff,0xff42c0ff,0xff63ccff,0xff44c1ff,0xff53c7ff,0xff44c1ff,0xff65ceff,0xff66ceff,0xff46c3ff,0xff46c3ff,0xff66cfff,0xff47c3ff,
+ 0xff58c9ff,0xff48c5ff,0xff48c3ff,0xff67cfff,0xff47c3ff,0xff46c2ff,0xff66cfff,0xff45c2ff,0xff55c7ff,0xff75d4ff,0xff44c1ff,0xff43c1ff,0xff42c1ff,0xff42c0ff,
+ 0xff63ccff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff50c5ff,0xff60cbff,0xff50c3ff,0xff4fc3ff,0xff71d0ff,0xff5fc9ff,0xff3dbcff,0xff4dc1ff,0xff5dc8ff,0xff4cc1ff,
+ 0xff4bc1ff,0xff4bc1ff,0xff5cc7ff,0xff3ab9ff,0xff3ab9ff,0xff5bc6ff,0xff3ab9ff,0xff49bfff,0xff49bfff,0xff59c6ff,0xff37b7ff,0xff48bdff,0xff55bdf5,0xff358bbd,
+ 0xff206c98,0xff206b98,0xff1f6b98,0xff1f6b98,0xff3288ba,0xff51b8f3,0xff316d90,0xff1c6590,0xffedf2f5,0xffffffff,0xfff4f7f9,0xffcddde6,0xff6894ae,0xff3baaeb,
+ 0xff2fb0ff,0xff51bfff,0xff51bfff,0xff2eaeff,0xff3fb7ff,0xff50bdff,0xff3eb7ff,0xff3db5ff,0xff61c5ff,0xff4ebdff,0xff2bacff,0xff3bb4ff,0xff4dbcff,0xff3bb3ff,
+ 0xff3ab3ff,0xff3ab2ff,0xff4cbbff,0xff28aaff,0xff39b2ff,0xff27a9ff,0xff38b1ff,0xff26a9ff,0xff26a9ff,0xff26a9ff,0xff25a7ff,0xff24a7ff,0xff24a8ff,0xff24a7ff,
+ 0xff23a5ff,0xff23a5ff,0xff46b7ff,0xff22a4ff,0xff46b5ff,0xff46b5ff,0xff32acff,0xff20a3ff,0xff44b4ff,0xff44b4ff,0xff1fa2ff,0xff31abff,0xff31abff,0xff30aaff,
+ 0xff1ea1ff,0xff41b3ff,0xff41b3ff,0xff1ca0ff,0xff1ba0ff,0xff2ea8ff,0xff2ea8ff,0xff1ca0ff,0xff41b3ff,0xff2fa9ff,0xff42b3ff,0xff30aaff,0xff42b3ff,0xff31abff,
+ 0xff4fcaff,0xff73d5ff,0xff74d6ff,0xff74d6ff,0xff63d0ff,0xff52ccff,0xff53ccff,0xff76d7ff,0xff76d7ff,0xff76d7ff,0xff55cdff,0xff77d7ff,0xff56ceff,0xff56ceff,
+ 0xff78d8ff,0xff57cfff,0xff7ad9ff,0xff58cfff,0xff58cfff,0xff5ad0ff,0xff7bd9ff,0xff59d0ff,0xff58cfff,0xff58cfff,0xff79d8ff,0xff56ceff,0xff56cdff,0xff66d3ff,
+ 0xff55cdff,0xff54cdff,0xff53cdff,0xff53ccff,0xff76d6ff,0xff75d6ff,0xff62d0ff,0xff51cbff,0xff85daff,0xff50caff,0xff72d5ff,0xff4fcaff,0xff72d4ff,0xff4ec9ff,
+ 0xff4dc9ff,0xff71d4ff,0xff4cc8ff,0xff70d2ff,0xff70d3ff,0xff5dcdff,0xff4ac7ff,0xff6fd2ff,0xff49c6ff,0xff6ed1ff,0xff49c6ff,0xff6cd1ff,0xff5acbff,0xff47c5ff,
+ 0xff6bd0ff,0xff66c5f2,0xff276e90,0xff759eb0,0xffcedee6,0xfff6f9fa,0xfff6f9fa,0xffd0dfe6,0xff7ca2b5,0xff256d90,0xff457790,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xff236c90,0xff62c6f7,0xff64cbff,0xff3cbeff,0xff3cbeff,0xff63caff,0xff63caff,0xff3abdff,0xff4ec3ff,0xff3abcff,0xff61caff,0xff39bcff,
+ 0xff38bcff,0xff5fc9ff,0xff36bbff,0xff5fc8ff,0xff5ec8ff,0xff4ac0ff,0xff34baff,0xff5dc8ff,0xff5cc6ff,0xff33b9ff,0xff5cc6ff,0xff33b8ff,0xff32b7ff,0xff32b8ff,
+ 0xff31b7ff,0xff30b6ff,0xff30b7ff,0xff30b6ff,0xff2eb5ff,0xff2eb5ff,0xff58c4ff,0xff2db4ff,0xff6ccbff,0xff2cb3ff,0xff57c3ff,0xff56c2ff,0xff2ab3ff,0xff2bb3ff,
+ 0xff55c1ff,0xff54c1ff,0xff53c1ff,0xff54c1ff,0xff52c1ff,0xff27b1ff,0xff27b1ff,0xff52c0ff,0xff26afff,0xff51bfff,0xff25b0ff,0xff52c0ff,0xff27b0ff,0xff3db9ff,
+ 0xff52c1ff,0xff3eb9ff,0xff29b2ff,0xff54c1ff,0xff3fbdff,0xff60cbff,0xff60cbff,0xff61cbff,0xff50c6ff,0xff62ccff,0xff62ccff,0xff63ccff,0xff74d2ff,0xff63cdff,
+ 0xff44c1ff,0xff64cdff,0xff65cdff,0xff65ceff,0xff55c8ff,0xff47c3ff,0xff66cfff,0xff48c3ff,0xff47c3ff,0xff58c9ff,0xff58cbff,0xff48c3ff,0xff47c3ff,0xff47c3ff,
+ 0xff66cfff,0xff45c2ff,0xff45c1ff,0xff54c7ff,0xff44c1ff,0xff43c1ff,0xff43c0ff,0xff42c0ff,0xff63ccff,0xff42bfff,0xff41bfff,0xff41bfff,0xff60cbff,0xff40bdff,
+ 0xff60cbff,0xff3fbdff,0xff5fc9ff,0xff3ebcff,0xff3ebcff,0xff6fcfff,0xff5dc8ff,0xff5dc8ff,0xff5cc7ff,0xff3bbaff,0xff3ab9ff,0xff3abaff,0xff3ab9ff,0xff5bc6ff,
+ 0xff3ab8ff,0xff5bc6ff,0xff38b8ff,0xff38b8ff,0xff59c5ff,0xff3e89b1,0xff779fb5,0xffffffff,0xffffffff,0xffeaf1f5,0xffe8eff4,0xffffffff,0xffffffff,0xff729fba,
+ 0xff306d90,0xffcadbe5,0xffffffff,0xffffffff,0xfff1f5f7,0xffcfdde5,0xff1b6490,0xff30b1ff,0xff52c0ff,0xff52bfff,0xff51bdff,0xff40b8ff,0xff51bdff,0xff2daeff,
+ 0xff2daeff,0xff2dadff,0xff4fbdff,0xff2badff,0xff2badff,0xff4dbcff,0xff2aacff,0xff4cbbff,0xff4cbbff,0xff28abff,0xff28aaff,0xff28aaff,0xff4abaff,0xff28a9ff,
+ 0xff5dc1ff,0xff27a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff23a7ff,0xff47b8ff,0xff22a5ff,0xff22a5ff,0xff46b7ff,0xff22a4ff,
+ 0xff45b4ff,0xff45b5ff,0xff20a3ff,0xff20a3ff,0xff43b4ff,0xff43b3ff,0xff43b3ff,0xff42b3ff,0xff41b3ff,0xff41b3ff,0xff41b3ff,0xff2ea9ff,0xff1ba0ff,0xff41b2ff,
+ 0xff1ca0ff,0xff41b2ff,0xff1da0ff,0xff1da0ff,0xff42b3ff,0xff42b3ff,0xff43b3ff,0xff57bcff,0xff50caff,0xff73d5ff,0xff62d0ff,0xff74d6ff,0xff62d1ff,0xff75d6ff,
+ 0xff75d6ff,0xff76d6ff,0xff76d7ff,0xff54cdff,0xff77d7ff,0xff67d2ff,0xff78d8ff,0xff78d8ff,0xff68d3ff,0xff57cfff,0xff7ad9ff,0xff58d0ff,0xff6ad4ff,0xff8bdeff,
+ 0xff7bd9ff,0xff69d4ff,0xff58cfff,0xff57ceff,0xff79d8ff,0xff56ceff,0xff66d3ff,0xff88dcff,0xff55ceff,0xff54cdff,0xff54ccff,0xff53ccff,0xff76d6ff,0xff75d6ff,
+ 0xff74d6ff,0xff62d0ff,0xff73d6ff,0xff50caff,0xff72d4ff,0xff4fc9ff,0xff60cfff,0xff72d4ff,0xff5fceff,0xff71d3ff,0xff70d3ff,0xff70d3ff,0xff70d3ff,0xff4bc7ff,
+ 0xff4ac7ff,0xff4ac7ff,0xff5cccff,0xff80d7ff,0xff6dd1ff,0xff6dd1ff,0xff47c5ff,0xff47c4ff,0xff6bd0ff,0xff3e7994,0xffdfe8ed,0xffffffff,0xffedf3f5,0xff317596,
+ 0xff307495,0xffedf3f5,0xffffffff,0xffe2eaee,0xff477a94,0xff256d90,0xffffffff,0xffffffff,0xffc7d9e1,0xff3e7e9d,0xff2e8ebd,0xff3dbfff,0xff50c5ff,0xff64cbff,
+ 0xff63cbff,0xff50c4ff,0xff63caff,0xff62caff,0xff62caff,0xff39bcff,0xff4dc3ff,0xff60c9ff,0xff4cc3ff,0xff5fc9ff,0xff5fc8ff,0xff5ec8ff,0xff5ec8ff,0xff36b9ff,
+ 0xff35b9ff,0xff35baff,0xff48bfff,0xff5cc6ff,0xff5bc6ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff30b7ff,0xff2fb6ff,0xff2fb6ff,0xff58c4ff,
+ 0xff2db4ff,0xff2db4ff,0xff57c4ff,0xff2cb4ff,0xff56c3ff,0xff40bcff,0xff56c2ff,0xff56c1ff,0xff3fbaff,0xff54c1ff,0xff3fbaff,0xff53c1ff,0xff3eb9ff,0xff52c1ff,
+ 0xff52c0ff,0xff3cb9ff,0xff51c0ff,0xff25b0ff,0xff25b0ff,0xff3cb8ff,0xff52c1ff,0xff52c1ff,0xff52c1ff,0xff53c1ff,0xff54c1ff,0xff69c9ff,0xff3fbdff,0xff40bdff,
+ 0xff41bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff43c0ff,0xff43c1ff,0xff43c1ff,0xff43c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff46c3ff,
+ 0xff77d4ff,0xff67cfff,0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff47c3ff,0xff57c9ff,0xff66cfff,0xff66cfff,0xff45c2ff,0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff43c0ff,
+ 0xff42c0ff,0xff42c1ff,0xff42c0ff,0xff42c0ff,0xff41bfff,0xff41bfff,0xff40bfff,0xff40bfff,0xff3fbdff,0xff3fbcff,0xff3fbcff,0xff3ebcff,0xff3ebbff,0xff3dbbff,
+ 0xff3cbbff,0xff3cbbff,0xff3bbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff3ab8ff,0xff39b8ff,0xff38b8ff,0xff37b8ff,0xff38b7ff,0xff347194,
+ 0xfffafbfc,0xffffffff,0xffcadbe5,0xff2172a1,0xff2172a1,0xffc8d9e3,0xffffffff,0xfffafbfc,0xff1e6894,0xff1d6590,0xffffffff,0xffffffff,0xffc3d6e1,0xff2587c2,
+ 0xff30b1ff,0xff30b0ff,0xff2fb1ff,0xff2fb0ff,0xff2eaeff,0xff2eb0ff,0xff2eaeff,0xff2daeff,0xff2daeff,0xff2cadff,0xff2cadff,0xff2cadff,0xff2badff,0xff2bacff,
+ 0xff2aacff,0xff2aacff,0xff29abff,0xff28aaff,0xff28abff,0xff28aaff,0xff4abaff,0xff4bb9ff,0xff4ab9ff,0xff27a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,
+ 0xff24a7ff,0xff24a7ff,0xff48b8ff,0xff23a5ff,0xff23a4ff,0xff23a4ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff21a3ff,0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff20a2ff,
+ 0xff1ea1ff,0xff1ea1ff,0xff1ea1ff,0xff1da0ff,0xff1ca0ff,0xff1ca0ff,0xff41b2ff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1ca1ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,
+ 0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff51cbff,0xff51caff,0xff51cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff54cdff,0xff54ccff,0xff55cdff,0xff55cdff,
+ 0xff56ceff,0xff56ceff,0xff57ceff,0xff57cfff,0xff58cfff,0xff58cfff,0xff59d0ff,0xff59d0ff,0xff59cfff,0xff58cfff,0xff58cfff,0xff57cfff,0xff57ceff,0xff56ceff,
+ 0xff56ceff,0xff55cdff,0xff55cdff,0xff54cdff,0xff54ccff,0xff53ccff,0xff52cbff,0xff52cbff,0xff51cbff,0xff51caff,0xff50cbff,0xff50caff,0xff50caff,0xff4fcaff,
+ 0xff4ecaff,0xff4ec9ff,0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,0xff4bc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,0xff49c6ff,0xff48c6ff,0xff48c5ff,0xff48c5ff,
+ 0xff48c5ff,0xff47c5ff,0xff46c4ff,0xff287294,0xffdee8ee,0xffffffff,0xffedf3f5,0xff307495,0xff2e7394,0xffeaf1f5,0xffffffff,0xffdde8ee,0xff267094,0xff246d90,
+ 0xffffffff,0xffffffff,0xffc5d8e1,0xff2f91c2,0xff3fbfff,0xff3dbeff,0xff3dbfff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff39bcff,
+ 0xff39bcff,0xff38bcff,0xff38bbff,0xff38bbff,0xff37baff,0xff36baff,0xff36baff,0xff36b9ff,0xff35b9ff,0xff34b9ff,0xff34b8ff,0xff34b8ff,0xff33b8ff,0xff33b7ff,
+ 0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff30b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2fb5ff,0xff2db5ff,0xff2eb4ff,0xff2cb5ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,
+ 0xff2ab3ff,0xff2ab3ff,0xff2ab2ff,0xff29b2ff,0xff28b1ff,0xff28b2ff,0xff28b1ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff26afff,0xff25afff,0xff25b0ff,0xff26b1ff,
+ 0xff26b0ff,0xff27b1ff,0xff28b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff61cbff,0xff61ccff,0xff41bfff,0xff42bfff,0xff42c0ff,0xff63ccff,
+ 0xff53c6ff,0xff44c1ff,0xff44c1ff,0xff45c1ff,0xff45c2ff,0xff46c2ff,0xff45c2ff,0xff46c3ff,0xff47c3ff,0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff47c5ff,0xff47c3ff,
+ 0xff47c3ff,0xff46c3ff,0xff65cfff,0xff45c2ff,0xff44c2ff,0xff44c1ff,0xff54c7ff,0xff44c1ff,0xff43c1ff,0xff42c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,
+ 0xff41bdff,0xff50c3ff,0xff3fbdff,0xff3fbdff,0xff3ebcff,0xff3ebcff,0xff4dc1ff,0xff3dbbff,0xff3dbbff,0xff5dc8ff,0xff3cbaff,0xff3bbaff,0xff3abaff,0xff4ac1ff,
+ 0xff3ab9ff,0xff3ab8ff,0xff39b8ff,0xff39b8ff,0xff49bfff,0xff38b7ff,0xff37b7ff,0xff267eaf,0xff6c9cb6,0xffffffff,0xffffffff,0xffe9f0f4,0xffe8eff4,0xffffffff,
+ 0xffffffff,0xff6c9bb7,0xff237baf,0xff1d6590,0xffffffff,0xffffffff,0xffc8d8e1,0xff2587c2,0xff30b1ff,0xff2fb1ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,
+ 0xff2eaeff,0xff2eaeff,0xff2dadff,0xff2cadff,0xff3db5ff,0xff2badff,0xff2bacff,0xff3bb4ff,0xff4dbbff,0xff3ab3ff,0xff28abff,0xff28aaff,0xff28abff,0xff4bbaff,
+ 0xff28a9ff,0xff27a9ff,0xff26a9ff,0xff27a9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff48b8ff,0xff24a7ff,0xff23a7ff,0xff23a5ff,0xff23a5ff,
+ 0xff22a4ff,0xff21a3ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff1fa2ff,0xff30abff,0xff1ea1ff,0xff1ea2ff,0xff1da1ff,0xff1da0ff,0xff41b2ff,
+ 0xff1ba0ff,0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1da1ff,0xff1da2ff,0xff1fa2ff,0xff1fa1ff,0xff1fa3ff,0xff50caff,0xff50caff,0xff73d5ff,0xff74d6ff,
+ 0xff52cbff,0xff53cbff,0xff75d6ff,0xff53ccff,0xff76d7ff,0xff54ccff,0xff54cdff,0xff55cdff,0xff56ceff,0xff56ceff,0xff56ceff,0xff57cfff,0xff57cfff,0xff58cfff,
+ 0xff58d0ff,0xff59d0ff,0xff59d0ff,0xff58cfff,0xff58cfff,0xff57cfff,0xff79d8ff,0xff56cfff,0xff56ceff,0xff55ceff,0xff77d7ff,0xff54cdff,0xff54ccff,0xff53ccff,
+ 0xff53ccff,0xff53cbff,0xff51ccff,0xff51cbff,0xff51caff,0xff62cfff,0xff4fcaff,0xff4fc9ff,0xff4ec9ff,0xff4ec9ff,0xff71d4ff,0xff4dc8ff,0xff4cc8ff,0xff70d3ff,
+ 0xff4bc7ff,0xff4bc7ff,0xff4ac7ff,0xff6ed1ff,0xff49c6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,0xff6cd1ff,0xff47c4ff,0xff46c4ff,0xff42baf2,0xff276f90,0xff6a9bb2,
+ 0xffcfdfe7,0xfff7fafb,0xfff7fafb,0xffd0dfe6,0xff6b9cb4,0xff256e90,0xff3eb6f1,0xff246d90,0xffffffff,0xffffffff,0xffc5d8e1,0xff2f92c2,0xff3ebfff,0xff3dbfff,
+ 0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3bbdff,0xff3bbeff,0xff3abdff,0xff3abdff,0xff3abcff,0xff61caff,0xff39bcff,0xff38bbff,0xff5fc9ff,0xff37bbff,0xff5ec9ff,
+ 0xff36baff,0xff36b9ff,0xff5ec7ff,0xff34b9ff,0xff33b9ff,0xff34b8ff,0xff33b8ff,0xff33b7ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b7ff,0xff2fb7ff,0xff5ac5ff,
+ 0xff2fb6ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2cb4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,0xff29b2ff,0xff53c1ff,0xff28b2ff,
+ 0xff27b1ff,0xff27b1ff,0xff52c0ff,0xff26b0ff,0xff25b0ff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff29b1ff,0xff29b3ff,
+ 0xff40bdff,0xff40bdff,0xff40bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff63ccff,0xff42c0ff,0xff74d2ff,0xff64ccff,0xff63ceff,0xff54c8ff,0xff65ceff,0xff65ceff,
+ 0xff56c8ff,0xff66cfff,0xff67cfff,0xff67cfff,0xff58cbff,0xff68cfff,0xff68cfff,0xff57cbff,0xff46c3ff,0xff66cfff,0xff46c3ff,0xff55c8ff,0xff65ceff,0xff65cdff,
+ 0xff64cdff,0xff63cdff,0xff63ccff,0xff63cdff,0xff41c0ff,0xff62ccff,0xff41bfff,0xff61ccff,0xff41bfff,0xff71d0ff,0xff40bdff,0xff4fc2ff,0xff5fcbff,0xff5fc8ff,
+ 0xff5ec9ff,0xff3dbbff,0xff5ec8ff,0xff3cbbff,0xff4cc1ff,0xff5cc7ff,0xff5cc7ff,0xff5cc7ff,0xff5bc6ff,0xff5bc6ff,0xff5bc6ff,0xff49bfff,0xff6bccff,0xff5ac5ff,
+ 0xff37b7ff,0xff59c5ff,0xff56bdf5,0xff4190bc,0xff347397,0xff347397,0xff347397,0xff296f97,0xff3f8eba,0xff31abf4,0xff55c1ff,0xff1c6590,0xff1c6590,0xff2f6d90,
+ 0xff1c6590,0xff4d97c2,0xff53c0ff,0xff53c0ff,0xff52bfff,0xff51bfff,0xff51bfff,0xff40b7ff,0xff51bdff,0xff50bdff,0xff50bdff,0xff3db5ff,0xff61c5ff,0xff4ebdff,
+ 0xff2bacff,0xff4ebcff,0xff2aacff,0xff2aabff,0xff29abff,0xff28abff,0xff4cbbff,0xff28aaff,0xff27aaff,0xff28a9ff,0xff27a9ff,0xff26a9ff,0xff26a9ff,0xff26a8ff,
+ 0xff25a8ff,0xff25a7ff,0xff49b8ff,0xff24a7ff,0xff47b7ff,0xff47b7ff,0xff47b7ff,0xff33adff,0xff5abfff,0xff46b5ff,0xff45b5ff,0xff32acff,0xff45b4ff,0xff44b4ff,
+ 0xff31abff,0xff43b3ff,0xff56bbff,0xff30aaff,0xff1da1ff,0xff1da0ff,0xff41b2ff,0xff1ca0ff,0xff41b2ff,0xff41b2ff,0xff41b2ff,0xff2ea9ff,0xff41b2ff,0xff42b2ff,
+ 0xff2faaff,0xff42b3ff,0xff43b3ff,0xff43b3ff,0xff4fcaff,0xff50cbff,0xff50caff,0xff51cbff,0xff51cbff,0xff63d0ff,0xff64d0ff,0xff53ccff,0xff76d7ff,0xff54cdff,
+ 0xff76d7ff,0xff77d7ff,0xff55cdff,0xff56ceff,0xff79d8ff,0xff79d9ff,0xff79d9ff,0xff7ad9ff,0xff7bd9ff,0xff7bd9ff,0xff7bd9ff,0xff7ad9ff,0xff58cfff,0xff7ad9ff,
+ 0xff57ceff,0xff78d8ff,0xff56ceff,0xff55cdff,0xff76d7ff,0xff65d2ff,0xff76d6ff,0xff87dbff,0xff52cbff,0xff75d6ff,0xff62d1ff,0xff62cfff,0xff51caff,0xff73d5ff,
+ 0xff50caff,0xff72d5ff,0xff4ec9ff,0xff4ec9ff,0xff72d4ff,0xff4dc8ff,0xff71d3ff,0xff4cc8ff,0xff6fd2ff,0xff4bc7ff,0xff4bc6ff,0xff6fd1ff,0xff6fd2ff,0xff48c6ff,
+ 0xff6dd1ff,0xff48c5ff,0xff6cd1ff,0xff47c5ff,0xff46c4ff,0xff6bd0ff,0xff45c3ff,0xff6ad0ff,0xff6acfff,0xff44c2ff,0xff43c2ff,0xff69ceff,0xff68ceff,0xff42c2ff,
+ 0xff67cdff,0xff41c1ff,0xff53c6ff,0xff53c6ff,0xff3fbfff,0xff66cdff,0xff3ec0ff,0xff65ccff,0xff64ccff,0xff3dbeff,0xff3cbeff,0xff63cbff,0xff76d1ff,0xff63caff,
+ 0xff75d1ff,0xff3abdff,0xff61caff,0xff38bcff,0xff37bbff,0xff60c9ff,0xff37bbff,0xff37bbff,0xff36baff,0xff49c1ff,0xff49c0ff,0xff35b9ff,0xff34b9ff,0xff33b8ff,
+ 0xff33b8ff,0xff33b7ff,0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff30b7ff,0xff59c5ff,0xff2fb5ff,0xff59c5ff,0xff2fb5ff,0xff2db5ff,0xff57c4ff,0xff57c3ff,0xff2cb4ff,
+ 0xff56c3ff,0xff56c2ff,0xff55c2ff,0xff55c2ff,0xff55c1ff,0xff29b2ff,0xff54c1ff,0xff28b2ff,0xff27b1ff,0xff3db9ff,0xff3db8ff,0xff26b0ff,0xff51c0ff,0xff25b0ff,
+ 0xff26b0ff,0xff26b0ff,0xff52c0ff,0xff3db9ff,0xff28b1ff,0xff53c1ff,0xff28b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff40bfff,0xff41bfff,0xff41bfff,0xff62ccff,
+ 0xff42c0ff,0xff42c0ff,0xff63cdff,0xff43c1ff,0xff64cdff,0xff64cdff,0xff45c2ff,0xff45c2ff,0xff66ceff,0xff67cfff,0xff66cfff,0xff67cfff,0xff67cfff,0xff49c5ff,
+ 0xff48c5ff,0xff57cbff,0xff57c9ff,0xff57c8ff,0xff45c2ff,0xff65ceff,0xff44c2ff,0xff54c7ff,0xff63cdff,0xff63cdff,0xff43c0ff,0xff63cdff,0xff41c0ff,0xff51c6ff,
+ 0xff62ccff,0xff41bfff,0xff40bfff,0xff60cbff,0xff40bdff,0xff5fc9ff,0xff3fbcff,0xff4ec2ff,0xff5ec9ff,0xff4dc1ff,0xff4dc1ff,0xff3cbbff,0xff5dc8ff,0xff3bbaff,
+ 0xff4bc1ff,0xff5cc6ff,0xff5cc6ff,0xff3ab9ff,0xff5bc6ff,0xff39b8ff,0xff5ac6ff,0xff38b8ff,0xff48bdff,0xff59c5ff,0xff59c5ff,0xff35b5ff,0xff58c3ff,0xff35b4ff,
+ 0xff34b4ff,0xff57c2ff,0xff56c2ff,0xff33b4ff,0xff67c8ff,0xff33b3ff,0xff54c1ff,0xff31b2ff,0xff31b1ff,0xff66c8ff,0xff30b1ff,0xff53c0ff,0xff52c0ff,0xff2eb0ff,
+ 0xff2eb0ff,0xff51bfff,0xff51bfff,0xff2dadff,0xff3eb7ff,0xff2dadff,0xff4fbdff,0xff2cadff,0xff3cb4ff,0xff4dbcff,0xff2aacff,0xff4cbbff,0xff29abff,0xff4cbbff,
+ 0xff28abff,0xff28aaff,0xff28aaff,0xff38b1ff,0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff37b0ff,0xff25a8ff,0xff36b0ff,0xff35aeff,0xff24a7ff,0xff48b8ff,0xff34adff,
+ 0xff23a5ff,0xff47b5ff,0xff46b5ff,0xff21a4ff,0xff45b4ff,0xff46b4ff,0xff20a3ff,0xff20a2ff,0xff31acff,0xff1fa3ff,0xff43b3ff,0xff30aaff,0xff1ea1ff,0xff42b3ff,
+ 0xff1da0ff,0xff1ca0ff,0xff41b2ff,0xff1ba0ff,0xff2ea9ff,0xff2ea9ff,0xff1ca0ff,0xff2faaff,0xff30aaff,0xff42b3ff,0xff1ea2ff,0xff31abff,0xff50caff,0xff50caff,
+ 0xff51caff,0xff51cbff,0xff62d0ff,0xff64d0ff,0xff53cbff,0xff53ccff,0xff65d1ff,0xff54cdff,0xff66d2ff,0xff56ceff,0xff78d8ff,0xff78d8ff,0xff57ceff,0xff68d3ff,
+ 0xff58cfff,0xff69d4ff,0xff59d0ff,0xff7bd9ff,0xff7bd9ff,0xff58cfff,0xff7ad9ff,0xff57cfff,0xff57ceff,0xff56ceff,0xff78d8ff,0xff66d2ff,0xff66d2ff,0xff65d2ff,
+ 0xff76d6ff,0xff76d6ff,0xff52ccff,0xff52ccff,0xff62d0ff,0xff51caff,0xff62d0ff,0xff73d5ff,0xff73d5ff,0xff4fc9ff,0xff72d5ff,0xff60ceff,0xff5fceff,0xff71d3ff,
+ 0xff4cc8ff,0xff4cc8ff,0xff4bc7ff,0xff6fd2ff,0xff5dccff,0xff5bccff,0xff5bccff,0xff6ed1ff,0xff5bcbff,0xff48c5ff,0xff47c5ff,0xff6cd1ff,0xff46c4ff,0xff6bd0ff,
+ 0xff6acfff,0xff6acfff,0xff57c9ff,0xff43c3ff,0xff44c2ff,0xff56c8ff,0xff56c8ff,0xff68ceff,0xff54c7ff,0xff54c6ff,0xff53c7ff,0xff3fc0ff,0xff3fc0ff,0xff65cdff,
+ 0xff65ccff,0xff51c5ff,0xff50c5ff,0xff3dbeff,0xff3cbeff,0xff4fc5ff,0xff4fc4ff,0xff63caff,0xff4ec3ff,0xff39bcff,0xff39bcff,0xff60caff,0xff38bbff,0xff4bc2ff,
+ 0xff5fc9ff,0xff4bc1ff,0xff4ac1ff,0xff49c0ff,0xff35b9ff,0xff34b9ff,0xff34b8ff,0xff70cdff,0xff47bfff,0xff32b8ff,0xff47beff,0xff6fccff,0xff31b6ff,0xff5ac5ff,
+ 0xff2fb6ff,0xff2fb6ff,0xff59c4ff,0xff44bcff,0xff57c4ff,0xff2db4ff,0xff41bcff,0xff2cb4ff,0xff41bbff,0xff2bb4ff,0xff55c2ff,0xff56c2ff,0xff2ab2ff,0xff29b2ff,
+ 0xff3fbaff,0xff3eb9ff,0xff3eb9ff,0xff3db9ff,0xff26b0ff,0xff26b0ff,0xff3cb8ff,0xff51c0ff,0xff3bb7ff,0xff26b0ff,0xff52c0ff,0xff52c1ff,0xff28b1ff,0xff3eb9ff,
+ 0xff53c1ff,0xff3fbaff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff50c6ff,0xff41c0ff,0xff41c0ff,0xff42c0ff,0xff42c1ff,0xff44c0ff,0xff44c1ff,0xff44c1ff,
+ 0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff46c3ff,0xff46c3ff,0xff47c5ff,0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff47c3ff,0xff57c9ff,0xff46c2ff,0xff46c3ff,0xff45c2ff,
+ 0xff45c2ff,0xff44c1ff,0xff43c1ff,0xff43c1ff,0xff42c1ff,0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff40bdff,0xff3fbdff,0xff3fbdff,
+ 0xff3fbcff,0xff3ebcff,0xff3dbcff,0xff4abaf4,0xff3ab3f4,0xff39b2f4,0xff3cbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3abaff,0xff3ab9ff,0xff39b9ff,0xff39b9ff,
+ 0xff39b8ff,0xff38b7ff,0xff38b7ff,0xff47bdff,0xff58c3ff,0xff47bdff,0xff35b5ff,0xff35b4ff,0xff35b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff43baff,
+ 0xff32b2ff,0xff32b2ff,0xff32b2ff,0xff41b8ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2eaeff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2dadff,
+ 0xff2cadff,0xff2cadff,0xff2badff,0xff2bacff,0xff2aacff,0xff2aabff,0xff3ab3ff,0xff28aaff,0xff28aaff,0xff28aaff,0xff28a9ff,0xff27a9ff,0xff27a9ff,0xff27a9ff,
+ 0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff36aeff,0xff24a7ff,0xff24a7ff,0xff34adff,0xff24a5ff,0xff22a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff20a4ff,
+ 0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff1fa2ff,0xff1ea2ff,0xff1fa1ff,0xff2faaff,0xff1da0ff,0xff1ca1ff,0xff1ca1ff,0xff1ba0ff,0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,
+ 0xff1ca0ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1fa1ff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff50caff,0xff51cbff,0xff52cbff,0xff52ccff,0xff53ccff,0xff53ccff,
+ 0xff54ccff,0xff54cdff,0xff54cdff,0xff55cdff,0xff55cdff,0xff56ceff,0xff57ceff,0xff58cfff,0xff58cfff,0xff58d0ff,0xff4fb8e1,0xff3d8faf,0xff357b97,0xff337793,
+ 0xff327793,0xff327793,0xff3885a5,0xff46a8d0,0xff55cbfd,0xff55ceff,0xff54cdff,0xff54ccff,0xff53ccff,0xff53ccff,0xff52ccff,0xff52cbff,0xff52ccff,0xff51cbff,
+ 0xff4dc0f1,0xff3484a7,0xff2e7493,0xff2e7493,0xff2e7493,0xff307b9c,0xff307b9d,0xff3b83a3,0xff70a4bc,0xff3a97c2,0xff4bc7ff,0xff4bc7ff,0xff4ac6ff,0xff4ac7ff,
+ 0xff49c6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,0xff48c4ff,0xff46c5ff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,0xff44c2ff,0xff43c2ff,
+ 0xff42c2ff,0xff41c1ff,0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff3fc0ff,0xff3fc0ff,0xff52c5ff,0xff3ebfff,0xff3ebfff,0xff3dbeff,0xff50c5ff,0xff50c5ff,0xff3bbdff,
+ 0xff4fc4ff,0xff3bbdff,0xff3abdff,0xff39bcff,0xff4dc2ff,0xff4cc3ff,0xff38bbff,0xff38bbff,0xff37bbff,0xff36baff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff35b9ff,
+ 0xff33b9ff,0xff33b9ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff31b7ff,0xff30b7ff,0xff31b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,
+ 0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,0xff2ab2ff,0xff2ab3ff,0xff29b2ff,0xff28b2ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b0ff,0xff26b1ff,
+ 0xff25afff,0xff25afff,0xff25b0ff,0xff3cb8ff,0xff26b1ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff3eb9ff,0xff3fbaff,0xff3fbdff,0xff40bdff,0xff40bdff,0xff41bfff,
+ 0xff61ccff,0xff62ccff,0xff62ccff,0xff42c0ff,0xff74d3ff,0xff63cdff,0xff63cdff,0xff44c1ff,0xff65ceff,0xff65ceff,0xff45c3ff,0xff67cfff,0xff67cfff,0xff52a6cc,
+ 0xff427a94,0xff97b9c8,0xffdfe9ee,0xfff8fafb,0xfffbfcfc,0xffebf1f4,0xffb6cdd8,0xff4b849f,0xff4285a6,0xff64cdff,0xff54c7ff,0xff74d3ff,0xff63ccff,0xff63ccff,
+ 0xff41c0ff,0xff41bfff,0xff41bfff,0xff41bdff,0xff4883a1,0xff7da4b7,0xffe8eff3,0xfffcfdfd,0xfff2f6f8,0xff82aac0,0xff9cbac9,0xfff2f6f7,0xffc9d9e1,0xff4798c2,
+ 0xff5dc7ff,0xff5cc7ff,0xff5cc7ff,0xff4ac1ff,0xff6dcdff,0xff5bc6ff,0xff5bc6ff,0xff5bc6ff,0xff5ac6ff,0xff5ac5ff,0xff49bdff,0xff59c5ff,0xff58c5ff,0xff58c3ff,
+ 0xff58c3ff,0xff58c3ff,0xff57c2ff,0xff45bbff,0xff57c2ff,0xff67c8ff,0xff55c1ff,0xff42baff,0xff32b3ff,0xff31b2ff,0xff31b2ff,0xff54c1ff,0xff30b1ff,0xff2fb0ff,
+ 0xff2fb0ff,0xff52bfff,0xff51bfff,0xff2eb0ff,0xff51bdff,0xff2eadff,0xff2daeff,0xff2dadff,0xff4fbdff,0xff4fbdff,0xff2bacff,0xff2babff,0xff2aabff,0xff29abff,
+ 0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff5ec2ff,0xff4ab9ff,0xff38b1ff,0xff49b8ff,0xff49b8ff,0xff49b8ff,0xff36aeff,0xff37aeff,0xff49b8ff,0xff35aeff,
+ 0xff35aeff,0xff47b7ff,0xff47b7ff,0xff33adff,0xff46b5ff,0xff22a4ff,0xff46b5ff,0xff20a3ff,0xff44b4ff,0xff44b4ff,0xff1fa2ff,0xff43b3ff,0xff43b3ff,0xff42b3ff,
+ 0xff41b3ff,0xff41b3ff,0xff41b3ff,0xff2ea9ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,0xff2ea9ff,0xff2fa9ff,0xff1ea1ff,0xff1da1ff,0xff1fa1ff,0xff42b3ff,0xff43b3ff,
+ 0xff4fcaff,0xff50caff,0xff50cbff,0xff51cbff,0xff75d6ff,0xff52cbff,0xff52ccff,0xff76d6ff,0xff76d7ff,0xff55cdff,0xff77d7ff,0xff77d7ff,0xff56ceff,0xff57ceff,
+ 0xff79d8ff,0xff79d8ff,0xff57cfff,0xff3e7e97,0xffc3d4db,0xffffffff,0xffffffff,0xffdfe9ee,0xffe2eaee,0xffffffff,0xffffffff,0xffebf0f3,0xff4089a7,0xff52c6f5,
+ 0xff4b9cbd,0xff468098,0xff317a98,0xff317a98,0xff317a98,0xff3c94ba,0xff4ec1f3,0xff2e7290,0xff417990,0xffedf3f5,0xffffffff,0xfff6f8f9,0xffcfdfe6,0xff6698ae,
+ 0xffffffff,0xffffffff,0xffc7d9e1,0xff357490,0xff3f7790,0xff2a7090,0xff2a7090,0xff5198ba,0xff4786a4,0xff297090,0xff296f90,0xff3e7690,0xff2f83aa,0xff3592bd,
+ 0xff3c7590,0xff3c7590,0xff286e90,0xff4c95b8,0xff488cac,0xff277194,0xff277093,0xff3d7793,0xff276f93,0xff4283a3,0xff359dd0,0xff54c5fe,0xff3a7490,0xff3a7490,
+ 0xff2f6f90,0xff2e6f90,0xff2f7294,0xff246f94,0xff236f94,0xff398db7,0xff2f7396,0xff237096,0xff2e7396,0xff2e7396,0xff2985b4,0xff35afee,0xff4dc3ff,0xff4cc2ff,
+ 0xff38bcff,0xff37bbff,0xff37bbff,0xff37baff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff34b9ff,0xff5dc7ff,0xff33b8ff,0xff5cc6ff,0xff5bc6ff,0xff31b7ff,0xff32b7ff,
+ 0xff5ac5ff,0xff5ac5ff,0xff30b6ff,0xff5ac5ff,0xff59c4ff,0xff2eb5ff,0xff2eb5ff,0xff42bcff,0xff57c3ff,0xff57c3ff,0xff2cb4ff,0xff56c3ff,0xff2ab3ff,0xff2ab2ff,
+ 0xff55c1ff,0xff54c1ff,0xff29b2ff,0xff3eb9ff,0xff52c1ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff51c0ff,0xff51c0ff,0xff52c0ff,0xff26b0ff,0xff52c1ff,0xff27b1ff,
+ 0xff28b1ff,0xff28b2ff,0xff3fbaff,0xff3fbaff,0xff3fbdff,0xff50c3ff,0xff61ccff,0xff61ccff,0xff61ccff,0xff41c0ff,0xff42bfff,0xff63ccff,0xff74d3ff,0xff63cdff,
+ 0xff64cdff,0xff64cdff,0xff65ceff,0xff66ceff,0xff66ceff,0xff67cfff,0xff47c3ff,0xff2a7397,0xfff8fafb,0xffffffff,0xffdee9ee,0xff2a6f91,0xff437890,0xff97b6c4,
+ 0xffeef2f5,0xffedf2f5,0xff6da4bf,0xff387490,0xff6c9ab0,0xffd4e0e6,0xfff7f9fa,0xfff6f9fa,0xffd0dfe6,0xff6d9db5,0xff256c90,0xff256b90,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffd6e2e9,0xffffffff,0xffd3e0e6,0xff2b6f93,0xff3f7591,0xffecf1f5,
+ 0xffffffff,0xffe5ecf0,0xff337090,0xff347293,0xffcedde6,0xffffffff,0xffd2e0e9,0xff387293,0xffa2bdcc,0xffe2ebef,0xfffafbfc,0xfffcfcfd,0xffeaf1f5,0xffb6cbd8,
+ 0xff32739a,0xff288cc7,0xff1c6590,0xffffffff,0xffffffff,0xffccdce6,0xffccdbe3,0xfffafbfc,0xff96b7cc,0xff6a9ab7,0xffd2e0e9,0xfff8fafb,0xfff8fafb,0xffd9e4ea,
+ 0xff74a0bc,0xff196290,0xff29a0ec,0xff2badff,0xff2bacff,0xff2aacff,0xff2aabff,0xff2aabff,0xff29abff,0xff4cbaff,0xff4bbbff,0xff39b2ff,0xff4bbaff,0xff27a9ff,
+ 0xff4ab9ff,0xff49b9ff,0xff49b9ff,0xff49b8ff,0xff37aeff,0xff5bc0ff,0xff49b8ff,0xff5bc0ff,0xff47b7ff,0xff23a5ff,0xff23a5ff,0xff22a4ff,0xff5abfff,0xff33adff,
+ 0xff21a4ff,0xff45b5ff,0xff45b4ff,0xff44b4ff,0xff44b3ff,0xff43b3ff,0xff30abff,0xff42b3ff,0xff41b3ff,0xff41b3ff,0xff2fa9ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,
+ 0xff1ba0ff,0xff1ca0ff,0xff41b2ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1fa1ff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff51cbff,0xff51caff,0xff74d6ff,0xff52ccff,
+ 0xff53ccff,0xff76d6ff,0xff76d7ff,0xff54ccff,0xff55cdff,0xff77d7ff,0xff56ceff,0xff56ceff,0xff78d8ff,0xff79d8ff,0xff58cfff,0xff3e7e97,0xffc6d7dd,0xffffffff,
+ 0xffffffff,0xfff1f5f7,0xffd2dee3,0xffaac6d1,0xff85a8b6,0xff4b7f94,0xff3684a3,0xff76a2b5,0xffffffff,0xffffffff,0xffebf2f5,0xffeaf1f4,0xffffffff,0xffffffff,
+ 0xff7da7ba,0xff2e7390,0xffd3dfe5,0xffffffff,0xffffffff,0xfff3f6f7,0xffcedee5,0xffcedee5,0xffffffff,0xffffffff,0xfff2f6f7,0xffd2dfe5,0xff90b0bf,0xffffffff,
+ 0xfffcfdfd,0xff367997,0xff6d97ab,0xffffffff,0xffffffff,0xffffffff,0xff578ea8,0xff327595,0xfffbfcfc,0xffffffff,0xff82abbf,0xffa4becb,0xffffffff,0xffffffff,
+ 0xffe8eff2,0xffd4e2e9,0xfffeffff,0xffffffff,0xffbfd4de,0xff317494,0xff3a7490,0xffffffff,0xffffffff,0xffffffff,0xfff0f4f6,0xffdce8ee,0xff9bbccc,0xffffffff,
+ 0xfffeffff,0xffd6e4ea,0xffd6e3ea,0xfffeffff,0xffffffff,0xff7ca7be,0xff2882b1,0xff38bcff,0xff38bcff,0xff38bbff,0xff37bbff,0xff36baff,0xff36baff,0xff35baff,
+ 0xff35b9ff,0xff35b9ff,0xff5dc7ff,0xff34b9ff,0xff5cc6ff,0xff5cc6ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff5ac5ff,0xff30b6ff,0xff59c5ff,0xff59c5ff,0xff2fb5ff,
+ 0xff2eb5ff,0xff42bcff,0xff57c3ff,0xff42bcff,0xff40bcff,0xff56c2ff,0xff2bb3ff,0xff2ab3ff,0xff55c1ff,0xff54c1ff,0xff29b1ff,0xff53c1ff,0xff53c1ff,0xff27b0ff,
+ 0xff27b1ff,0xff26b1ff,0xff51c0ff,0xff51c0ff,0xff52c0ff,0xff26b0ff,0xff27b1ff,0xff52c0ff,0xff27b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff40bdff,
+ 0xff40bfff,0xff41bfff,0xff62ccff,0xff62ccff,0xff63ccff,0xff42c0ff,0xff63ccff,0xff44c1ff,0xff44c1ff,0xff64ceff,0xff45c2ff,0xff45c2ff,0xff66ceff,0xff66cfff,
+ 0xff65cdfd,0xff51a3c9,0xff427a94,0xff93b6c6,0xffdee9ee,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffe7eef2,0xff5588a0,0xffdfe8ed,0xffffffff,0xffeff3f5,
+ 0xff427b96,0xff417995,0xffedf3f5,0xffffffff,0xffdfe9ee,0xff266f94,0xff407590,0xffffffff,0xffffffff,0xffc7d8e1,0xff3a7c9d,0xff367290,0xffffffff,0xffffffff,
+ 0xffc9d9e1,0xff447f9d,0xff427a98,0xfff8fafb,0xffffffff,0xff739cb2,0xffabc2cf,0xffffffff,0xfffbfcfc,0xffffffff,0xff9ebdcf,0xff6093b0,0xffffffff,0xfff9fafb,
+ 0xff407898,0xff5989a5,0xff769eb5,0xff77a3bc,0xff36769c,0xff6d98b1,0xffe5edf2,0xffffffff,0xfffafbfc,0xff1d6590,0xff1c6590,0xffffffff,0xffffffff,0xfff9fafb,
+ 0xff34759c,0xff306f93,0xffdde8ee,0xffffffff,0xfff2f6f8,0xffcadbe5,0xffcadae5,0xfff2f6f8,0xffffffff,0xffdae5ed,0xff1a6595,0xff2cacff,0xff2badff,0xff2aacff,
+ 0xff29acff,0xff29abff,0xff29abff,0xff29abff,0xff28aaff,0xff28aaff,0xff5ec1ff,0xff4ab9ff,0xff38b1ff,0xff49b8ff,0xff26a8ff,0xff25a8ff,0xff24a8ff,0xff49b8ff,
+ 0xff24a7ff,0xff48b8ff,0xff35adff,0xff47b7ff,0xff47b7ff,0xff33adff,0xff46b5ff,0xff21a4ff,0xff45b5ff,0xff45b4ff,0xff20a3ff,0xff20a3ff,0xff43b4ff,0xff43b3ff,
+ 0xff43b3ff,0xff56bbff,0xff41b3ff,0xff41b3ff,0xff41b2ff,0xff2ea9ff,0xff1ca0ff,0xff1b9fff,0xff1ca0ff,0xff1ca1ff,0xff1da0ff,0xff41b3ff,0xff1ea1ff,0xff1ea2ff,
+ 0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff51caff,0xff51cbff,0xff52cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff54ccff,0xff54cdff,0xff55cdff,0xff55ceff,
+ 0xff56ceff,0xff56ceff,0xff56ceff,0xff57cfff,0xff56cdfc,0xff4a859d,0xff7ca6b7,0xff7ca6b7,0xff578ea4,0xff407e98,0xff6598ac,0xffabc7d2,0xffffffff,0xffffffff,
+ 0xffb1cbd5,0xfffafbfc,0xffffffff,0xffcedee5,0xff3581a1,0xff3481a1,0xffcedde3,0xffffffff,0xfffafcfc,0xff397994,0xff2e7390,0xffffffff,0xffffffff,0xffc7d9e1,
+ 0xff3c9ac2,0xff2c7290,0xffffffff,0xffffffff,0xffc7d9e1,0xff3a97c1,0xff2c7696,0xffb8cfda,0xffffffff,0xffa5c2d0,0xffe7eff3,0xffffffff,0xff97b9c8,0xffffffff,
+ 0xffe9f0f4,0xff9fbfce,0xffffffff,0xffb8cfda,0xff287395,0xff548da8,0xffc2d6e0,0xfff0f5f7,0xfffbfcfc,0xffd3e2e9,0xffeaf1f5,0xffffffff,0xffffffff,0xff256c90,
+ 0xff246c90,0xffffffff,0xffffffff,0xffd4e2e9,0xff247095,0xff3a7593,0xfffbfcfc,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfff9fafb,
+ 0xff216e95,0xff39bbff,0xff38bbff,0xff38bbff,0xff37bbff,0xff36baff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,
+ 0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b7ff,0xff2fb6ff,0xff2fb6ff,0xff2fb6ff,0xff2eb5ff,0xff2eb5ff,0xff2db4ff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,
+ 0xff2bb3ff,0xff2ab2ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff28b1ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff25afff,0xff26b0ff,0xff26b0ff,
+ 0xff27b1ff,0xff27b1ff,0xff53c1ff,0xff29b1ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff40bfff,0xff41bdff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff42c0ff,0xff42c1ff,
+ 0xff43c0ff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff45c1ff,0xff45c2ff,0xff46c3ff,0xff46c3ff,0xff45c1fc,0xff4f89a4,0xffffffff,0xffffffff,0xffd8e5ea,0xff397a99,
+ 0xff297093,0xff4c86a3,0xffffffff,0xffffffff,0xffb8cfda,0xffdee8ee,0xffffffff,0xffedf3f5,0xff307395,0xff2d7294,0xffeaf1f5,0xffffffff,0xffdde8ee,0xff266f94,
+ 0xff256b90,0xffffffff,0xffffffff,0xffc5d7e1,0xff308fc2,0xff236a90,0xfffeffff,0xffffffff,0xffc7d9e3,0xff236d94,0xff2a85b6,0xff6194b0,0xffffffff,0xfff4f7f9,
+ 0xffffffff,0xffebf1f5,0xff256c93,0xffebf1f5,0xffffffff,0xfff4f7f9,0xffffffff,0xff6194b0,0xff2273a2,0xffe2ebf0,0xffffffff,0xffdfe9ee,0xff2c7098,0xff276e97,
+ 0xffe1ebf0,0xffffffff,0xffffffff,0xff1d6590,0xff1c6590,0xffffffff,0xffffffff,0xffc4d7e2,0xff227fb7,0xff1c6693,0xffe0e9ef,0xffffffff,0xffdce7ee,0xff1f6693,
+ 0xff1b6490,0xff578cae,0xff4b84a8,0xff34749d,0xff1a6595,0xff2cacff,0xff2badff,0xff2aacff,0xff2aabff,0xff2aacff,0xff28abff,0xff28abff,0xff28aaff,0xff28aaff,
+ 0xff28aaff,0xff27aaff,0xff27a9ff,0xff27a8ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff23a5ff,0xff22a5ff,
+ 0xff21a4ff,0xff22a4ff,0xff21a3ff,0xff21a3ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff20a2ff,0xff1fa1ff,0xff1ea2ff,0xff1da1ff,0xff1ea0ff,0xff1ca0ff,0xff1ca0ff,
+ 0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1da1ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff50cbff,0xff51cbff,0xff51caff,
+ 0xff51cbff,0xff52ccff,0xff53ccff,0xff53ccff,0xff54cdff,0xff54cdff,0xff55cdff,0xff55ceff,0xff78d8ff,0xff79d8ff,0xff56ceff,0xff57cfff,0xff57cdfc,0xff327590,
+ 0xffbed3dc,0xffffffff,0xffffffff,0xfff9fafb,0xffe7eff2,0xfffcfdfd,0xffffffff,0xfffafbfc,0xff6c99ab,0xff7ea6b6,0xffffffff,0xffffffff,0xffeaf1f4,0xffeaf1f4,
+ 0xffffffff,0xffffffff,0xff77a4b7,0xff388baf,0xff2d7290,0xffffffff,0xffffffff,0xffc7d9e1,0xff3b99c2,0xff2c7291,0xffecf2f5,0xffffffff,0xfffafbfc,0xffd7e4eb,
+ 0xff3181a5,0xff2c7191,0xffeaf1f4,0xffffffff,0xffffffff,0xffa7c4d1,0xff2e7ea2,0xffa5c3d0,0xffffffff,0xffffffff,0xffebf1f5,0xff2b7192,0xff2c7da2,0xffecf2f5,
+ 0xffffffff,0xfffeffff,0xffd5e3ea,0xffeef4f6,0xfffcfdfd,0xffffffff,0xffffffff,0xff286f92,0xff256d90,0xffffffff,0xffffffff,0xffc4d8e1,0xff2f91c2,0xff4488ab,
+ 0xff82a9bd,0xffffffff,0xffffffff,0xffe7eff3,0xffe0eaef,0xffffffff,0xffffffff,0xff83acc1,0xff34ace9,0xff38bcff,0xff38bbff,0xff38bbff,0xff37bbff,0xff36baff,
+ 0xff36baff,0xff35baff,0xff35b9ff,0xff5ec7ff,0xff34b8ff,0xff33b8ff,0xff47bfff,0xff32b7ff,0xff32b7ff,0xff32b7ff,0xff30b7ff,0xff30b7ff,0xff30b7ff,0xff2fb6ff,
+ 0xff2fb5ff,0xff2eb6ff,0xff43bcff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff41bcff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff54c2ff,0xff29b2ff,0xff28b1ff,0xff3ebaff,
+ 0xff28b1ff,0xff27b1ff,0xff26b1ff,0xff26b0ff,0xff25b0ff,0xff3bb7ff,0xff25afff,0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff28b1ff,0xff29b2ff,
+ 0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff42c0ff,0xff43c1ff,0xff43c1ff,0xff44c2ff,0xff45c1ff,0xff64cdff,0xff65ceff,
+ 0xff46c3ff,0xff47c3ff,0xff46c3ff,0xff399bcb,0xff307494,0xff9dbac7,0xffdbe7ec,0xfff7f9fa,0xfffcfdfd,0xffeef4f6,0xffbfd4de,0xff578ea9,0xff277194,0xff387490,
+ 0xff699ab2,0xffcfdfe7,0xfff7fafb,0xfff7fafb,0xffd0dfe6,0xff6b9bb4,0xff256c90,0xff3db5f1,0xff256c90,0xffffffff,0xffffffff,0xffc5d7e1,0xff3090c2,0xff2777a2,
+ 0xff7aa4bb,0xffeff4f6,0xfffbfcfd,0xffe8f0f4,0xff3180aa,0xff2679a5,0xff97b9cb,0xffffffff,0xffffffff,0xff5a8fad,0xff319dd9,0xff548baa,0xffffffff,0xffffffff,
+ 0xff99bacc,0xff2376a4,0xff2274a2,0xff5b8fae,0xffdbe6ed,0xfffbfcfc,0xffedf2f5,0xffa9c5d6,0xff96b4c6,0xffffffff,0xffffffff,0xff4581a4,0xff1d6590,0xffffffff,
+ 0xffffffff,0xffc2d6e1,0xff2587c2,0xff4db2ed,0xff2f6c90,0xff77a2bd,0xffdbe7ee,0xfffafbfc,0xfffafbfc,0xffd9e5ed,0xff79a3be,0xff196290,0xff289ee9,0xff2cadff,
+ 0xff2bacff,0xff2aacff,0xff2aacff,0xff29abff,0xff29abff,0xff29abff,0xff4cbaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff49b9ff,0xff27a9ff,0xff26a8ff,0xff26a8ff,
+ 0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff34adff,0xff23a4ff,0xff22a4ff,0xff22a4ff,0xff46b5ff,0xff20a4ff,0xff20a3ff,0xff44b3ff,
+ 0xff20a2ff,0xff1fa2ff,0xff1fa2ff,0xff42b3ff,0xff1ea1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,0xff41b1ff,0xff1ca0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,
+ 0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff73d5ff,0xff74d6ff,0xff74d6ff,0xff52cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff54ccff,0xff54ccff,
+ 0xff55cdff,0xff55ceff,0xff56ceff,0xff56ceff,0xff57ceff,0xff57cfff,0xff57cfff,0xff59cfff,0xff5dbee3,0xff619bb2,0xff498198,0xff327792,0xff4e7f92,0xff457c92,
+ 0xff4b88a0,0xff43a2c8,0xff54c9f9,0xff72d0f5,0xff3e97bc,0xff467f97,0xff327997,0xff467f97,0xff3b7c97,0xff559cba,0xff6fcdf4,0xff62d0ff,0xff2e7290,0xff4b7b90,
+ 0xff2d7290,0xff407890,0xff57a2c2,0xff6ac5ed,0xff3b809f,0xff2c7493,0xff2c7393,0xff2b7393,0xff3c85a5,0xff61b8df,0xff3f7790,0xff347390,0xff2a7090,0xff297090,
+ 0xff46c0f8,0xff3e7690,0xff3d7690,0xff3d7690,0xff327290,0xff5db4dd,0xff67c9f7,0xff4a90b1,0xff337493,0xff477a93,0xff3d7793,0xff2a7aa1,0xff457890,0xff3a7490,
+ 0xff3b7490,0xff2f7090,0xff3a7490,0xff3a7490,0xff2e6f90,0xff236c90,0xff4d9bc2,0xff3dbeff,0xff5dbded,0xff458cb0,0xff397694,0xff2e7294,0xff397594,0xff397594,
+ 0xff448db2,0xff35aeec,0xff74d0ff,0xff61c9ff,0xff4cc2ff,0xff5fc9ff,0xff5fc9ff,0xff5fc8ff,0xff36baff,0xff35baff,0xff5ec8ff,0xff34b9ff,0xff5dc7ff,0xff5dc6ff,
+ 0xff6fcdff,0xff47bfff,0xff5bc5ff,0xff5ac5ff,0xff46bdff,0xff5ac5ff,0xff30b6ff,0xff59c5ff,0xff2eb6ff,0xff43bcff,0xff58c4ff,0xff2db4ff,0xff57c4ff,0xff57c3ff,
+ 0xff6bcaff,0xff2bb3ff,0xff2ab3ff,0xff55c1ff,0xff29b3ff,0xff54c1ff,0xff54c1ff,0xff68c9ff,0xff3eb9ff,0xff52c1ff,0xff52c1ff,0xff3cb9ff,0xff51c0ff,0xff67c7ff,
+ 0xff3bb8ff,0xff3cb8ff,0xff52c1ff,0xff53c1ff,0xff3eb9ff,0xff68c9ff,0xff54c1ff,0xff54c1ff,0xff3fbdff,0xff61cbff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,
+ 0xff42c0ff,0xff42c0ff,0xff43c1ff,0xff43c1ff,0xff44c1ff,0xff44c2ff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff56c9ff,0xff67cfff,0xff67cfff,0xff48c3ff,0xff68cfff,
+ 0xff47c5ff,0xff47c3ff,0xff66cfff,0xff46c3ff,0xff66ceff,0xff45c2ff,0xff44c2ff,0xff64cdff,0xff44c1ff,0xff63cdff,0xff42c1ff,0xff63ccff,0xff62ccff,0xff41bfff,
+ 0xff62ccff,0xff41bfff,0xff40bfff,0xff60ccff,0xff3fbdff,0xff5fcbff,0xff3ebcff,0xff3ebcff,0xff5fc9ff,0xff4dc1ff,0xff5ec8ff,0xff5dc8ff,0xff5dc8ff,0xff3bbaff,
+ 0xff3bbaff,0xff3ab9ff,0xff49c0ff,0xff5bc6ff,0xff5bc6ff,0xff5bc6ff,0xff39b8ff,0xff38b7ff,0xff5ac6ff,0xff47bdff,0xff58c3ff,0xff6acbff,0xff35b5ff,0xff58c3ff,
+ 0xff34b5ff,0xff34b4ff,0xff56c2ff,0xff33b3ff,0xff55c1ff,0xff43b9ff,0xff54c1ff,0xff54c1ff,0xff41b9ff,0xff31b1ff,0xff53c0ff,0xff30b1ff,0xff52bfff,0xff2eb0ff,
+ 0xff2eb0ff,0xff51bdff,0xff51bdff,0xff2daeff,0xff50bdff,0xff2cadff,0xff4fbdff,0xff4fbcff,0xff4dbcff,0xff60c3ff,0xff4cbbff,0xff5fc3ff,0xff29abff,0xff3ab2ff,
+ 0xff3ab2ff,0xff28aaff,0xff4bbaff,0xff28aaff,0xff4ab9ff,0xff26a9ff,0xff49b8ff,0xff49b8ff,0xff49b8ff,0xff36aeff,0xff35aeff,0xff48b8ff,0xff24a5ff,0xff23a5ff,
+ 0xff46b7ff,0xff22a5ff,0xff46b5ff,0xff21a4ff,0xff46b5ff,0xff21a3ff,0xff32acff,0xff31acff,0xff20a3ff,0xff43b3ff,0xff1ea2ff,0xff42b3ff,0xff41b3ff,0xff1da1ff,
+ 0xff1ca0ff,0xff41b2ff,0xff1ba0ff,0xff41b1ff,0xff1ca0ff,0xff41b2ff,0xff1da0ff,0xff41b2ff,0xff1ea1ff,0xff42b3ff,0xff1ea2ff,0xff43b3ff,0xff50caff,0xff73d6ff,
+ 0xff51caff,0xff62d0ff,0xff52cbff,0xff52ccff,0xff53ccff,0xff53ccff,0xff53cdff,0xff55cdff,0xff54ceff,0xff56cdff,0xff56cdff,0xff57ceff,0xff56ceff,0xff58cfff,
+ 0xff57cfff,0xff58d0ff,0xff59d0ff,0xff7bd9ff,0xff59cfff,0xff58cfff,0xff89ddff,0xff57cfff,0xff78d9ff,0xff56ceff,0xff55ceff,0xff77d8ff,0xff55cdff,0xff77d7ff,
+ 0xff54cdff,0xff87dbff,0xff52ccff,0xff86daff,0xff63d0ff,0xff51cbff,0xff50caff,0xff73d6ff,0xff50caff,0xff72d4ff,0xff4fc9ff,0xff4ec9ff,0xff72d3ff,0xff4dc9ff,
+ 0xff4dc8ff,0xff4cc7ff,0xff70d3ff,0xff4bc7ff,0xff4ac6ff,0xff5bccff,0xff4ac6ff,0xff49c5ff,0xff48c5ff,0xff6dd1ff,0xff5acbff,0xff47c4ff,0xff6cd0ff,0xff6bd0ff,
+ 0xff45c4ff,0xff6acfff,0xff45c3ff,0xff6aceff,0xff43c2ff,0xff56c8ff,0xff68ceff,0xff42c2ff,0xff67cdff,0xff40c1ff,0xff40c1ff,0xff40c0ff,0xff3fc0ff,0xff52c5ff,
+ 0xff51c5ff,0xff3dbfff,0xff64cbff,0xff3cbeff,0xff3cbeff,0xff63caff,0xff63caff,0xff3abdff,0xff62caff,0xff39bdff,0xff61caff,0xff60c9ff,0xff60c9ff,0xff60c9ff,
+ 0xff37bbff,0xff4ac1ff,0xff36baff,0xff5ec8ff,0xff35baff,0xff35b9ff,0xff5dc7ff,0xff34b9ff,0xff70cdff,0xff5cc6ff,0xff32b7ff,0xff31b7ff,0xff5ac5ff,0xff30b6ff,
+ 0xff5ac5ff,0xff44bdff,0xff2fb6ff,0xff2eb5ff,0xff57c4ff,0xff2db4ff,0xff57c3ff,0xff2cb4ff,0xff6bcbff,0xff2bb4ff,0xff56c2ff,0xff2ab3ff,0xff29b2ff,0xff54c1ff,
+ 0xff29b2ff,0xff68c8ff,0xff52c1ff,0xff27b1ff,0xff26b0ff,0xff52c0ff,0xff25b0ff,0xff51bfff,0xff3cb8ff,0xff26b0ff,0xff67c8ff,0xff3db9ff,0xff27b1ff,0xff53c1ff,
+ 0xff29b2ff,0xff54c1ff,0xff3fbcff,0xff50c5ff,0xff61cbff,0xff50c5ff,0xff41c0ff,0xff41bfff,0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff43c0ff,0xff44c1ff,0xff44c1ff,
+ 0xff45c1ff,0xff45c2ff,0xff46c2ff,0xff47c3ff,0xff47c3ff,0xff48c3ff,0xff48c5ff,0xff58cbff,0xff48c5ff,0xff48c3ff,0xff67cfff,0xff66cfff,0xff56c8ff,0xff45c2ff,
+ 0xff64ceff,0xff64cdff,0xff54c7ff,0xff53c7ff,0xff63ccff,0xff53c7ff,0xff63ccff,0xff52c6ff,0xff61ccff,0xff50c5ff,0xff50c5ff,0xff60cbff,0xff60cbff,0xff4fc2ff,
+ 0xff3fbdff,0xff3dbcff,0xff4dc1ff,0xff3dbbff,0xff3dbbff,0xff3cbaff,0xff3bbbff,0xff5cc7ff,0xff5cc7ff,0xff3ab9ff,0xff3ab9ff,0xff39b8ff,0xff39b8ff,0xff5bc6ff,
+ 0xff49bfff,0xff5ac5ff,0xff38b7ff,0xff48bdff,0xff58c3ff,0xff58c3ff,0xff35b5ff,0xff35b5ff,0xff57c2ff,0xff33b4ff,0xff44bbff,0xff33b3ff,0xff43baff,0xff33b3ff,
+ 0xff32b2ff,0xff32b2ff,0xff31b1ff,0xff54c1ff,0xff31b2ff,0xff30b1ff,0xff40b8ff,0xff2fb0ff,0xff2eaeff,0xff3fb8ff,0xff3fb7ff,0xff50bdff,0xff3eb7ff,0xff2daeff,
+ 0xff3db5ff,0xff2badff,0xff3cb4ff,0xff3cb4ff,0xff4dbcff,0xff3ab3ff,0xff3ab3ff,0xff3ab3ff,0xff28aaff,0xff28aaff,0xff39b1ff,0xff4abaff,0xff38b1ff,0xff27a9ff,
+ 0xff49b8ff,0xff49b8ff,0xff37b0ff,0xff24a7ff,0xff36aeff,0xff24a7ff,0xff24a7ff,0xff47b7ff,0xff47b7ff,0xff34adff,0xff33adff,0xff46b5ff,0xff32adff,0xff32acff,
+ 0xff31acff,0xff20a3ff,0xff1fa3ff,0xff31abff,0xff42b3ff,0xff30aaff,0xff1ea1ff,0xff41b3ff,0xff41b2ff,0xff1ca0ff,0xff1ba0ff,0xff2ea8ff,0xff2ea8ff,0xff41b2ff,
+ 0xff2faaff,0xff41b2ff,0xff2faaff,0xff30abff,0xff1ea1ff,0xff31abff,0xff4fcaff,0xff50cbff,0xff51cbff,0xff51cbff,0xff51cbff,0xff52ccff,0xff53ccff,0xff53ccff,
+ 0xff54cdff,0xff54cdff,0xff55cdff,0xff55cdff,0xff55ceff,0xff57ceff,0xff56cfff,0xff58cfff,0xff57cfff,0xff58cfff,0xff59cfff,0xff59d0ff,0xff58cfff,0xff58d0ff,
+ 0xff69d4ff,0xff57cfff,0xff56ceff,0xff56ceff,0xff55cdff,0xff55cdff,0xff55cdff,0xff54cdff,0xff53ccff,0xff53ccff,0xff52ccff,0xff75d6ff,0xff75d6ff,0xff51cbff,
+ 0xff51caff,0xff50caff,0xff50caff,0xff4fcaff,0xff4fcaff,0xff4ec9ff,0xff4ec8ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac7ff,0xff4ac7ff,
+ 0xff4ac6ff,0xff48c6ff,0xff49c6ff,0xff5acbff,0xff47c4ff,0xff47c5ff,0xff46c4ff,0xff46c4ff,0xff45c3ff,0xff45c3ff,0xff44c3ff,0xff44c2ff,0xff43c2ff,0xff43c1ff,
+ 0xff42c2ff,0xff42c1ff,0xff41c1ff,0xff41c0ff,0xff40c1ff,0xff40c0ff,0xff40c0ff,0xff52c6ff,0xff3ebfff,0xff3ebfff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3cbeff,
+ 0xff3bbdff,0xff3abdff,0xff3abdff,0xff3abcff,0xff39bcff,0xff38bbff,0xff38bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff4ac1ff,0xff35b9ff,0xff35b9ff,0xff35b9ff,
+ 0xff34b9ff,0xff34b8ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,0xff30b7ff,0xff30b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb6ff,0xff2db5ff,0xff2db4ff,
+ 0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff40bcff,0xff2bb3ff,0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff28b2ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,
+ 0xff25afff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff52c0ff,0xff52c1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff50c5ff,0xff50c5ff,
+ 0xff41bfff,0xff41bfff,0xff41c0ff,0xff43c0ff,0xff42c0ff,0xff43c1ff,0xff43c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff45c3ff,0xff46c2ff,0xff46c3ff,0xff47c3ff,
+ 0xff47c3ff,0xff48c5ff,0xff48c3ff,0xff47c3ff,0xff46c3ff,0xff46c3ff,0xff46c2ff,0xff45c2ff,0xff44c1ff,0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff42c0ff,0xff42c0ff,
+ 0xff41c0ff,0xff42bfff,0xff41bfff,0xff41bfff,0xff41bdff,0xff40bdff,0xff3fbcff,0xff3fbdff,0xff3fbcff,0xff3ebcff,0xff3ebbff,0xff3dbcff,0xff3dbbff,0xff4cc1ff,
+ 0xff3cbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff39b8ff,0xff38b8ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,
+ 0xff35b4ff,0xff35b4ff,0xff34b4ff,0xff41b3f4,0xff31acf4,0xff31abf4,0xff33b3ff,0xff33b2ff,0xff33b2ff,0xff31b2ff,0xff31b2ff,0xff31b2ff,0xff30b1ff,0xff30b0ff,
+ 0xff2fb1ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2daeff,0xff2daeff,0xff2cadff,0xff2cadff,0xff2badff,0xff3cb5ff,0xff2aacff,0xff2aacff,0xff29abff,
+ 0xff29abff,0xff29abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff28aaff,0xff26a9ff,0xff26a9ff,0xff24a1f4,0xff23a1f4,0xff22a1f4,0xff25a7ff,0xff24a8ff,0xff24a7ff,
+ 0xff24a7ff,0xff23a7ff,0xff23a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff33acff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1fa1ff,0xff1ea1ff,
+ 0xff1da1ff,0xff1da1ff,0xff1da0ff,0xff1ca1ff,0xff1ba0ff,0xff1b9fff,0xff1c9fff,0xff1ca0ff,0xff1da0ff,0xff1ea1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff31abff,
+ 0xff4fcaff,0xff50caff,0xff74d6ff,0xff74d6ff,0xff51cbff,0xff52ccff,0xff53ccff,0xff53ccff,0xff54ccff,0xff76d6ff,0xff77d7ff,0xff55ceff,0xff56ceff,0xff56ceff,
+ 0xff56cfff,0xff57cfff,0xff58cfff,0xff58cfff,0xff59cfff,0xff59d0ff,0xff59cfff,0xff58d0ff,0xff57cfff,0xff57cfff,0xff57ceff,0xff57ceff,0xff55cdff,0xff55cdff,
+ 0xff55cdff,0xff54cdff,0xff54cdff,0xff53ccff,0xff52ccff,0xff75d6ff,0xff52ccff,0xff51caff,0xff74d6ff,0xff2e7290,0xff2d7290,0xff2d7290,0xff2d7290,0xff3b99c2,
+ 0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,0xff70d2ff,0xff6fd2ff,0xff4bc7ff,0xff4bc6ff,0xff49c6ff,0xff49c6ff,0xff49c6ff,0xff48c6ff,0xff48c5ff,0xff47c5ff,0xff47c5ff,
+ 0xff46c4ff,0xff45c4ff,0xff46c4ff,0xff45c3ff,0xff44c3ff,0xff3cade2,0xff357b9d,0xff4083a3,0xff6ca2bc,0xff3194c2,0xff67cdff,0xff41c0ff,0xff40c1ff,0xff3fc0ff,
+ 0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff226c90,0xff387390,0xff226b90,0xff216b90,0xff2d90c2,0xff377290,0xff206a90,0xff206a90,0xff2b6e90,
+ 0xff3994c2,0xff38bbff,0xff37bbff,0xff5fc8ff,0xff36baff,0xff36baff,0xff35baff,0xff35b9ff,0xff33b9ff,0xff5cc7ff,0xff2da3e2,0xff1f719d,0xff2c79a3,0xff649dbc,
+ 0xff258bc2,0xff1c6790,0xff1b6790,0xff1b6790,0xff1b6690,0xff238ac2,0xff2eb5ff,0xff2db4ff,0xff2db5ff,0xff2cb4ff,0xff57c3ff,0xff2bb3ff,0xff2bb3ff,0xff2ab3ff,
+ 0xff2ab2ff,0xff29b2ff,0xff28b2ff,0xff28b1ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff26b0ff,0xff26b0ff,0xff51bfff,0xff25afff,0xff3cb8ff,0xff52c0ff,0xff52c1ff,
+ 0xff3db9ff,0xff28b2ff,0xff28b2ff,0xff54c2ff,0xff3fbdff,0xff40bdff,0xff50c3ff,0xff50c3ff,0xff41bfff,0xff41c0ff,0xff42bfff,0xff42c0ff,0xff43c1ff,0xff63cdff,
+ 0xff43c1ff,0xff44c1ff,0xff64ceff,0xff66ceff,0xff45c3ff,0xff56c9ff,0xff67cfff,0xff58c9ff,0xff57cbff,0xff58cbff,0xff67cfff,0xff47c5ff,0xff47c3ff,0xff46c3ff,
+ 0xff46c2ff,0xff55c8ff,0xff54c8ff,0xff64ceff,0xff44c1ff,0xff54c6ff,0xff63cdff,0xff52c6ff,0xff51c6ff,0xff73d0ff,0xff62ccff,0xff41bdff,0xff60cbff,0xff367390,
+ 0xffffffff,0xffffffff,0xffc9d9e1,0xff4899c2,0xff4dc2ff,0xff3dbbff,0xff4cc1ff,0xff4cc1ff,0xff5cc7ff,0xff4bc1ff,0xff5cc6ff,0xff3abaff,0xff49c0ff,0xff5bc6ff,
+ 0xff49c0ff,0xff38b8ff,0xff5bc5ff,0xff49bdff,0xff37b8ff,0xff47bdff,0xff58c3ff,0xff47bdff,0xff35b4ff,0xff1e6690,0xff9ab8c9,0xfff1f5f7,0xffc5d7e1,0xff4193c2,
+ 0xff55c1ff,0xff33b3ff,0xff54c1ff,0xff54c1ff,0xff31b2ff,0xff41b8ff,0xff30b1ff,0xff41b8ff,0xff2fb1ff,0xff246890,0xffffffff,0xffffffff,0xffc5d6e1,0xff3d90c2,
+ 0xff2e6b90,0xffffffff,0xffffffff,0xffc7d7e1,0xff2184c2,0xff3cb4ff,0xff4cbbff,0xff4cbbff,0xff29abff,0xff4cbbff,0xff4cbbff,0xff28aaff,0xff4bbaff,0xff5dc1ff,
+ 0xff206490,0xff8cb1c9,0xfff2f5f7,0xffc3d5e1,0xff2a86c2,0xff1f6290,0xffffffff,0xffffffff,0xffc3d5e1,0xff1b7ec2,0xff23a5ff,0xff33adff,0xff21a5ff,0xff33adff,
+ 0xff32adff,0xff32acff,0xff32acff,0xff44b4ff,0xff1fa3ff,0xff31acff,0xff43b3ff,0xff30aaff,0xff1ea1ff,0xff41b3ff,0xff41b3ff,0xff1ca0ff,0xff41b2ff,0xff55baff,
+ 0xff2ea9ff,0xff41b2ff,0xff1da1ff,0xff1da1ff,0xff30aaff,0xff1ea2ff,0xff31abff,0xff31abff,0xff4fcaff,0xff50caff,0xff51caff,0xff51cbff,0xff52ccff,0xff75d6ff,
+ 0xff76d6ff,0xff64d1ff,0xff76d6ff,0xff87dcff,0xff65d2ff,0xff77d7ff,0xff55ceff,0xff56ceff,0xff68d4ff,0xff89ddff,0xff58cfff,0xff7ad9ff,0xff7ad9ff,0xff6ad5ff,
+ 0xff58cfff,0xff7ad9ff,0xff69d4ff,0xff79d8ff,0xff79d8ff,0xff78d8ff,0xff67d3ff,0xff55ceff,0xff77d7ff,0xff65d2ff,0xff54ccff,0xff76d6ff,0xff52ccff,0xff75d6ff,
+ 0xff52cbff,0xff51cbff,0xff85daff,0xff2d7290,0xffffffff,0xffffffff,0xffc7d9e1,0xff3b99c2,0xff2b7290,0xff2b7290,0xff3f7790,0xff2b7190,0xff4786a3,0xff367895,
+ 0xff2c7495,0xff417a95,0xff55a2c5,0xff49c5fe,0xff6ccffc,0xff399bc9,0xff43829f,0xff3e7892,0xff3e7792,0xff3d7792,0xff297497,0xff4b93b5,0xff266e90,0xff266e90,
+ 0xffffffff,0xffffffff,0xffcbdae1,0xff256e90,0xff457790,0xff3986ac,0xff257094,0xff256f93,0xff3b7693,0xff3a7693,0xff287aa3,0xff52a6d0,0xff3dbefe,0xff226b90,
+ 0xffffffff,0xffffffff,0xffcad9e1,0xff2c90c2,0xff427690,0xffffffff,0xffffffff,0xffcad9e1,0xff2b8ec2,0xff53aedd,0xff257eac,0xff437894,0xff367393,0xff1f6b93,
+ 0xff1f6b93,0xff3b7fa3,0xff2a97d0,0xff357090,0xff1c6890,0xffffffff,0xffffffff,0xffc9d9e1,0xff1b6790,0xff3e7390,0xffcadbe5,0xffcfdde5,0xffa4bfcd,0xff248ac2,
+ 0xff2caef5,0xff4191bd,0xff1b6b98,0xff347498,0xff1a6b98,0xff337498,0xff2e88ba,0xff28abf3,0xff54c1ff,0xff3b7290,0xff176590,0xff2f6d90,0xff2f6d90,0xff1971a3,
+ 0xff176795,0xff307095,0xff166795,0xff3f94c5,0xff25affe,0xff52c0ff,0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff54c1ff,0xff29b2ff,0xff3fbdff,0xff40bdff,
+ 0xff40bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff42c0ff,0xff43c0ff,0xff63cdff,0xff43c2ff,0xff64ceff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff67cfff,
+ 0xff47c3ff,0xff67cfff,0xff68cfff,0xff49c5ff,0xff48c3ff,0xff68cfff,0xff47c3ff,0xff47c3ff,0xff46c2ff,0xff66ceff,0xff45c1ff,0xff44c1ff,0xff63cdff,0xff63cdff,
+ 0xff63cdff,0xff74d2ff,0xff42c0ff,0xff62ccff,0xff41bfff,0xff41bfff,0xff61ccff,0xff246b90,0xffffffff,0xffffffff,0xffc9d9e1,0xff4899c2,0xff2b6e90,0xffffffff,
+ 0xffffffff,0xffc5d8e2,0xff9ebbc9,0xffebf1f5,0xfff9fafb,0xffc7d8e1,0xff437b99,0xff32a0dd,0xff3e86ad,0xff4681a3,0xffc1d3dd,0xfff0f4f6,0xfffcfdfd,0xfff8fafb,
+ 0xffd9e4ea,0xff709ab2,0xff1e6690,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff367193,0xff9cbbcc,0xffe2eaef,0xfffafbfc,0xfffcfdfd,0xffeaf1f5,
+ 0xffb6cbd8,0xff41799a,0xff258ac7,0xff1a6390,0xffffffff,0xffffffff,0xffc7d8e1,0xff2284c2,0xff2d6b90,0xffffffff,0xffffffff,0xffc2d5e1,0xff2183c2,0xff326e93,
+ 0xff96b7cc,0xffe1eaef,0xfffafbfc,0xfffbfcfd,0xffeaf0f5,0xffb4cad8,0xff2c6e9a,0xff2a6890,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff296890,
+ 0xffffffff,0xffffffff,0xffc6d6e1,0xff1b7ec2,0xff135d90,0xff6794b0,0xffc9dae6,0xfff6f9fa,0xfff6f8fa,0xffd0dee6,0xff6192b5,0xff125c90,0xff3fa8ef,0xff266690,
+ 0xffffffff,0xffffffff,0xffc7d7e2,0xff97b5c9,0xffebf1f5,0xfff9fafb,0xffbdd2e1,0xff367099,0xff188bdd,0xff41b2ff,0xff1ca0ff,0xff1da1ff,0xff2faaff,0xff1ea2ff,
+ 0xff42b3ff,0xff20a2ff,0xff50caff,0xff50caff,0xff50cbff,0xff51cbff,0xff51cbff,0xff52cbff,0xff53ccff,0xff53cdff,0xff54cdff,0xff76d7ff,0xff55cdff,0xff66d2ff,
+ 0xff78d8ff,0xff78d8ff,0xff68d3ff,0xff89ddff,0xff79d9ff,0xff7bd9ff,0xff7bd9ff,0xff7bd9ff,0xff7ad9ff,0xff69d5ff,0xff58cfff,0xff58ceff,0xff57cfff,0xff78d8ff,
+ 0xff78d8ff,0xff77d7ff,0xff66d2ff,0xff77d7ff,0xff76d7ff,0xff87dbff,0xff53ccff,0xff63d0ff,0xff74d6ff,0xff62cfff,0xff74d5ff,0xff2d7290,0xffffffff,0xffffffff,
+ 0xffc7d9e1,0xff3b99c2,0xff2b7290,0xffffffff,0xffffffff,0xfffcfdfd,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffa9c1cd,0xff55a1c5,0xff488aa8,0xffe0eaee,
+ 0xffffffff,0xfffcfdfd,0xffd8e3e9,0xfff4f7f8,0xffffffff,0xfffafbfc,0xff4c87a3,0xffd2dfe5,0xffffffff,0xffffffff,0xfff3f6f7,0xffd1dfe5,0xffa8bfcb,0xffffffff,
+ 0xffffffff,0xffe8eff2,0xffd8e3e9,0xfffeffff,0xffffffff,0xffbed4de,0xff236f94,0xff387390,0xffffffff,0xffffffff,0xffcad9e1,0xff4b9ac2,0xff427590,0xffffffff,
+ 0xffffffff,0xffc4d7e1,0xff2b8ec2,0xffa1bccb,0xffffffff,0xffffffff,0xffe6eef2,0xffd7e3e9,0xfffeffff,0xffffffff,0xffbdd3de,0xff357090,0xffd0dee5,0xffffffff,
+ 0xffffffff,0xfff2f5f7,0xffcadce5,0xff336f90,0xffffffff,0xffffffff,0xffc5d7e1,0xff3e88b1,0xff769fb5,0xffffffff,0xffffffff,0xffe9f0f5,0xffe7eff4,0xffffffff,
+ 0xffffffff,0xff7ea4ba,0xff2b80ae,0xff2f6d90,0xffffffff,0xffffffff,0xfffcfcfd,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffa1bdcd,0xff3f94c5,0xff3cb8ff,
+ 0xff52c0ff,0xff52c1ff,0xff3db9ff,0xff53c1ff,0xff28b1ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42c0ff,
+ 0xff43c0ff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff45c2ff,0xff66ceff,0xff46c3ff,0xff48c3ff,0xff68cfff,0xff48c5ff,0xff47c3ff,0xff47c3ff,
+ 0xff46c3ff,0xff46c3ff,0xff46c2ff,0xff65ceff,0xff45c2ff,0xff44c2ff,0xff43c1ff,0xff43c1ff,0xff43c1ff,0xff42c0ff,0xff42bfff,0xff41c0ff,0xff41bfff,0xff41bdff,
+ 0xff41bdff,0xff246b90,0xffffffff,0xffffffff,0xffc4d7e1,0xff2f8ec2,0xff236a90,0xffffffff,0xffffffff,0xfff0f5f7,0xff427fa0,0xff548caa,0xffffffff,0xffffffff,
+ 0xffc1d5e0,0xff2b8cc2,0xff2679a8,0xffe5edf2,0xffffffff,0xffe8eff4,0xff76a2bb,0xff78a3bc,0xff74a0ba,0xff4983a5,0xff407a9b,0xff1e6690,0xffffffff,0xffffffff,
+ 0xffc3d6e1,0xff1f6f9d,0xff4882a5,0xff6898b5,0xff76a2bc,0xff35759c,0xff5e91b1,0xffe5edf2,0xffffffff,0xfffafbfc,0xff1b6390,0xff1a6390,0xffffffff,0xffffffff,
+ 0xffc2d5e1,0xff2284c2,0xff196290,0xffffffff,0xffffffff,0xffc2d5e1,0xff2183c2,0xff447fa5,0xff6596b5,0xff739fbc,0xff30729c,0xff5a8fb1,0xffe4edf2,0xffffffff,
+ 0xfffafbfc,0xff165f90,0xff165f90,0xffffffff,0xffffffff,0xffc6d7e1,0xff226c9d,0xff145f90,0xffffffff,0xffffffff,0xffc0d4e1,0xff146094,0xffd9e5ed,0xffffffff,
+ 0xffedf2f5,0xff1f6596,0xff1d6495,0xffedf2f5,0xffffffff,0xffdce7ee,0xff125f94,0xff125b90,0xffffffff,0xffffffff,0xffeff4f7,0xff3372a0,0xff4781aa,0xffffffff,
+ 0xffffffff,0xffbcd1e0,0xff157ac2,0xff1ca0ff,0xff1ca0ff,0xff1da1ff,0xff1da1ff,0xff42b3ff,0xff1fa2ff,0xff1fa2ff,0xff50c9ff,0xff50caff,0xff51cbff,0xff51caff,
+ 0xff52cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff53cdff,0xff54ccff,0xff54ceff,0xff55cdff,0xff55ceff,0xff57ceff,0xff56cfff,0xff57ceff,0xff58cfff,0xff59cfff,
+ 0xff59d0ff,0xff59d0ff,0xff58d0ff,0xff59cfff,0xff58cfff,0xff57cfff,0xff57ceff,0xff56ceff,0xff56cdff,0xff55cdff,0xff55cdff,0xff54cdff,0xff53cdff,0xff53ccff,
+ 0xff52ccff,0xff52ccff,0xff51ccff,0xff52cbff,0xff50cbff,0xff2d7290,0xffffffff,0xffffffff,0xffc7d9e1,0xff3b99c2,0xff2b7190,0xffffffff,0xffffffff,0xffc9dbe3,
+ 0xff2e7b9d,0xff2a7190,0xffffffff,0xffffffff,0xffc6d9e1,0xff3897c2,0xff2f82a8,0xff548ca7,0xffcddde5,0xfffafbfc,0xffffffff,0xffffffff,0xffffffff,0xffd4e2e9,
+ 0xff4683a0,0xff266e90,0xffffffff,0xffffffff,0xffc5d8e1,0xff2c81aa,0xff538ca8,0xffc1d6e0,0xfff0f5f7,0xfffbfcfc,0xffd2e2e9,0xffeaf1f5,0xffffffff,0xffffffff,
+ 0xff226c90,0xff226b90,0xffffffff,0xffffffff,0xffc4d7e1,0xff2d8fc2,0xff216b90,0xffffffff,0xffffffff,0xffc4d7e1,0xff257daa,0xff4e89a8,0xffc0d5e0,0xffeff5f7,
+ 0xfffafbfc,0xffd1e1e9,0xffeaf1f5,0xffffffff,0xffffffff,0xff1d6890,0xff1d6890,0xffffffff,0xffffffff,0xffc3d7e1,0xff248bc1,0xff1b6790,0xffffffff,0xffffffff,
+ 0xffc2d6e1,0xff1b6994,0xfffafbfc,0xffffffff,0xffc9dbe5,0xff1c72a1,0xff1b71a1,0xffc6d9e3,0xffffffff,0xfffafbfc,0xff186794,0xff176590,0xffffffff,0xffffffff,
+ 0xffc4d8e3,0xff196c9d,0xff156390,0xffffffff,0xffffffff,0xffc1d5e1,0xff1d86c2,0xff26b0ff,0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,
+ 0xff3fbdff,0xff40bdff,0xff61cbff,0xff61ccff,0xff41bfff,0xff41bfff,0xff42c0ff,0xff42c0ff,0xff52c6ff,0xff44c1ff,0xff43c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,
+ 0xff46c2ff,0xff46c2ff,0xff47c3ff,0xff47c3ff,0xff47c5ff,0xff49c5ff,0xff48c5ff,0xff67cfff,0xff47c3ff,0xff46c3ff,0xff46c3ff,0xff45c2ff,0xff45c2ff,0xff44c2ff,
+ 0xff43c1ff,0xff43c0ff,0xff43c1ff,0xff42c0ff,0xff42c0ff,0xff51c6ff,0xff41bfff,0xff41bdff,0xff40bfff,0xff367390,0xffffffff,0xffffffff,0xffc5d7e1,0xff3b94c2,
+ 0xff236a90,0xffffffff,0xffffffff,0xffc4d7e1,0xff2d8ec1,0xff216990,0xffffffff,0xffffffff,0xffc9d9e1,0xff4597c2,0xff337ea7,0xff6697b3,0xff74a1ba,0xff76a2bb,
+ 0xff417fa1,0xff709eb8,0xffffffff,0xffffffff,0xffb2cad8,0xff326e90,0xfffeffff,0xffffffff,0xffc8d9e3,0xff1e6894,0xffe3ebf0,0xffffffff,0xffdee8ee,0xff2b6f98,
+ 0xff2f7097,0xffe1eaf0,0xffffffff,0xffffffff,0xff1b6490,0xff2e6c90,0xffffffff,0xffffffff,0xffc5d6e1,0xff3d90c2,0xff236690,0xffffffff,0xffffffff,0xffc2d5e1,
+ 0xff1b6ea2,0xffe1eaf0,0xffffffff,0xffe0e9ee,0xff266b98,0xff216997,0xffe0eaf0,0xffffffff,0xffffffff,0xff2a6890,0xff2a6890,0xfffeffff,0xffffffff,0xffc4d6e3,
+ 0xff156294,0xff1e6390,0xffffffff,0xffffffff,0xffc1d4e1,0xff146094,0xffdbe6ee,0xffffffff,0xffecf2f5,0xff1d6495,0xff1b6294,0xffe8f0f5,0xffffffff,0xffdae6ee,
+ 0xff125e94,0xff125b90,0xffffffff,0xffffffff,0xffc0d3e1,0xff167ac1,0xff105b90,0xffffffff,0xffffffff,0xffbfd3e1,0xff3187c2,0xff1ca0ff,0xff1da0ff,0xff1da0ff,
+ 0xff2faaff,0xff1ea1ff,0xff1fa1ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff74d5ff,0xff74d6ff,0xff52cbff,0xff52ccff,0xff53ccff,0xff53cdff,0xff76d6ff,0xff55cdff,
+ 0xff55cdff,0xff56ceff,0xff56cdff,0xff57ceff,0xff57cfff,0xff57cfff,0xff58cfff,0xff58cfff,0xff59d0ff,0xff59d0ff,0xff7bd9ff,0xff58cfff,0xff58cfff,0xff57cfff,
+ 0xff57cfff,0xff56ceff,0xff56ceff,0xff55ceff,0xff55cdff,0xff54cdff,0xff53ccff,0xff54ccff,0xff53ccff,0xff76d6ff,0xff51cbff,0xff51cbff,0xff50cbff,0xff417890,
+ 0xffffffff,0xffffffff,0xffc7d9e1,0xff499dc2,0xff2b7190,0xffffffff,0xffffffff,0xffc7d9e1,0xff3a97c2,0xff2a7090,0xffffffff,0xffffffff,0xffccdae1,0xff3897c2,
+ 0xff518ca7,0xffeef3f5,0xffffffff,0xffffffff,0xffdce7ed,0xffe2ecf0,0xffffffff,0xffffffff,0xff9ebac7,0xff276e91,0xffecf2f5,0xffffffff,0xfffafcfc,0xffd6e4eb,
+ 0xffedf2f5,0xffffffff,0xfffeffff,0xffd5e3ea,0xfff0f4f6,0xfffcfdfd,0xffffffff,0xffffffff,0xff3c7592,0xff226b90,0xffffffff,0xffffffff,0xffcad9e1,0xff2c90c2,
+ 0xff377290,0xffffffff,0xffffffff,0xffc4d7e1,0xff2477a2,0xffebf1f5,0xffffffff,0xfffeffff,0xffd4e2ea,0xffeef3f6,0xfffcfdfd,0xffffffff,0xffffffff,0xff377292,
+ 0xff347191,0xffebf1f5,0xffffffff,0xfffafbfc,0xffd4e3eb,0xff336f90,0xffffffff,0xffffffff,0xffc2d6e1,0xff207caf,0xff79a1b6,0xffffffff,0xffffffff,0xffe8f0f4,
+ 0xffe7eff4,0xffffffff,0xffffffff,0xff699ab7,0xff1c7baf,0xff176590,0xffffffff,0xffffffff,0xffc1d6e1,0xff1e87c2,0xff166490,0xffffffff,0xffffffff,0xffc1d5e1,
+ 0xff3e92c2,0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff52c1ff,0xff28b2ff,0xff28b1ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff41bdff,0xff41bfff,0xff41bfff,0xff41c0ff,
+ 0xff42c0ff,0xff42c0ff,0xff63ccff,0xff43c1ff,0xff43c1ff,0xff44c1ff,0xff44c2ff,0xff45c2ff,0xff45c2ff,0xff46c3ff,0xff47c2ff,0xff47c3ff,0xff48c3ff,0xff48c5ff,
+ 0xff67cfff,0xff47c3ff,0xff77d4ff,0xff66cfff,0xff66cfff,0xff65ceff,0xff65cdff,0xff64ceff,0xff54c7ff,0xff63cdff,0xff63ccff,0xff63ccff,0xff52c6ff,0xff73d0ff,
+ 0xff61ccff,0xff41bfff,0xff41bdff,0xff367390,0xffffffff,0xffffffff,0xffc7d8e1,0xff4899c2,0xff226a90,0xffffffff,0xffffffff,0xffc9d9e1,0xff2e8ec2,0xff216990,
+ 0xffffffff,0xffffffff,0xffc9d9e1,0xff2c8dc2,0xff397da1,0xff5086a4,0xffc2d4de,0xffeef3f5,0xfffcfdfd,0xfff9fafb,0xffe1e9ee,0xff91b3c6,0xff346f91,0xff2273a2,
+ 0xff77a2bb,0xffeef3f6,0xfffcfdfd,0xffe9f0f4,0xff739cb4,0xffdde7ed,0xfffafbfc,0xffedf2f5,0xffb0c8d6,0xff8bb0c6,0xffffffff,0xffffffff,0xff4b83a4,0xff2e6c90,
+ 0xffffffff,0xffffffff,0xffc7d8e1,0xff308bc2,0xff196290,0xffffffff,0xffffffff,0xffc2d5e1,0xff1b6da2,0xff578cae,0xffdae5ed,0xfffafbfc,0xffecf2f5,0xffa6c3d6,
+ 0xff88aec6,0xffffffff,0xffffffff,0xff407ca4,0xff196ba2,0xff729ebb,0xffeef3f6,0xfffbfcfd,0xffe7eff4,0xff347096,0xffffffff,0xffffffff,0xffc1d4e1,0xff1b7ec2,
+ 0xff286790,0xff5c8fb2,0xffd2dee7,0xfff7fafb,0xfff7fafb,0xffcedde6,0xff6c97b4,0xff266690,0xff2ea2f1,0xff266590,0xffffffff,0xffffffff,0xffc2d5e1,0xff3188c2,
+ 0xff256590,0xffffffff,0xffffffff,0xffc5d6e1,0xff157ac2,0xff2eaaff,0xff41b2ff,0xff41b3ff,0xff41b3ff,0xff42b3ff,0xff43b3ff,0xff43b3ff,0xff50caff,0xff50caff,
+ 0xff50caff,0xff51caff,0xff52cbff,0xff75d6ff,0xff76d6ff,0xff64d1ff,0xff76d6ff,0xff55cdff,0xff54cdff,0xff55ceff,0xff56ceff,0xff56ceff,0xff56cfff,0xff57cfff,
+ 0xff57cfff,0xff58cfff,0xff59d0ff,0xff6bd5ff,0xff6ad5ff,0xff58cfff,0xff79d9ff,0xff57cfff,0xff79d8ff,0xff78d8ff,0xff55ceff,0xff55cdff,0xff77d8ff,0xff87dcff,
+ 0xff76d7ff,0xff87dbff,0xff53ccff,0xff75d6ff,0xff52cbff,0xff51cbff,0xff51caff,0xff427890,0xff2d7290,0xff2d7290,0xff2d7290,0xff57a1c2,0xff2c7190,0xff407790,
+ 0xff2b7190,0xff3f7790,0xff3997c2,0xff357490,0xff347490,0xff297090,0xff3f7690,0xff3896c2,0xff6ccefb,0xff55a4c8,0xff2d7ca1,0xff297192,0xff3d7792,0xff287092,
+ 0xff3e7995,0xff2e85ae,0xff5fb9e4,0xff3eb5ed,0xff41809f,0xff3d7793,0xff3c7793,0xff317393,0xff4f89a5,0xff3b7693,0xff256f93,0xff256f93,0xff4081a1,0xff236c90,
+ 0xff236c90,0xff236c90,0xff226b90,0xff226b90,0xff387390,0xff2d6f90,0xff216b90,0xff3b95c2,0xff377290,0xff377290,0xff206a90,0xff206a90,0xff2b8ec2,0xff2682b1,
+ 0xff206c93,0xff206b93,0xff1f6b93,0xff2275a1,0xff1e6990,0xff1e6890,0xff1d6890,0xff1d6890,0xff2fabed,0xff20739f,0xff347293,0xff347293,0xff286e93,0xff336f90,
+ 0xff1b6790,0xff1b6790,0xff1b6690,0xff348fc2,0xff3fb5f5,0xff2185bc,0xff347397,0xff1a6b97,0xff337397,0xff337397,0xff1f83ba,0xff28abf4,0xff55c1ff,0xff306d90,
+ 0xff2f6d90,0xff2f6d90,0xff2e6d90,0xff3e92c2,0xff2e6c90,0xff2e6d90,0xff156390,0xff2e6c90,0xff1c86c2,0xff52c0ff,0xff27b0ff,0xff27b1ff,0xff53c1ff,0xff3ebaff,
+ 0xff53c1ff,0xff6ac9ff,0xff40bdff,0xff40bfff,0xff41bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42c0ff,0xff42c0ff,0xff63cdff,0xff43c0ff,0xff44c1ff,0xff44c1ff,
+ 0xff45c1ff,0xff55c8ff,0xff46c2ff,0xff46c3ff,0xff57c9ff,0xff47c5ff,0xff48c5ff,0xff68cfff,0xff48c5ff,0xff47c3ff,0xff77d4ff,0xff46c3ff,0xff65ceff,0xff65ceff,
+ 0xff44c1ff,0xff44c1ff,0xff64cdff,0xff63ccff,0xff43c0ff,0xff52c6ff,0xff42c0ff,0xff62ccff,0xff41bfff,0xff50c5ff,0xff40bdff,0xff60cbff,0xff3fbdff,0xff3fbcff,
+ 0xff3fbcff,0xff5fc9ff,0xff3ebcff,0xff6fcfff,0xff3cbbff,0xff5dc8ff,0xff3bbaff,0xff5cc7ff,0xff3bbaff,0xff3ab9ff,0xff5bc6ff,0xff39b8ff,0xff5bc6ff,0xff5bc6ff,
+ 0xff38b8ff,0xff38b8ff,0xff59c5ff,0xff36b7ff,0xff59c3ff,0xff47bdff,0xff58c3ff,0xff35b4ff,0xff45bbff,0xff57c2ff,0xff57c1ff,0xff33b3ff,0xff67c8ff,0xff54c1ff,
+ 0xff32b2ff,0xff31b2ff,0xff54c0ff,0xff30b2ff,0xff41b8ff,0xff2fb1ff,0xff52c0ff,0xff2eb0ff,0xff2eb0ff,0xff51bfff,0xff51bfff,0xff2eaeff,0xff50bdff,0xff4fbdff,
+ 0xff2cadff,0xff2badff,0xff2bacff,0xff2bacff,0xff2aabff,0xff2aabff,0xff28abff,0xff29abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff26a9ff,0xff27a8ff,
+ 0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff49b8ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff48b7ff,0xff23a5ff,0xff22a4ff,0xff46b5ff,0xff21a4ff,0xff46b5ff,0xff46b4ff,
+ 0xff20a3ff,0xff20a3ff,0xff44b3ff,0xff43b3ff,0xff42b3ff,0xff42b3ff,0xff41b3ff,0xff1da1ff,0xff1ca1ff,0xff2ea9ff,0xff2ea9ff,0xff2ea8ff,0xff1ca0ff,0xff41b2ff,
+ 0xff1da1ff,0xff2faaff,0xff42b3ff,0xff42b3ff,0xff1ea2ff,0xff43b4ff,0xff4fcaff,0xff50caff,0xff50caff,0xff51cbff,0xff52cbff,0xff52cbff,0xff52ccff,0xff53cdff,
+ 0xff76d6ff,0xff76d6ff,0xff77d7ff,0xff56cdff,0xff67d3ff,0xff89ddff,0xff57cfff,0xff58ceff,0xff8addff,0xff69d5ff,0xff6ad5ff,0xff6bd5ff,0xff58cfff,0xff58cfff,
+ 0xff7ad9ff,0xff79d9ff,0xff68d3ff,0xff67d3ff,0xff56ceff,0xff55cdff,0xff66d2ff,0xff65d2ff,0xff76d7ff,0xff64d1ff,0xff52ccff,0xff52ccff,0xff75d6ff,0xff51cbff,
+ 0xff62d0ff,0xff73d5ff,0xff73d5ff,0xff4fc9ff,0xff72d4ff,0xff72d4ff,0xff5fceff,0xff5fcdff,0xff70d3ff,0xff5ecdff,0xff5dcdff,0xff5dcdff,0xff4ac6ff,0xff4ac6ff,
+ 0xff6fd1ff,0xff6ed1ff,0xff48c6ff,0xff47c5ff,0xff6cd1ff,0xff6cd0ff,0xff46c5ff,0xff46c4ff,0xff58caff,0xff58c9ff,0xff44c3ff,0xff69ceff,0xff56c8ff,0xff55c8ff,
+ 0xff56c8ff,0xff42c1ff,0xff54c7ff,0xff41c1ff,0xff66cdff,0xff66cdff,0xff3fc0ff,0xff3ebfff,0xff78d2ff,0xff51c5ff,0xff3dbfff,0xff63cbff,0xff63cbff,0xff3bbdff,
+ 0xff4fc5ff,0xff63caff,0xff4ec3ff,0xff4ec4ff,0xff61caff,0xff61caff,0xff4cc3ff,0xff37bbff,0xff37baff,0xff36bbff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff34b9ff,
+ 0xff34b8ff,0xff34b8ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff32b7ff,0xff31b6ff,0xff5ac5ff,0xff59c5ff,0xff59c5ff,0xff43bcff,0xff43bcff,0xff2eb4ff,0xff2db4ff,
+ 0xff42bcff,0xff2cb4ff,0xff41bcff,0xff2cb3ff,0xff55c2ff,0xff55c2ff,0xff2ab3ff,0xff3fbaff,0xff29b2ff,0xff3eb9ff,0xff28b1ff,0xff52c1ff,0xff52c0ff,0xff26b0ff,
+ 0xff51c0ff,0xff25afff,0xff26afff,0xff26b0ff,0xff52c0ff,0xff3db9ff,0xff3eb9ff,0xff3fbaff,0xff53c1ff,0xff54c1ff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,
+ 0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff43c0ff,0xff43c0ff,0xff43c1ff,0xff45c1ff,0xff45c1ff,0xff45c2ff,0xff46c2ff,0xff46c2ff,0xff47c3ff,0xff48c5ff,
+ 0xff58c9ff,0xff48c5ff,0xff48c5ff,0xff47c3ff,0xff57c9ff,0xff46c3ff,0xff46c2ff,0xff46c2ff,0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,0xff43c0ff,0xff42c0ff,
+ 0xff42c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff40bfff,0xff40bdff,0xff40bdff,0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff3ebbff,0xff3dbbff,0xff3cbbff,0xff3cbbff,
+ 0xff4cc1ff,0xff3bbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff38b8ff,0xff38b7ff,0xff38b7ff,0xff37b7ff,0xff36b7ff,0xff37b7ff,0xff36b5ff,
+ 0xff35b5ff,0xff35b5ff,0xff34b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,
+ 0xff2fb0ff,0xff2fb0ff,0xff2eaeff,0xff2eaeff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2aacff,0xff29abff,
+ 0xff29abff,0xff29aaff,0xff28aaff,0xff28aaff,0xff28a9ff,0xff27aaff,0xff27aaff,0xff26a9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,
+ 0xff35aeff,0xff23a5ff,0xff23a5ff,0xff22a5ff,0xff22a4ff,0xff22a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea2ff,0xff1ea1ff,
+ 0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca0ff,0xff2ea9ff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1da1ff,0xff1ea2ff,0xff1fa2ff,0xff20a2ff,
+ 0xff4fcaff,0xff50cbff,0xff62cfff,0xff62d0ff,0xff52cbff,0xff52ccff,0xff53ccff,0xff64d1ff,0xff53cdff,0xff54cdff,0xff55cdff,0xff55ceff,0xff56ceff,0xff56ceff,
+ 0xff57ceff,0xff57ceff,0xff58cfff,0xff59cfff,0xff59d0ff,0xff59d0ff,0xff59cfff,0xff58cfff,0xff57cfff,0xff57cfff,0xff68d4ff,0xff57ceff,0xff56ceff,0xff55ceff,
+ 0xff54cdff,0xff54cdff,0xff54ccff,0xff53ccff,0xff53ccff,0xff53cbff,0xff52cbff,0xff51caff,0xff50cbff,0xff50caff,0xff50caff,0xff4fc9ff,0xff4fc9ff,0xff4ec9ff,
+ 0xff4ec9ff,0xff4dc9ff,0xff4dc8ff,0xff5ecdff,0xff4bc7ff,0xff4bc7ff,0xff4bc6ff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,0xff49c5ff,0xff47c5ff,0xff47c5ff,0xff47c5ff,
+ 0xff46c4ff,0xff46c4ff,0xff46c4ff,0xff45c3ff,0xff45c3ff,0xff44c2ff,0xff43c2ff,0xff43c2ff,0xff42c2ff,0xff41c1ff,0xff41c1ff,0xff41c1ff,0xff40c1ff,0xff40c0ff,
+ 0xff53c5ff,0xff3fbfff,0xff3fbfff,0xff3ebfff,0xff3dbeff,0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff3bbeff,0xff3bbdff,0xff3abdff,0xff39bcff,0xff39bcff,0xff38bbff,
+ 0xff38bcff,0xff37bbff,0xff37baff,0xff37baff,0xff36baff,0xff35baff,0xff35baff,0xff48c0ff,0xff34b8ff,0xff33b8ff,0xff33b8ff,0xff33b8ff,0xff31b8ff,0xff31b7ff,
+ 0xff31b6ff,0xff30b6ff,0xff30b6ff,0xff44bdff,0xff2fb6ff,0xff2eb5ff,0xff2db5ff,0xff2db4ff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,0xff2ab3ff,
+ 0xff29b3ff,0xff29b3ff,0xff29b2ff,0xff28b1ff,0xff28b2ff,0xff28b0ff,0xff27b0ff,0xff3cb8ff,0xff25b0ff,0xff25afff,0xff25b0ff,0xff26b0ff,0xff27b1ff,0xff27b1ff,
+ 0xff27b1ff,0xff28b2ff,0xff29b1ff,0xff29b2ff,0xff3fbcff,0xff40bdff,0xff60cbff,0xff61ccff,0xff41bfff,0xff41c0ff,0xff51c6ff,0xff52c6ff,0xff63ccff,0xff43c1ff,
+ 0xff43c1ff,0xff44c2ff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff46c3ff,0xff47c3ff,0xff48c3ff,0xff47c3ff,0xff48c5ff,0xff48c3ff,0xff48c3ff,0xff46c3ff,0xff46c3ff,
+ 0xff66ceff,0xff45c2ff,0xff45c2ff,0xff44c1ff,0xff64cdff,0xff43c1ff,0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff40bfff,0xff60cbff,
+ 0xff3fbdff,0xff3fbcff,0xff3fbcff,0xff3ebcff,0xff5fc8ff,0xff3dbbff,0xff3dbbff,0xff5dc7ff,0xff3cbaff,0xff3bbaff,0xff3abaff,0xff5cc6ff,0xff3ab9ff,0xff3ab9ff,
+ 0xff3ab8ff,0xff39b8ff,0xff5ac6ff,0xff37b7ff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b4ff,
+ 0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff42b9ff,0xff41b9ff,0xff31b1ff,0xff30b1ff,0xff30b0ff,0xff2fb1ff,0xff2fb0ff,0xff2eaeff,0xff2eaeff,0xff2eb0ff,0xff2daeff,
+ 0xff2daeff,0xff2dadff,0xff4fbdff,0xff2bacff,0xff2bacff,0xff4ebcff,0xff4dbbff,0xff4dbbff,0xff29abff,0xff29aaff,0xff3ab3ff,0xff39b2ff,0xff28aaff,0xff28a9ff,
+ 0xff27a9ff,0xff27a8ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff48b8ff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff22a5ff,0xff22a5ff,0xff21a4ff,
+ 0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff43b3ff,0xff1fa2ff,0xff1da1ff,0xff1da1ff,0xff2eaaff,0xff2ea9ff,0xff1c9fff,0xff1ba0ff,
+ 0xff1ba0ff,0xff1ca0ff,0xff1da1ff,0xff1da0ff,0xff1ea1ff,0xff1ea2ff,0xff1ea2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff62cfff,0xff62d0ff,0xff51cbff,0xff53ccff,
+ 0xff75d6ff,0xff54ccff,0xff76d6ff,0xff76d6ff,0xff66d2ff,0xff55ceff,0xff78d7ff,0xff79d8ff,0xff56ceff,0xff68d3ff,0xff69d4ff,0xff69d4ff,0xff59d0ff,0xff7bd9ff,
+ 0xff7bd9ff,0xff58cfff,0xff57cfff,0xff68d4ff,0xff67d3ff,0xff56ceff,0xff78d8ff,0xff66d3ff,0xff77d7ff,0xff65d2ff,0xff76d6ff,0xff64d1ff,0xff52ccff,0xff63d1ff,
+ 0xff51cbff,0xff62d0ff,0xff50cbff,0xff73d5ff,0xff4fcaff,0xff4fcaff,0xff72d5ff,0xff60ceff,0xff71d3ff,0xff4dc8ff,0xff5ecdff,0xff5ecdff,0xff4cc7ff,0xff6fd2ff,
+ 0xff5cccff,0xff6fd1ff,0xff5bccff,0xff6ed1ff,0xff5bcbff,0xff5acbff,0xff7fd6ff,0xff6cd0ff,0xff47c4ff,0xff59caff,0xff6acfff,0xff58c9ff,0xff58c9ff,0xff57c8ff,
+ 0xff69ceff,0xff43c2ff,0xff55c8ff,0xff42c1ff,0xff54c7ff,0xff41c1ff,0xff40c1ff,0xff66cdff,0xff3fbfff,0xff52c5ff,0xff65ccff,0xff50c5ff,0xff50c5ff,0xff50c5ff,
+ 0xff63caff,0xff3bbdff,0xff4fc4ff,0xff62caff,0xff4ec4ff,0xff4ec3ff,0xff74d0ff,0xff60caff,0xff38bbff,0xff60c9ff,0xff37baff,0xff4ac1ff,0xff36baff,0xff35b9ff,
+ 0xff5ec8ff,0xff34b9ff,0xff33b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff32b7ff,0xff31b6ff,0xff31b7ff,0xff45bdff,0xff44bdff,0xff43bcff,0xff43bdff,
+ 0xff58c4ff,0xff2db4ff,0xff41bcff,0xff57c3ff,0xff41bcff,0xff2bb3ff,0xff55c2ff,0xff55c1ff,0xff29b2ff,0xff55c2ff,0xff69c8ff,0xff3eb9ff,0xff28b2ff,0xff27b1ff,
+ 0xff52c0ff,0xff26b0ff,0xff3cb8ff,0xff51c0ff,0xff3bb8ff,0xff26b1ff,0xff52c0ff,0xff52c1ff,0xff28b1ff,0xff3fb9ff,0xff54c1ff,0xff3fbaff,0xff40bdff,0xff40bdff,
+ 0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff63ccff,0xff43c0ff,0xff74d3ff,0xff43c1ff,0xff64cdff,0xff64cdff,0xff45c2ff,0xff45c2ff,0xff66ceff,0xff66cfff,
+ 0xff67cfff,0xff67cfff,0xff68cfff,0xff48c5ff,0xff48c5ff,0xff67cfff,0xff46c3ff,0xff66cfff,0xff45c3ff,0xff65ceff,0xff44c1ff,0xff54c7ff,0xff63cdff,0xff53c7ff,
+ 0xff43c0ff,0xff63ccff,0xff42bfff,0xff62ccff,0xff41c0ff,0xff61ccff,0xff41bdff,0xff60ccff,0xff3fbdff,0xff5fcbff,0xff3ebcff,0xff4ec2ff,0xff5fc9ff,0xff3dbbff,
+ 0xff5dc8ff,0xff3cbbff,0xff5dc8ff,0xff3bbaff,0xff4ac0ff,0xff5cc6ff,0xff5cc6ff,0xff3ab9ff,0xff5bc6ff,0xff39b8ff,0xff5bc6ff,0xff38b8ff,0xff37b7ff,0xff59c5ff,
+ 0xff37b7ff,0xff58c3ff,0xff58c3ff,0xff46bcff,0xff34b4ff,0xff56c2ff,0xff57c2ff,0xff33b4ff,0xff55c1ff,0xff33b3ff,0xff32b3ff,0xff54c1ff,0xff31b2ff,0xff65c7ff,
+ 0xff30b1ff,0xff52c0ff,0xff52c0ff,0xff40b8ff,0xff2fb0ff,0xff51bfff,0xff51bdff,0xff2daeff,0xff50bdff,0xff2cadff,0xff4fbdff,0xff2bacff,0xff2bacff,0xff4dbcff,
+ 0xff2aabff,0xff2aacff,0xff28abff,0xff28aaff,0xff4cbbff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27aaff,0xff27a9ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff25a8ff,
+ 0xff49b8ff,0xff24a7ff,0xff48b7ff,0xff34adff,0xff23a4ff,0xff46b5ff,0xff5abfff,0xff21a4ff,0xff46b5ff,0xff45b4ff,0xff20a3ff,0xff20a3ff,0xff43b4ff,0xff1fa2ff,
+ 0xff43b3ff,0xff1ea2ff,0xff1da1ff,0xff1da0ff,0xff41b2ff,0xff1ca0ff,0xff41b1ff,0xff1ba0ff,0xff2ea8ff,0xff2eaaff,0xff2fa9ff,0xff1da1ff,0xff2faaff,0xff42b3ff,
+ 0xff1fa2ff,0xff31abff,0xff50caff,0xff50caff,0xff51caff,0xff51cbff,0xff52cbff,0xff75d6ff,0xff52ccff,0xff53ccff,0xff76d6ff,0xff54cdff,0xff77d7ff,0xff77d8ff,
+ 0xff56ceff,0xff56ceff,0xff78d8ff,0xff79d9ff,0xff7ad9ff,0xff7ad9ff,0xff7ad9ff,0xff7bd9ff,0xff7ad9ff,0xff69d4ff,0xff57cfff,0xff79d9ff,0xff56ceff,0xff78d8ff,
+ 0xff56ceff,0xff55ceff,0xff77d7ff,0xff76d6ff,0xff76d7ff,0xff87dbff,0xff52ccff,0xff75d6ff,0xff74d6ff,0xff51cbff,0xff50cbff,0xff73d5ff,0xff4fcaff,0xff72d4ff,
+ 0xff4fcaff,0xff4ec9ff,0xff71d4ff,0xff4dc8ff,0xff71d3ff,0xff4bc7ff,0xff70d2ff,0xff4bc7ff,0xff4ac7ff,0xff6fd2ff,0xff6ed1ff,0xff48c6ff,0xff6dd1ff,0xff47c5ff,
+ 0xff6cd1ff,0xff46c5ff,0xff46c5ff,0xff6bcfff,0xff6ad0ff,0xff58c9ff,0xff6acfff,0xff44c3ff,0xff44c3ff,0xff69ceff,0xff68cdff,0xff41c1ff,0xff67cdff,0xff41c1ff,
+ 0xff66cdff,0xff40c0ff,0xff3fbfff,0xff66cdff,0xff3ebfff,0xff64cbff,0xff64ccff,0xff3cbeff,0xff3cbeff,0xff63caff,0xff76d1ff,0xff62caff,0xff62caff,0xff3abdff,
+ 0xff61caff,0xff38bbff,0xff38bbff,0xff60c8ff,0xff37baff,0xff4bc1ff,0xff36baff,0xff5ec7ff,0xff35b9ff,0xff34b9ff,0xff34b8ff,0xff33b9ff,0xff32b8ff,0xff33b8ff,
+ 0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff31b7ff,0xff59c5ff,0xff30b5ff,0xff59c5ff,0xff2eb5ff,0xff2eb5ff,0xff58c4ff,0xff57c3ff,0xff2cb4ff,0xff56c3ff,0xff56c2ff,
+ 0xff55c2ff,0xff55c1ff,0xff3fbbff,0xff29b2ff,0xff54c1ff,0xff28b2ff,0xff27b1ff,0xff52c1ff,0xff26b1ff,0xff26b0ff,0xff51bfff,0xff25afff,0xff26afff,0xff26b0ff,
+ 0xff3cb8ff,0xff52c1ff,0xff27b1ff,0xff53c1ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff40bfff,0xff40bdff,0xff41bfff,0xff41bfff,0xff62ccff,0xff41c0ff,0xff42c0ff,
+ 0xff63ccff,0xff43c1ff,0xff63cdff,0xff54c7ff,0xff64ceff,0xff65ceff,0xff56c8ff,0xff66ceff,0xff57c9ff,0xff67cfff,0xff58c9ff,0xff68cfff,0xff68cfff,0xff57c9ff,
+ 0xff67cfff,0xff46c2ff,0xff45c2ff,0xff55c8ff,0xff64ceff,0xff64ceff,0xff64cdff,0xff63cdff,0xff63ccff,0xff74d2ff,0xff42c0ff,0xff41c0ff,0xff62ccff,0xff41bfff,
+ 0xff50c3ff,0xff71d0ff,0xff60cbff,0xff4fc3ff,0xff5fc9ff,0xff5fc9ff,0xff5ec9ff,0xff5ec9ff,0xff3dbbff,0xff3bbbff,0xff4bc1ff,0xff5cc7ff,0xff5cc6ff,0xff5cc6ff,
+ 0xff5bc6ff,0xff5bc6ff,0xff5bc6ff,0xff38b8ff,0xff49bfff,0xff5ac5ff,0xff49bdff,0xff59c5ff,0xff58c3ff,0xff46bcff,0xff58c3ff,0xff35b4ff,0xff35b4ff,0xff57c2ff,
+ 0xff56c2ff,0xff55c2ff,0xff67c8ff,0xff33b2ff,0xff55c1ff,0xff31b2ff,0xff31b2ff,0xff65c7ff,0xff53c0ff,0xff53bfff,0xff52bfff,0xff2fb1ff,0xff2eb0ff,0xff51bfff,
+ 0xff51bdff,0xff51bdff,0xff50bdff,0xff2cadff,0xff3db5ff,0xff4ebcff,0xff3cb4ff,0xff4dbcff,0xff4dbcff,0xff4cbcff,0xff29abff,0xff4cbaff,0xff28aaff,0xff28abff,
+ 0xff27aaff,0xff5dc1ff,0xff38b1ff,0xff27a8ff,0xff38b1ff,0xff5cc0ff,0xff25a8ff,0xff49b8ff,0xff24a7ff,0xff24a7ff,0xff48b8ff,0xff47b7ff,0xff47b7ff,0xff33adff,
+ 0xff46b5ff,0xff21a4ff,0xff45b5ff,0xff32acff,0xff44b4ff,0xff44b3ff,0xff31abff,0xff1fa2ff,0xff43b3ff,0xff42b3ff,0xff1da1ff,0xff41b2ff,0xff1ca0ff,0xff1ca0ff,
+ 0xff41b2ff,0xff41b1ff,0xff41b1ff,0xff2ea9ff,0xff41b3ff,0xff41b3ff,0xff30aaff,0xff43b3ff,0xff43b3ff,0xff43b3ff,0xff50caff,0xff50caff,0xff51cbff,0xff51cbff,
+ 0xff74d6ff,0xff52cbff,0xff53ccff,0xff53ccff,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff27b0ff,0xff27b1ff,0xff29b1ff,0xff28b2ff,0xff29b3ff,
+ 0xff40bdff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff000000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff000000,0xff1da1ff,
+ 0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff20a2ff,0xff50caff,0xff50caff,0xff51cbff,0xff51cbff,0xff63d0ff,0xff75d6ff,0xff64d0ff,0xff53ccff,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,0xff000000,
+ 0xff000000,0xff000000,0xff000000,0xff27b1ff,0xff28b2ff,0xff28b1ff,0xff54c1ff,0xff54c1ff,0xff40bcff,0xff40bdff,0xff40bfff,0xff41bdff,0xff62ccff,0xff41bfff,
+ 0xff51c6ff,0xff52c6ff,0xff63cdff,0xff43c1ff,0xff63cdff,0xff54c7ff,0xff54c7ff,0xff55c8ff,0xff56c8ff,0xff67ceff,0xff47c3ff,0xff67cfff,0xff67cfff,0xff49c5ff,
+ 0xff68cfff,0xff48c5ff,0xff67cfff,0xff46c3ff,0xff66ceff,0xff65cfff,0xff45c2ff,0xff44c1ff,0xff64cdff,0xff63cdff,0xff42c1ff,0xff42c0ff,0xff41c0ff,0xff41bfff,
+ 0xff41bfff,0xff41bfff,0xff61cbff,0xff40bdff,0xff60c9ff,0xff5fcbff,0xff3ebcff,0xff3ebcff,0xff5ec9ff,0xff5ec8ff,0xff3dbbff,0xff5cc8ff,0xff5dc8ff,0xff3bbaff,
+ 0xff3bb9ff,0xff5cc6ff,0xff5bc6ff,0xff3ab9ff,0xff39b9ff,0xff5ac6ff,0xff39b8ff,0xff38b7ff,0xff59c6ff,0xff59c5ff,0xff36b5ff,0xff58c5ff,0xff58c2ff,0xff35b4ff,
+ 0xff34b4ff,0xff56c2ff,0xff34b4ff,0xff56c1ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff53c0ff,0xff30b1ff,0xff2fb1ff,0xff2fb1ff,0xff51bfff,
+ 0xff51bfff,0xff2eb0ff,0xff51bdff,0xff2eaeff,0xff2dadff,0xff2cadff,0xff4fbdff,0xff4ebcff,0xff2aadff,0xff2bacff,0xff2aacff,0xff2aabff,0xff29abff,0xff29abff,
+ 0xff28aaff,0xff28aaff,0xff4bb9ff,0xff28a9ff,0xff4ab9ff,0xff49b9ff,0xff26a8ff,0xff25a8ff,0xff49b8ff,0xff49b8ff,0xff24a7ff,0xff48b8ff,0xff48b8ff,0xff23a5ff,
+ 0xff23a5ff,0xff46b7ff,0xff46b7ff,0xff33adff,0xff32adff,0xff33acff,0xff32acff,0xff32acff,0xff31acff,0xff43b3ff,0xff1ea1ff,0xff42b3ff,0xff41b3ff,0xff1da1ff,
+ 0xff1ca0ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,0xff1ca0ff,0xff1ca0ff,0xff41b3ff,0xff1da1ff,0xff1ea1ff,0xff1ea2ff,0xff42b3ff,0xff43b3ff,0xff50caff,0xff50caff,
+ 0xff50cbff,0xff51cbff,0xff75d6ff,0xff52cbff,0xff53ccff,0xff76d6ff,0xff76d7ff,0xff54cdff,0xff76d7ff,0xff77d8ff,0xff55ceff,0xff56ceff,0xff79d8ff,0xff7ad9ff,
+ 0xff58cfff,0xff58cfff,0xff7bd9ff,0xff7bd9ff,0xff59d0ff,0xff59cfff,0xff7ad9ff,0xff57cfff,0xff78d8ff,0xff78d8ff,0xff55ceff,0xff55ceff,0xff55ceff,0xff87dcff,
+ 0xff76d7ff,0xff53ccff,0xff52cbff,0xff52ccff,0xff51cbff,0xff51cbff,0xff84daff,0xff73d6ff,0xff61cfff,0xff72d5ff,0xff4fc9ff,0xff4ec9ff,0xff71d4ff,0xff71d4ff,
+ 0xff4cc8ff,0xff4cc7ff,0xff70d2ff,0xff4bc7ff,0xff4ac7ff,0xff6fd2ff,0xff80d7ff,0xff6ed1ff,0xff48c6ff,0xff6dd1ff,0xff48c4ff,0xff47c4ff,0xff6bd0ff,0xff6bcfff,
+ 0xff45c4ff,0xff6acfff,0xff6acfff,0xff44c3ff,0xff44c3ff,0xff68ceff,0xff42c2ff,0xff68ceff,0xff41c1ff,0xff54c7ff,0xff66cdff,0xff66cdff,0xff52c6ff,0xff3fbfff,
+ 0xff65ccff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3cbeff,0xff3bbeff,0xff62caff,0xff3abdff,0xff39bcff,0xff39bcff,0xff39bcff,0xff38bbff,0xff37bbff,
+ 0xff36bbff,0xff37bbff,0xff36baff,0xff35baff,0xff34b9ff,0xff34b9ff,0xff5dc6ff,0xff33b9ff,0xff5cc6ff,0xff5cc5ff,0xff31b8ff,0xff32b7ff,0xff5ac5ff,0xff5ac5ff,
+ 0xff30b6ff,0xff5ac5ff,0xff58c5ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff6ccbff,0xff41bcff,0xff2cb4ff,0xff56c3ff,0xff2bb3ff,0xff2ab3ff,0xff55c2ff,0xff54c1ff,
+ 0xff29b2ff,0xff28b1ff,0xff53c1ff,0xff52c1ff,0xff3db8ff,0xff26b1ff,0xff52c0ff,0xff51bfff,0xff52c0ff,0xff26b0ff,0xff52c0ff,0xff27b1ff,0xff27b1ff,0xff28b2ff,
+ 0xff29b2ff,0xff29b2ff,0xff40bdff,0xff50c3ff,0xff61ccff,0xff61ccff,0xff62ccff,0xff41c0ff,0xff42c0ff,0xff63ccff,0xff74d2ff,0xff63ccff,0xff54c7ff,0xff64ceff,
+ 0xff65ceff,0xff65cfff,0xff65ceff,0xff66cfff,0xff47c3ff,0xff47c3ff,0xff68cfff,0xff59cbff,0xff57c9ff,0xff47c5ff,0xff76d4ff,0xff66cfff,0xff76d4ff,0xff65ceff,
+ 0xff45c2ff,0xff64ceff,0xff64cdff,0xff63cdff,0xff42c0ff,0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff60cbff,0xff40bdff,0xff5fcbff,0xff5fcbff,
+ 0xff3fbcff,0xff3ebbff,0xff5fc8ff,0xff5ec9ff,0xff4cc1ff,0xff6ecfff,0xff5cc7ff,0xff5cc7ff,0xff6dceff,0xff3abaff,0xff5bc6ff,0xff3ab8ff,0xff39b8ff,0xff5bc6ff,
+ 0xff5ac6ff,0xff5ac6ff,0xff38b7ff,0xff59c5ff,0xff36b7ff,0xff58c3ff,0xff58c2ff,0xff58c3ff,0xff69c9ff,0xff34b4ff,0xff33b3ff,0xff56c2ff,0xff33b3ff,0xff42baff,
+ 0xff54c1ff,0xff54c1ff,0xff41b9ff,0xff30b2ff,0xff53c0ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff51bdff,0xff2daeff,0xff2cadff,
+ 0xff2cadff,0xff2badff,0xff2bacff,0xff2aacff,0xff2aacff,0xff29abff,0xff28abff,0xff4cbaff,0xff4cbaff,0xff39b2ff,0xff4bb9ff,0xff27a9ff,0xff4ab9ff,0xff49b9ff,
+ 0xff49b8ff,0xff49b8ff,0xff25a8ff,0xff5bc0ff,0xff49b8ff,0xff5bc0ff,0xff48b8ff,0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff46b5ff,0xff46b5ff,0xff20a4ff,0xff45b4ff,
+ 0xff44b4ff,0xff44b3ff,0xff43b3ff,0xff43b3ff,0xff31abff,0xff57bcff,0xff42b3ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,0xff41b1ff,0xff41b2ff,0xff41b2ff,0xff1ca0ff,
+ 0xff2faaff,0xff2faaff,0xff1da1ff,0xff1fa1ff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff50caff,0xff51cbff,0xff75d6ff,0xff52ccff,0xff63d1ff,0xff64d1ff,
+ 0xff76d7ff,0xff54ccff,0xff55cdff,0xff77d7ff,0xff56cdff,0xff56ceff,0xff78d9ff,0xff79d8ff,0xff58cfff,0xff7ad9ff,0xff7bd9ff,0xff5acfff,0xff69d5ff,0xff69d5ff,
+ 0xff7ad9ff,0xff57cfff,0xff79d9ff,0xff78d8ff,0xff56ceff,0xff66d2ff,0xff77d7ff,0xff76d7ff,0xff53cdff,0xff53ccff,0xff53ccff,0xff52ccff,0xff52cbff,0xff51cbff,
+ 0xff74d6ff,0xff50caff,0xff73d5ff,0xff72d5ff,0xff4fc9ff,0xff4ec9ff,0xff71d3ff,0xff71d4ff,0xff4dc8ff,0xff81d9ff,0xff6fd2ff,0xff4ac7ff,0xff5dcdff,0xff5ccdff,
+ 0xff6ed1ff,0xff49c5ff,0xff48c6ff,0xff6dd1ff,0xff48c5ff,0xff47c4ff,0xff46c4ff,0xff6bd0ff,0xff46c4ff,0xff6acfff,0xff6acfff,0xff44c2ff,0xff56c8ff,0xff56c8ff,
+ 0xff42c1ff,0xff68cdff,0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff40c0ff,0xff3fbfff,0xff3fc0ff,0xff51c5ff,0xff51c5ff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3cbdff,
+ 0xff3bbdff,0xff4fc4ff,0xff4ec3ff,0xff3abdff,0xff39bbff,0xff39bcff,0xff38bbff,0xff37bbff,0xff37baff,0xff37baff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff34b9ff,
+ 0xff5dc6ff,0xff34b8ff,0xff5cc6ff,0xff5bc6ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff5ac5ff,0xff30b6ff,0xff59c5ff,0xff58c4ff,0xff2eb5ff,0xff2eb4ff,0xff57c4ff,
+ 0xff57c3ff,0xff2cb4ff,0xff57c3ff,0xff56c2ff,0xff2bb3ff,0xff2ab2ff,0xff54c1ff,0xff54c2ff,0xff28b2ff,0xff68c8ff,0xff53c1ff,0xff27b0ff,0xff27b1ff,0xff26b0ff,
+ 0xff26b0ff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff52c1ff,0xff27b1ff,0xff29b2ff,0xff28b1ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff41bfff,0xff41bfff,
+ 0xff50c5ff,0xff62ccff,0xff52c5ff,0xff42c0ff,0xff52c7ff,0xff43c0ff,0xff43c1ff,0xff54c8ff,0xff45c1ff,0xff45c2ff,0xff56c9ff,0xff57c9ff,0xff67cfff,0xff58cbff,
+ 0xff58c9ff,0xff48c5ff,0xff48c3ff,0xff58c9ff,0xff57c9ff,0xff46c3ff,0xff56c9ff,0xff45c2ff,0xff65ceff,0xff54c7ff,0xff54c7ff,0xff63cdff,0xff63ccff,0xff63ccff,
+ 0xff42c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff61ccff,0xff60ccff,0xff3fbdff,0xff3fbdff,0xff5fc9ff,0xff5fc9ff,0xff3dbcff,0xff4dc1ff,0xff5dc8ff,0xff4cc1ff,
+ 0xff4cc1ff,0xff3bbaff,0xff3ab9ff,0xff4ac0ff,0xff5cc6ff,0xff5bc6ff,0xff5bc6ff,0xff49bfff,0xff38b7ff,0xff38b7ff,0xff37b8ff,0xff48bdff,0xff58c5ff,0xff47bcff,
+ 0xff47bcff,0xff35b5ff,0xff34b5ff,0xff45bbff,0xff33b4ff,0xff44baff,0xff33b3ff,0xff33b2ff,0xff32b3ff,0xff31b2ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff52c0ff,
+ 0xff30b0ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2dadff,0xff50bdff,0xff2cadff,0xff2cadff,0xff2cacff,0xff2badff,0xff2babff,0xff2aabff,0xff29abff,
+ 0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff4bbaff,0xff4bb9ff,0xff27a9ff,0xff38b0ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff36aeff,0xff24a7ff,0xff35aeff,
+ 0xff24a7ff,0xff47b7ff,0xff47b7ff,0xff22a5ff,0xff33adff,0xff21a4ff,0xff33adff,0xff32acff,0xff20a3ff,0xff20a2ff,0xff31acff,0xff31abff,0xff43b3ff,0xff30aaff,
+ 0xff30aaff,0xff41b3ff,0xff41b2ff,0xff2eaaff,0xff1ba0ff,0xff1ba0ff,0xff1ba0ff,0xff1da1ff,0xff1da0ff,0xff2faaff,0xff30abff,0xff1ea2ff,0xff1fa2ff,0xff1fa2ff,
+ 0xff4fcaff,0xff50caff,0xff50cbff,0xff51cbff,0xff52ccff,0xff52ccff,0xff52cbff,0xff53ccff,0xff54ccff,0xff54cdff,0xff55cdff,0xff55ceff,0xff55ceff,0xff56ceff,
+ 0xff57cfff,0xff57cfff,0xff58cfff,0xff58cfff,0xff59d0ff,0xff59d0ff,0xff59cfff,0xff58cfff,0xff57cfff,0xff57ceff,0xff57cfff,0xff56ceff,0xff56cdff,0xff56cdff,
+ 0xff54cdff,0xff54cdff,0xff53cdff,0xff53ccff,0xff63d1ff,0xff75d6ff,0xff75d6ff,0xff62d0ff,0xff50caff,0xff50caff,0xff4fcaff,0xff4fcaff,0xff4ec9ff,0xff4ec8ff,
+ 0xff4ec9ff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff4bc8ff,0xff4bc7ff,0xff4bc7ff,0xff4ac6ff,0xff4ac6ff,0xff49c5ff,0xff48c5ff,0xff47c5ff,0xff47c5ff,0xff47c4ff,
+ 0xff46c4ff,0xff46c4ff,0xff45c3ff,0xff45c3ff,0xff44c3ff,0xff43c3ff,0xff43c2ff,0xff43c2ff,0xff42c1ff,0xff42c1ff,0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff40c1ff,
+ 0xff3fc0ff,0xff3fbfff,0xff3ec0ff,0xff50c5ff,0xff3dbfff,0xff3cbeff,0xff3cbdff,0xff3cbdff,0xff3bbdff,0xff3bbdff,0xff4ec4ff,0xff3abcff,0xff39bcff,0xff39bbff,
+ 0xff38bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff36baff,0xff36baff,0xff34b9ff,0xff34b9ff,0xff34b9ff,0xff34b8ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,
+ 0xff31b7ff,0xff30b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb6ff,0xff2fb5ff,0xff2db5ff,0xff2db5ff,0xff2db4ff,0xff2cb4ff,0xff2cb3ff,0xff2bb4ff,0xff2ab3ff,0xff2ab3ff,
+ 0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff26b0ff,0xff25afff,0xff25b0ff,0xff26b0ff,0xff26b1ff,0xff28b1ff,
+ 0xff3db9ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff43c1ff,0xff43c0ff,
+ 0xff44c1ff,0xff44c1ff,0xff55c8ff,0xff55c8ff,0xff46c3ff,0xff46c3ff,0xff46c3ff,0xff47c5ff,0xff48c3ff,0xff49c5ff,0xff48c5ff,0xff47c3ff,0xff47c3ff,0xff46c3ff,
+ 0xff45c3ff,0xff45c2ff,0xff45c1ff,0xff44c2ff,0xff44c1ff,0xff43c0ff,0xff43c0ff,0xff42c1ff,0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff40bfff,0xff40bdff,
+ 0xff3fbdff,0xff3fbcff,0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff3dbcff,0xff3dbbff,0xff3cbbff,0xff3bbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,
+ 0xff39b8ff,0xff39b8ff,0xff39b8ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,0xff36b7ff,0xff35b5ff,0xff35b5ff,0xff35b5ff,0xff34b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,
+ 0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff31b1ff,0xff31b2ff,0xff30b1ff,0xff41b8ff,0xff2fb1ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,
+ 0xff2dadff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2aacff,0xff2aabff,0xff2aacff,0xff29abff,0xff29abff,0xff28aaff,0xff3ab2ff,0xff28aaff,0xff27a9ff,
+ 0xff26a9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff25a7ff,0xff25a7ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a7ff,0xff22a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,
+ 0xff21a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff31abff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1da0ff,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,
+ 0xff1b9fff,0xff1da0ff,0xff1ca1ff,0xff1da0ff,0xff1ea1ff,0xff1ea2ff,0xff1fa1ff,0xff1fa2ff,0xff4fcaff,0xff50cbff,0xff50caff,0xff51cbff,0xff52cbff,0xff52ccff,
+ 0xff52ccff,0xff53ccff,0xff54cdff,0xff54ccff,0xff54cdff,0xff55ceff,0xff77d7ff,0xff78d8ff,0xff57ceff,0xff57cfff,0xff57cfff,0xff58cfff,0xff59d0ff,0xff6ad5ff,
+ 0xff7bd9ff,0xff69d4ff,0xff58cfff,0xff57cfff,0xff57ceff,0xff56ceff,0xff66d3ff,0xff77d7ff,0xff55cdff,0xff54cdff,0xff54ccff,0xff53ccff,0xff52ccff,0xff52cbff,
+ 0xff52cbff,0xff51cbff,0xff51caff,0xff73d5ff,0xff4fcaff,0xff4fcaff,0xff4fc9ff,0xff4ec9ff,0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,0xff4bc8ff,0xff4bc7ff,
+ 0xff4bc7ff,0xff49c7ff,0xff4ac6ff,0xff49c5ff,0xff48c5ff,0xff48c5ff,0xff47c5ff,0xff47c4ff,0xff47c5ff,0xff46c4ff,0xff45c4ff,0xff45c4ff,0xff45c3ff,0xff6acfff,
+ 0xff43c2ff,0xff42c1ff,0xff68ceff,0xff41c1ff,0xff41c1ff,0xff41c1ff,0xff40c1ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff64cbff,0xff64cbff,0xff3dbfff,
+ 0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff3abcff,0xff39bcff,0xff38bbff,0xff38bbff,0xff38bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff35baff,
+ 0xff48c1ff,0xff48c0ff,0xff34b9ff,0xff34b9ff,0xff5cc7ff,0xff32b8ff,0xff31b7ff,0xff31b8ff,0xff31b7ff,0xff30b7ff,0xff2fb7ff,0xff2fb6ff,0xff2fb6ff,0xff2eb5ff,
+ 0xff58c4ff,0xff2db4ff,0xff2cb5ff,0xff2cb4ff,0xff57c3ff,0xff2cb3ff,0xff2ab3ff,0xff3fbbff,0xff3fbbff,0xff29b2ff,0xff28b1ff,0xff53c1ff,0xff28b2ff,0xff28b1ff,
+ 0xff27b0ff,0xff26b0ff,0xff26b0ff,0xff51c0ff,0xff25b0ff,0xff26b1ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff50c3ff,
+ 0xff61ccff,0xff50c5ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42c0ff,0xff42c0ff,0xff43c0ff,0xff44c1ff,0xff44c1ff,0xff55c7ff,0xff55c8ff,0xff45c2ff,0xff47c3ff,
+ 0xff47c2ff,0xff47c5ff,0xff48c3ff,0xff68cfff,0xff48c3ff,0xff47c5ff,0xff57c9ff,0xff67cfff,0xff56c8ff,0xff46c2ff,0xff45c2ff,0xff64ceff,0xff44c1ff,0xff53c7ff,
+ 0xff42c0ff,0xff52c6ff,0xff42c0ff,0xff62ccff,0xff51c5ff,0xff50c3ff,0xff41bdff,0xff60ccff,0xff3fbdff,0xff4fc2ff,0xff4fc3ff,0xff5fc9ff,0xff3ebbff,0xff3dbbff,
+ 0xff3cbbff,0xff3cbbff,0xff3bbaff,0xff5cc7ff,0xff5cc7ff,0xff3ab9ff,0xff3ab9ff,0xff3ab8ff,0xff39b8ff,0xff49bfff,0xff49bfff,0xff5ac6ff,0xff37b7ff,0xff48bdff,
+ 0xff59c5ff,0xff47bcff,0xff46bcff,0xff68cbff,0xff57c3ff,0xff34b4ff,0xff56c1ff,0xff56c2ff,0xff43baff,0xff42baff,0xff54c1ff,0xff54c1ff,0xff41b9ff,0xff30b1ff,
+ 0xff41b8ff,0xff41b8ff,0xff52bfff,0xff40b8ff,0xff51bdff,0xff2eb0ff,0xff3fb7ff,0xff50bdff,0xff3eb7ff,0xff2cadff,0xff4fbdff,0xff3cb4ff,0xff2bacff,0xff3cb4ff,
+ 0xff4dbbff,0xff3bb3ff,0xff29abff,0xff28abff,0xff4cbbff,0xff28aaff,0xff38b2ff,0xff4abaff,0xff4ab9ff,0xff27a8ff,0xff49b8ff,0xff49b8ff,0xff25a8ff,0xff36b0ff,
+ 0xff24a7ff,0xff35aeff,0xff24a7ff,0xff34adff,0xff33adff,0xff22a5ff,0xff33adff,0xff46b5ff,0xff46b5ff,0xff20a4ff,0xff20a3ff,0xff44b3ff,0xff1fa2ff,0xff31abff,
+ 0xff43b3ff,0xff42b3ff,0xff1ea1ff,0xff41b3ff,0xff41b2ff,0xff1ca0ff,0xff41b2ff,0xff55bbff,0xff2ea9ff,0xff1ca0ff,0xff41b2ff,0xff2faaff,0xff30abff,0xff30aaff,
+ 0xff42b3ff,0xff31abff,0xff50caff,0xff73d5ff,0xff50cbff,0xff62d0ff,0xff52cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff53cdff,0xff55cdff,0xff55cdff,0xff56cdff,
+ 0xff56cdff,0xff57ceff,0xff56ceff,0xff68d4ff,0xff79d9ff,0xff7ad9ff,0xff6ad5ff,0xff8bdeff,0xff7bd9ff,0xff58cfff,0xff8addff,0xff57cfff,0xff79d8ff,0xff56ceff,
+ 0xff56cdff,0xff77d7ff,0xff55cdff,0xff76d7ff,0xff54cdff,0xff76d7ff,0xff76d6ff,0xff52cbff,0xff75d6ff,0xff51cbff,0xff50caff,0xff73d5ff,0xff4fcaff,0xff72d5ff,
+ 0xff61ceff,0xff4ec9ff,0xff72d3ff,0xff5fceff,0xff71d3ff,0xff70d2ff,0xff6fd2ff,0xff4bc7ff,0xff4ac7ff,0xff5ccdff,0xff5bccff,0xff6ed1ff,0xff6ed1ff,0xff6dd1ff,
+ 0xff5acbff,0xff46c5ff,0xff6bd0ff,0xff59caff,0xff45c3ff,0xff6ad0ff,0xff45c3ff,0xff6aceff,0xff44c2ff,0xff43c1ff,0xff7bd4ff,0xff42c1ff,0xff67cdff,0xff40c0ff,
+ 0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff65ccff,0xff3ebfff,0xff64ccff,0xff50c5ff,0xff3cbeff,0xff63caff,0xff63caff,0xff3abcff,0xff62caff,0xff3abcff,
+ 0xff61caff,0xff60caff,0xff5fc9ff,0xff5fc9ff,0xff37baff,0xff5ec8ff,0xff36baff,0xff35baff,0xff5ec7ff,0xff34b9ff,0xff5dc7ff,0xff33b8ff,0xff6fcdff,0xff47beff,
+ 0xff32b7ff,0xff31b7ff,0xff5ac5ff,0xff5ac5ff,0xff30b7ff,0xff59c4ff,0xff2fb6ff,0xff2eb5ff,0xff58c4ff,0xff2eb4ff,0xff57c3ff,0xff2cb4ff,0xff6bcbff,0xff2bb3ff,
+ 0xff2bb3ff,0xff55c2ff,0xff29b2ff,0xff54c1ff,0xff29b1ff,0xff68c8ff,0xff52c1ff,0xff27b1ff,0xff27b1ff,0xff52c0ff,0xff25b0ff,0xff51bfff,0xff25b0ff,0xff52c0ff,
+ 0xff26b0ff,0xff52c0ff,0xff28b1ff,0xff68c9ff,0xff29b2ff,0xff54c1ff,0xff3fbdff,0xff60cbff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42c0ff,
+ 0xff43c1ff,0xff43c1ff,0xff44c1ff,0xff44c2ff,0xff44c2ff,0xff45c2ff,0xff46c2ff,0xff46c2ff,0xff47c3ff,0xff47c5ff,0xff48c3ff,0xff68cfff,0xff48c5ff,0xff47c3ff,
+ 0xff67cfff,0xff46c3ff,0xff66ceff,0xff45c2ff,0xff44c1ff,0xff64cdff,0xff44c1ff,0xff63cdff,0xff42c1ff,0xff63ccff,0xff52c6ff,0xff62ccff,0xff62ccff,0xff41bfff,
+ 0xff41bfff,0xff60cbff,0xff40bcff,0xff5fcbff,0xff3fbcff,0xff3ebcff,0xff5ec8ff,0xff3dbbff,0xff3dbbff,0xff3cbbff,0xff5dc8ff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,
+ 0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff5bc6ff,0xff38b8ff,0xff38b8ff,0xff5ac5ff,0xff59c3ff,0xff58c3ff,0xff6acbff,0xff35b5ff,0xff58c3ff,0xff34b5ff,0xff34b4ff,
+ 0xff56c1ff,0xff33b4ff,0xff55c1ff,0xff43b9ff,0xff54c1ff,0xff54c1ff,0xff41b9ff,0xff30b1ff,0xff54c0ff,0xff2fb0ff,0xff52c0ff,0xff2fb0ff,0xff2eaeff,0xff51bfff,
+ 0xff51bdff,0xff2eaeff,0xff50bdff,0xff2cadff,0xff4fbdff,0xff4fbdff,0xff4ebcff,0xff60c3ff,0xff4dbcff,0xff4dbcff,0xff29abff,0xff4cbbff,0xff28abff,0xff28aaff,
+ 0xff4abaff,0xff28aaff,0xff4ab9ff,0xff38b1ff,0xff49b8ff,0xff49b8ff,0xff49b8ff,0xff24a7ff,0xff49b8ff,0xff48b8ff,0xff23a7ff,0xff23a5ff,0xff46b7ff,0xff22a5ff,
+ 0xff46b5ff,0xff21a4ff,0xff46b5ff,0xff20a3ff,0xff45b4ff,0xff20a2ff,0xff20a3ff,0xff43b3ff,0xff1ea2ff,0xff42b3ff,0xff41b3ff,0xff1da1ff,0xff1ca0ff,0xff41b2ff,
+ 0xff1ba0ff,0xff41b1ff,0xff1ba0ff,0xff2eaaff,0xff41b3ff,0xff41b2ff,0xff1ea1ff,0xff42b3ff,0xff1ea2ff,0xff44b3ff,0xff50c9ff,0xff73d5ff,0xff74d5ff,0xff74d6ff,
+ 0xff51cbff,0xff52cbff,0xff53cbff,0xff53ccff,0xff53ccff,0xff54ccff,0xff54ceff,0xff56ceff,0xff56cdff,0xff56ceff,0xff56ceff,0xff57cfff,0xff58cfff,0xff58cfff,
+ 0xff59d0ff,0xff7bd9ff,0xff59cfff,0xff58cfff,0xff8addff,0xff7ad9ff,0xff79d9ff,0xff56ceff,0xff78d8ff,0xff88dcff,0xff66d2ff,0xff76d6ff,0xff76d6ff,0xff87dbff,
+ 0xff63d1ff,0xff75d6ff,0xff75d6ff,0xff51cbff,0xff62d0ff,0xff84daff,0xff72d5ff,0xff72d4ff,0xff4ec9ff,0xff4ec9ff,0xff71d4ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,
+ 0xff5ecdff,0xff6fd2ff,0xff6fd2ff,0xff5ccdff,0xff4ac6ff,0xff49c6ff,0xff49c5ff,0xff6cd1ff,0xff6cd1ff,0xff6bd1ff,0xff59cbff,0xff6bd0ff,0xff6ad0ff,0xff7dd5ff,
+ 0xff44c3ff,0xff57c9ff,0xff6aceff,0xff55c8ff,0xff68cdff,0xff42c1ff,0xff67cdff,0xff41c1ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff65cdff,0xff3ebfff,0xff3ebfff,
+ 0xff64ccff,0xff3dbfff,0xff3cbeff,0xff63caff,0xff63cbff,0xff62caff,0xff62caff,0xff3abcff,0xff61caff,0xff4cc2ff,0xff60c9ff,0xff60c9ff,0xff5fc9ff,0xff5fc8ff,
+ 0xff36baff,0xff5ec8ff,0xff35b9ff,0xff34b9ff,0xff5dc7ff,0xff5cc7ff,0xff70cdff,0xff47bfff,0xff5bc6ff,0xff5ac5ff,0xff5ac5ff,0xff31b6ff,0xff5ac5ff,0xff2fb6ff,
+ 0xff2fb6ff,0xff58c4ff,0xff6ccbff,0xff42bcff,0xff57c4ff,0xff57c3ff,0xff6bcaff,0xff2cb3ff,0xff56c2ff,0xff2ab3ff,0xff29b2ff,0xff54c1ff,0xff54c1ff,0xff68c8ff,
+ 0xff3eb9ff,0xff52c1ff,0xff52c0ff,0xff3cb8ff,0xff25b0ff,0xff51c0ff,0xff51c0ff,0xff3cb8ff,0xff52c0ff,0xff52c1ff,0xff27b1ff,0xff53c1ff,0xff28b2ff,0xff54c1ff,
+ 0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff43c1ff,0xff44c1ff,0xff44c2ff,0xff45c2ff,0xff45c2ff,
+ 0xff46c2ff,0xff46c3ff,0xff47c3ff,0xff47c3ff,0xff48c5ff,0xff48c5ff,0xff48c3ff,0xff47c3ff,0xff67cfff,0xff46c3ff,0xff46c3ff,0xff45c2ff,0xff44c2ff,0xff44c2ff,
+ 0xff44c2ff,0xff43c1ff,0xff42c1ff,0xff42c0ff,0xff51c6ff,0xff62ccff,0xff61ccff,0xff51c5ff,0xff40bfff,0xff40bdff,0xff3fbdff,0xff3fbdff,0xff3fbdff,0xff3ebcff,
+ 0xff3dbcff,0xff3dbbff,0xff3cbaff,0xff3cbaff,0xff3cbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff5bc6ff,0xff38b8ff,0xff38b7ff,
+ 0xff38b7ff,0xff37b7ff,0xff37b7ff,0xff36b7ff,0xff36b5ff,0xff35b5ff,0xff35b4ff,0xff33b3ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff32b2ff,0xff32b2ff,
+ 0xff31b1ff,0xff54c1ff,0xff30b1ff,0xff30b0ff,0xff30b0ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2bacff,
+ 0xff2badff,0xff2aabff,0xff2aacff,0xff29acff,0xff4cbbff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a9ff,0xff25a8ff,
+ 0xff25a8ff,0xff25a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff23a5ff,0xff23a5ff,0xff22a4ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff45b5ff,0xff20a3ff,0xff20a2ff,
+ 0xff20a2ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1da0ff,0xff1ca0ff,0xff1ba0ff,0xff1b9fff,0xff1c9fff,0xff2ea9ff,0xff41b2ff,0xff41b2ff,
+ 0xff30aaff,0xff1ea1ff,0xff1fa1ff,0xff1fa2ff,0xff4fcaff,0xff50cbff,0xff51cbff,0xff51caff,0xff51cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff53cdff,0xff55cdff,
+ 0xff55cdff,0xff55cdff,0xff55ceff,0xff56ceff,0xff57ceff,0xff58ceff,0xff58cfff,0xff59cfff,0xff59d0ff,0xff59d0ff,0xff59d0ff,0xff58d0ff,0xff58cfff,0xff57cfff,
+ 0xff57ceff,0xff56ceff,0xff55ceff,0xff55ceff,0xff54cdff,0xff54cdff,0xff54ccff,0xff53ccff,0xff53cbff,0xff52ccff,0xff51cbff,0xff51caff,0xff51caff,0xff51caff,
+ 0xff4fcaff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,0xff4ec8ff,0xff4cc8ff,0xff4dc8ff,0xff4cc8ff,0xff4cc7ff,0xff4bc7ff,0xff4ac7ff,0xff4ac7ff,0xff49c6ff,0xff49c6ff,
+ 0xff48c5ff,0xff48c5ff,0xff47c5ff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,0xff43c3ff,0xff43c2ff,0xff42c1ff,0xff42c1ff,
+ 0xff41c1ff,0xff41c0ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff3ec0ff,0xff3ebeff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3cbdff,0xff3bbeff,0xff3bbdff,
+ 0xff3abcff,0xff3abcff,0xff39bcff,0xff38bbff,0xff38bcff,0xff38bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff35baff,0xff35b9ff,0xff35b9ff,0xff34b8ff,0xff34b8ff,
+ 0xff32b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,0xff31b6ff,0xff30b7ff,0xff30b7ff,0xff30b6ff,0xff2fb6ff,0xff2eb6ff,0xff2db5ff,0xff2db5ff,0xff2db5ff,0xff2cb4ff,
+ 0xff2bb4ff,0xff2cb3ff,0xff2bb3ff,0xff2ab2ff,0xff2ab2ff,0xff29b2ff,0xff29b1ff,0xff29b1ff,0xff28b1ff,0xff28b1ff,0xff27b0ff,0xff26b1ff,0xff26afff,0xff25b0ff,
+ 0xff26afff,0xff26b1ff,0xff26b0ff,0xff27b1ff,0xff28b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff60cbff,0xff61cbff,0xff41bfff,0xff41bfff,
+ 0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff53c6ff,0xff53c7ff,0xff44c2ff,0xff45c1ff,0xff45c2ff,0xff45c3ff,0xff46c3ff,0xff46c3ff,0xff47c3ff,0xff47c3ff,0xff48c5ff,
+ 0xff47c5ff,0xff47c5ff,0xff47c3ff,0xff46c3ff,0xff46c3ff,0xff46c2ff,0xff45c2ff,0xff44c2ff,0xff44c1ff,0xff43c1ff,0xff42c1ff,0xff42c0ff,0xff42c0ff,0xff51c5ff,
+ 0xff41bfff,0xff41bfff,0xff50c5ff,0xff40bdff,0xff3fbdff,0xff3fbdff,0xff3ebdff,0xff3ebcff,0xff3ebcff,0xff3dbbff,0xff3cbbff,0xff5dc8ff,0xff4cc1ff,0xff3bbaff,
+ 0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff38b8ff,0xff38b8ff,0xff38b8ff,0xff38b8ff,0xff36b7ff,0xff36b7ff,0xff36b5ff,0xff35b5ff,0xff35b5ff,
+ 0xff34b4ff,0xff56c2ff,0xff33b4ff,0xff33b3ff,0xff43baff,0xff32b3ff,0xff32b3ff,0xff31b2ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2fb0ff,
+ 0xff40b8ff,0xff2eb0ff,0xff2eaeff,0xff2daeff,0xff3eb7ff,0xff2cadff,0xff2cadff,0xff2bacff,0xff4ebdff,0xff2bacff,0xff2aacff,0xff3bb3ff,0xff29abff,0xff28aaff,
+ 0xff28abff,0xff28aaff,0xff28aaff,0xff39b2ff,0xff26a9ff,0xff26a9ff,0xff26a9ff,0xff25a8ff,0xff24a7ff,0xff25a7ff,0xff24a8ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,
+ 0xff23a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff46b5ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,
+ 0xff1da0ff,0xff1ca0ff,0xff1ba0ff,0xff2ea8ff,0xff1ca0ff,0xff1ca0ff,0xff41b2ff,0xff41b2ff,0xff1da1ff,0xff1ea1ff,0xff1fa2ff,0xff44b3ff,0xff4fcaff,0xff50caff,
+ 0xff73d6ff,0xff74d6ff,0xff52ccff,0xff52ccff,0xff52ccff,0xff53ccff,0xff54ccff,0xff76d6ff,0xff66d2ff,0xff55ceff,0xff56ceff,0xff56ceff,0xff56ceff,0xff58ceff,
+ 0xff58cfff,0xff58cfff,0xff59d0ff,0xff59d0ff,0xff58cfff,0xff58cfff,0xff58cfff,0xff57cfff,0xff56cfff,0xff56ceff,0xff55ceff,0xff55ceff,0xff54cdff,0xff55cdff,
+ 0xff53cdff,0xff53ccff,0xff52cbff,0xff75d6ff,0xff52cbff,0xff51cbff,0xff74d6ff,0xff50caff,0xff50c9ff,0xff4fcaff,0xff4fcaff,0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,
+ 0xff4dc8ff,0xff70d3ff,0xff70d3ff,0xff4bc7ff,0xff4bc7ff,0xff49c7ff,0xff4ac6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff47c4ff,0xff47c4ff,0xff46c4ff,
+ 0xff45c3ff,0xff45c4ff,0xff44c3ff,0xff44c3ff,0xff69cfff,0xff43c2ff,0xff42c2ff,0xff42c1ff,0xff67cdff,0xff41c1ff,0xff40c0ff,0xff40c0ff,0xff3fbfff,0xff3fc0ff,
+ 0xff3fbfff,0xff3ebfff,0xff3dbfff,0xff3dbfff,0xff50c4ff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff62caff,0xff3abcff,0xff39bcff,0xff61c9ff,0xff38bbff,0xff37bbff,
+ 0xff37bbff,0xff5ec8ff,0xff36baff,0xff36b9ff,0xff35baff,0xff34b9ff,0xff34b9ff,0xff5cc7ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff32b7ff,0xff31b7ff,0xff31b6ff,
+ 0xff30b6ff,0xff2fb5ff,0xff2fb6ff,0xff2eb5ff,0xff2db4ff,0xff2db4ff,0xff2db4ff,0xff2db4ff,0xff56c2ff,0xff2cb3ff,0xff2bb3ff,0xff2bb3ff,0xff29b2ff,0xff29b2ff,
+ 0xff29b2ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff26afff,0xff51bfff,0xff26b0ff,0xff52c0ff,0xff27b1ff,0xff27b0ff,0xff52c1ff,0xff28b2ff,
+ 0xff29b2ff,0xff54c1ff,0xff3fbdff,0xff40bdff,0xff41bdff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff42bfff,0xff43c0ff,0xff63ccff,0xff74d2ff,0xff54c7ff,0xff54c8ff,
+ 0xff65ceff,0xff66ceff,0xff55c8ff,0xff76d4ff,0xff67cfff,0xff67cfff,0xff68cfff,0xff68cfff,0xff67cfff,0xff57c9ff,0xff47c3ff,0xff47c2ff,0xff46c2ff,0xff65ceff,
+ 0xff65ceff,0xff64cdff,0xff54c7ff,0xff63cdff,0xff63ccff,0xff63cdff,0xff52c5ff,0xff73d2ff,0xff62ccff,0xff41bfff,0xff71d0ff,0xff60ccff,0xff60cbff,0xff4fc3ff,
+ 0xff5fc9ff,0xff5fc9ff,0xff4dc2ff,0xff3dbbff,0xff5ec8ff,0xff3cbbff,0xff5cc8ff,0xff5cc7ff,0xff5cc7ff,0xff4ac0ff,0xff5bc6ff,0xff5bc6ff,0xff5bc6ff,0xff39b8ff,
+ 0xff6cccff,0xff59c6ff,0xff48bdff,0xff59c5ff,0xff58c5ff,0xff58c3ff,0xff36b5ff,0xff35b5ff,0xff58c2ff,0xff34b3ff,0xff57c1ff,0xff56c1ff,0xff67c8ff,0xff42baff,
+ 0xff54c1ff,0xff54c1ff,0xff42b9ff,0xff54c0ff,0xff30b1ff,0xff52c0ff,0xff2fb0ff,0xff40b8ff,0xff51bfff,0xff2eaeff,0xff51bdff,0xff50bdff,0xff62c5ff,0xff2dadff,
+ 0xff2cadff,0xff4fbdff,0xff2badff,0xff4dbcff,0xff4dbcff,0xff60c3ff,0xff3ab3ff,0xff4cbaff,0xff4cbbff,0xff39b2ff,0xff4bbaff,0xff5dc1ff,0xff38b1ff,0xff38b1ff,
+ 0xff49b9ff,0xff49b8ff,0xff37b0ff,0xff5bc0ff,0xff49b8ff,0xff48b8ff,0xff48b8ff,0xff23a5ff,0xff23a5ff,0xff46b7ff,0xff22a4ff,0xff46b5ff,0xff20a4ff,0xff45b4ff,
+ 0xff45b4ff,0xff44b4ff,0xff31abff,0xff57bcff,0xff42b3ff,0xff42b3ff,0xff2faaff,0xff41b3ff,0xff41b2ff,0xff2ea9ff,0xff41b2ff,0xff55baff,0xff2ea9ff,0xff41b2ff,
+ 0xff1da0ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff43b3ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff50caff,0xff51cbff,0xff52cbff,0xff75d6ff,0xff76d6ff,0xff64d1ff,
+ 0xff53cdff,0xff76d7ff,0xff55cdff,0xff77d7ff,0xff56ceff,0xff56ceff,0xff57cfff,0xff7ad9ff,0xff57cfff,0xff7ad9ff,0xff7ad9ff,0xff59d0ff,0xff59cfff,0xff7ad9ff,
+ 0xff69d4ff,0xff79d9ff,0xff78d8ff,0xff78d8ff,0xff56cdff,0xff55cdff,0xff77d7ff,0xff65d2ff,0xff76d7ff,0xff87dcff,0xff53ccff,0xff75d6ff,0xff51cbff,0xff51cbff,
+ 0xff73d6ff,0xff50caff,0xff73d5ff,0xff61ceff,0xff72d5ff,0xff72d4ff,0xff60ceff,0xff4dc8ff,0xff71d3ff,0xff4cc8ff,0xff70d2ff,0xff4bc8ff,0xff4bc7ff,0xff6fd2ff,
+ 0xff6fd1ff,0xff48c6ff,0xff6dd1ff,0xff48c5ff,0xff6cd1ff,0xff6cd0ff,0xff6bd0ff,0xff7dd6ff,0xff6bd0ff,0xff7dd5ff,0xff44c3ff,0xff56c9ff,0xff56c8ff,0xff43c2ff,
+ 0xff68ceff,0xff42c1ff,0xff67cdff,0xff41c0ff,0xff66cdff,0xff66cdff,0xff66cdff,0xff51c6ff,0xff52c5ff,0xff64ccff,0xff3dbeff,0xff3dbeff,0xff63cbff,0xff3cbdff,
+ 0xff63caff,0xff3bbdff,0xff62caff,0xff39bcff,0xff4dc3ff,0xff4cc3ff,0xff37bbff,0xff5fc9ff,0xff37baff,0xff5ec8ff,0xff5ec8ff,0xff36b9ff,0xff35baff,0xff5dc7ff,
+ 0xff34b8ff,0xff5cc6ff,0xff33b8ff,0xff5bc6ff,0xff32b8ff,0xff5ac6ff,0xff31b7ff,0xff5ac5ff,0xff2fb6ff,0xff59c5ff,0xff59c4ff,0xff2eb5ff,0xff2db5ff,0xff57c4ff,
+ 0xff2cb4ff,0xff57c3ff,0xff2bb4ff,0xff56c2ff,0xff2bb3ff,0xff2ab3ff,0xff55c2ff,0xff54c1ff,0xff28b1ff,0xff53c1ff,0xff53c1ff,0xff52c1ff,0xff52c0ff,0xff52c0ff,
+ 0xff25afff,0xff51bfff,0xff25b0ff,0xff52c0ff,0xff26b0ff,0xff27b1ff,0xff28b1ff,0xff28b1ff,0xff53c1ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff40bfff,0xff41bfff,
+ 0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff42c1ff,0xff63cdff,0xff44c2ff,0xff64cdff,0xff45c2ff,0xff45c2ff,0xff56c8ff,0xff76d4ff,0xff47c3ff,0xff67cfff,
+ 0xff68cfff,0xff58cbff,0xff48c5ff,0xff67cfff,0xff47c3ff,0xff46c3ff,0xff46c2ff,0xff65ceff,0xff55c8ff,0xff44c2ff,0xff64cdff,0xff63cdff,0xff43c0ff,0xff63ccff,
+ 0xff41c0ff,0xff62ccff,0xff41bfff,0xff50c3ff,0xff60ccff,0xff40bdff,0xff5fcbff,0xff3fbcff,0xff3fbcff,0xff3ebcff,0xff3dbcff,0xff4dc2ff,0xff4cc1ff,0xff3cbbff,
+ 0xff5dc8ff,0xff3bbaff,0xff3abaff,0xff5cc7ff,0xff5bc6ff,0xff3ab9ff,0xff5bc6ff,0xff39b8ff,0xff5ac6ff,0xff5ac5ff,0xff59c5ff,0xff58c3ff,0xff37b5ff,0xff46bcff,
+ 0xff35b5ff,0xff58c2ff,0xff34b4ff,0xff34b4ff,0xff57c1ff,0xff33b3ff,0xff67c8ff,0xff55c1ff,0xff32b2ff,0xff31b2ff,0xff54c1ff,0xff31b1ff,0xff53c0ff,0xff41b8ff,
+ 0xff2fb0ff,0xff2eb0ff,0xff51bfff,0xff2eaeff,0xff51bfff,0xff2eaeff,0xff62c6ff,0xff2daeff,0xff4fbdff,0xff2cacff,0xff2badff,0xff4ebcff,0xff2aacff,0xff60c3ff,
+ 0xff4cbbff,0xff28abff,0xff28aaff,0xff4bbaff,0xff28aaff,0xff4ab9ff,0xff38b1ff,0xff27a9ff,0xff5cc0ff,0xff37b0ff,0xff25a8ff,0xff49b8ff,0xff24a7ff,0xff48b7ff,
+ 0xff48b7ff,0xff24a5ff,0xff33adff,0xff46b5ff,0xff33adff,0xff33adff,0xff21a4ff,0xff45b5ff,0xff31acff,0xff20a3ff,0xff44b3ff,0xff43b3ff,0xff1ea2ff,0xff42b3ff,
+ 0xff42b3ff,0xff1da0ff,0xff1ca0ff,0xff2ea9ff,0xff1ba0ff,0xff41b2ff,0xff2ea9ff,0xff41b2ff,0xff1da1ff,0xff1da1ff,0xff42b3ff,0xff30aaff,0xff31abff,0xff1fa2ff,
+ 0xff50caff,0xff51caff,0xff51cbff,0xff51cbff,0xff51cbff,0xff52cbff,0xff52ccff,0xff53ccff,0xff54cdff,0xff65d1ff,0xff54cdff,0xff55ceff,0xff77d8ff,0xff78d8ff,
+ 0xff56ceff,0xff79d9ff,0xff7ad9ff,0xff6ad5ff,0xff7bd9ff,0xff6ad5ff,0xff7ad9ff,0xff58cfff,0xff58cfff,0xff57ceff,0xff57ceff,0xff78d8ff,0xff67d3ff,0xff77d8ff,
+ 0xff55cdff,0xff65d1ff,0xff76d6ff,0xff76d6ff,0xff53ccff,0xff52cbff,0xff74d6ff,0xff51caff,0xff62cfff,0xff50caff,0xff61cfff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,
+ 0xff4dc8ff,0xff71d3ff,0xff4dc8ff,0xff4cc7ff,0xff5ecdff,0xff4bc7ff,0xff4ac7ff,0xff5cccff,0xff5bccff,0xff6dd1ff,0xff5accff,0xff47c5ff,0xff5acbff,0xff47c5ff,
+ 0xff59caff,0xff59caff,0xff6acfff,0xff58c9ff,0xff57c9ff,0xff56c9ff,0xff43c2ff,0xff42c2ff,0xff55c7ff,0xff68cdff,0xff54c7ff,0xff41c1ff,0xff67cdff,0xff66cdff,
+ 0xff52c6ff,0xff3ebfff,0xff51c5ff,0xff3dbfff,0xff3dbfff,0xff64ccff,0xff63cbff,0xff4fc5ff,0xff4fc5ff,0xff62caff,0xff4ec4ff,0xff4dc3ff,0xff4dc3ff,0xff39bcff,
+ 0xff38bbff,0xff4bc2ff,0xff5fc9ff,0xff4ac1ff,0xff36baff,0xff5ec7ff,0xff5dc7ff,0xff34b9ff,0xff33b9ff,0xff48bfff,0xff47bfff,0xff5bc6ff,0xff46beff,0xff5ac5ff,
+ 0xff46beff,0xff45bdff,0xff30b6ff,0xff44bdff,0xff2fb5ff,0xff58c4ff,0xff43bcff,0xff42bcff,0xff57c3ff,0xff2cb3ff,0xff2cb3ff,0xff56c3ff,0xff40bbff,0xff56c2ff,
+ 0xff29b2ff,0xff3fbaff,0xff28b2ff,0xff3ebaff,0xff28b1ff,0xff52c1ff,0xff52c0ff,0xff26b0ff,0xff25b0ff,0xff3bb7ff,0xff3bb8ff,0xff26b0ff,0xff52c0ff,0xff52c0ff,
+ 0xff28b1ff,0xff53c1ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42c1ff,0xff43c1ff,
+ 0xff43c1ff,0xff44c2ff,0xff45c1ff,0xff45c2ff,0xff45c2ff,0xff56c9ff,0xff47c3ff,0xff48c3ff,0xff58cbff,0xff48c5ff,0xff48c5ff,0xff47c3ff,0xff47c3ff,0xff47c3ff,
+ 0xff46c2ff,0xff55c8ff,0xff45c2ff,0xff45c2ff,0xff44c1ff,0xff43c0ff,0xff43c0ff,0xff42c0ff,0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff40bfff,0xff40bdff,
+ 0xff3fbdff,0xff3fbcff,0xff3ebdff,0xff3ebcff,0xff3ebbff,0xff4dc2ff,0xff3dbbff,0xff3cbaff,0xff3cbaff,0xff3bbaff,0xff3bb9ff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,
+ 0xff39b9ff,0xff39b8ff,0xff38b8ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff35b5ff,0xff46bcff,0xff35b5ff,0xff34b4ff,0xff33b4ff,0xff34b3ff,0xff33b4ff,
+ 0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff32b2ff,0xff30b2ff,0xff31b1ff,0xff30b0ff,0xff2fb0ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2daeff,
+ 0xff2daeff,0xff3db5ff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2aabff,0xff29abff,0xff29abff,0xff29aaff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,
+ 0xff27aaff,0xff26a9ff,0xff49b9ff,0xff49b8ff,0xff25a7ff,0xff24a8ff,0xff24a8ff,0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff23a5ff,0xff22a4ff,0xff33adff,0xff21a4ff,
+ 0xff20a3ff,0xff32acff,0xff20a3ff,0xff20a3ff,0xff1fa3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,0xff1b9fff,
+ 0xff1ba0ff,0xff1ca0ff,0xff1ca1ff,0xff1da0ff,0xff1da1ff,0xff30abff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff62cfff,0xff62d0ff,0xff52cbff,0xff52cbff,
+ 0xff53ccff,0xff53ccff,0xff54ccff,0xff54ccff,0xff55ceff,0xff55ceff,0xff56cdff,0xff56ceff,0xff57cfff,0xff57ceff,0xff58cfff,0xff58cfff,0xff59d0ff,0xff5ad0ff,
+ 0xff59d0ff,0xff6ad5ff,0xff58cfff,0xff57ceff,0xff57ceff,0xff56ceff,0xff56cdff,0xff55cdff,0xff55ceff,0xff54cdff,0xff54ccff,0xff53ccff,0xff52cbff,0xff52cbff,
+ 0xff51cbff,0xff51cbff,0xff50caff,0xff50caff,0xff50caff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,0xff4ec9ff,0xff4dc9ff,0xff4cc8ff,0xff4cc8ff,0xff4bc7ff,0xff4bc7ff,
+ 0xff4bc7ff,0xff5ccdff,0xff4ac6ff,0xff49c6ff,0xff48c6ff,0xff48c5ff,0xff47c5ff,0xff46c5ff,0xff46c5ff,0xff46c4ff,0xff45c3ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,
+ 0xff44c2ff,0xff43c2ff,0xff42c2ff,0xff42c1ff,0xff41c1ff,0xff41c0ff,0xff40c0ff,0xff40c0ff,0xff3fbfff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbfff,0xff3cbeff,
+ 0xff3cbeff,0xff3bbeff,0xff3bbdff,0xff3abdff,0xff3abdff,0xff3abcff,0xff39bcff,0xff38bcff,0xff38bbff,0xff38bbff,0xff4bc2ff,0xff4ac1ff,0xff36baff,0xff36baff,
+ 0xff34b9ff,0xff35b9ff,0xff34b9ff,0xff47c0ff,0xff47bfff,0xff32b8ff,0xff32b7ff,0xff31b7ff,0xff30b7ff,0xff30b7ff,0xff30b6ff,0xff2fb5ff,0xff2fb6ff,0xff2eb5ff,
+ 0xff2eb5ff,0xff42bcff,0xff2db4ff,0xff2cb4ff,0xff2cb3ff,0xff2bb4ff,0xff2bb3ff,0xff2ab2ff,0xff2ab2ff,0xff29b2ff,0xff28b1ff,0xff28b2ff,0xff28b1ff,0xff27b0ff,
+ 0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff25afff,0xff3bb7ff,0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff40bfff,
+ 0xff61ccff,0xff61ccff,0xff41c0ff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff63ccff,0xff43c0ff,0xff44c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff46c3ff,0xff46c2ff,
+ 0xff46c3ff,0xff47c3ff,0xff47c5ff,0xff48c5ff,0xff58cbff,0xff57c9ff,0xff47c3ff,0xff46c3ff,0xff46c2ff,0xff45c2ff,0xff45c2ff,0xff44c2ff,0xff43c2ff,0xff43c1ff,
+ 0xff43c1ff,0xff42c0ff,0xff41c0ff,0xff62ccff,0xff41bfff,0xff41bfff,0xff41bdff,0xff71d0ff,0xff40bdff,0xff3fbdff,0xff3ebcff,0xff5fc9ff,0xff3dbbff,0xff5ec8ff,
+ 0xff3dbbff,0xff3cbbff,0xff3bbbff,0xff3bbaff,0xff4bc0ff,0xff49c0ff,0xff6dcdff,0xff5bc6ff,0xff49c0ff,0xff38b8ff,0xff39b8ff,0xff38b7ff,0xff38b7ff,0xff37b7ff,
+ 0xff58c3ff,0xff36b5ff,0xff47bcff,0xff58c3ff,0xff57c2ff,0xff45bbff,0xff56c1ff,0xff33b3ff,0xff55c1ff,0xff55c1ff,0xff32b2ff,0xff32b2ff,0xff54c1ff,0xff31b2ff,
+ 0xff30b1ff,0xff30b0ff,0xff41b8ff,0xff51bfff,0xff51bfff,0xff40b8ff,0xff51bdff,0xff51bdff,0xff50bdff,0xff4fbdff,0xff2cadff,0xff2badff,0xff2bacff,0xff2aacff,
+ 0xff4dbcff,0xff4cbbff,0xff29abff,0xff28abff,0xff28abff,0xff28aaff,0xff28aaff,0xff4abaff,0xff49b9ff,0xff27a9ff,0xff25a9ff,0xff25a8ff,0xff24a8ff,0xff49b8ff,
+ 0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff34adff,0xff34adff,0xff46b5ff,0xff21a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa3ff,0xff1fa2ff,
+ 0xff1fa2ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,0xff41b2ff,0xff1ca0ff,0xff1ca0ff,0xff1ea1ff,0xff41b3ff,0xff1ea2ff,
+ 0xff1ea2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff62d0ff,0xff62d0ff,0xff51cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff76d6ff,0xff54ccff,0xff55cdff,0xff55cdff,
+ 0xff56ceff,0xff56ceff,0xff56ceff,0xff58ceff,0xff58ceff,0xff58cfff,0xff59d0ff,0xff59d0ff,0xff7bd9ff,0xff58cfff,0xff68d4ff,0xff7ad9ff,0xff68d4ff,0xff68d3ff,
+ 0xff66d3ff,0xff77d8ff,0xff54cdff,0xff65d2ff,0xff76d6ff,0xff64d1ff,0xff64d1ff,0xff86daff,0xff74d6ff,0xff51cbff,0xff51cbff,0xff73d5ff,0xff4fc9ff,0xff4fc9ff,
+ 0xff61ceff,0xff60ceff,0xff4ec8ff,0xff71d3ff,0xff71d3ff,0xff5ecdff,0xff4cc8ff,0xff4bc7ff,0xff6fd2ff,0xff4ac7ff,0xff6fd1ff,0xff49c6ff,0xff6dd1ff,0xff48c6ff,
+ 0xff6cd1ff,0xff6cd1ff,0xff46c4ff,0xff6bcfff,0xff7dd6ff,0xff58c9ff,0xff6acfff,0xff44c2ff,0xff43c2ff,0xff56c8ff,0xff8edaff,0xff41c1ff,0xff67cdff,0xff66cdff,
+ 0xff40c0ff,0xff40c0ff,0xff66cdff,0xff3fbfff,0xff3fbfff,0xff3ebfff,0xff64ccff,0xff3dbeff,0xff3cbdff,0xff4fc5ff,0xff63caff,0xff3abdff,0xff4ec4ff,0xff62caff,
+ 0xff39bcff,0xff39bcff,0xff38bcff,0xff37bbff,0xff4bc1ff,0xff4ac2ff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff33b9ff,0xff47bfff,0xff47bfff,0xff33b8ff,
+ 0xff32b7ff,0xff32b7ff,0xff30b7ff,0xff5ac5ff,0xff30b6ff,0xff2fb6ff,0xff2fb6ff,0xff2eb5ff,0xff58c4ff,0xff2db5ff,0xff57c3ff,0xff57c3ff,0xff41bbff,0xff2bb3ff,
+ 0xff56c2ff,0xff56c2ff,0xff29b2ff,0xff3fbaff,0xff3ebaff,0xff3ebaff,0xff28b1ff,0xff52c1ff,0xff52c1ff,0xff26b0ff,0xff26b0ff,0xff3bb8ff,0xff3cb8ff,0xff26b0ff,
+ 0xff52c1ff,0xff3db8ff,0xff53c1ff,0xff3ebaff,0xff54c1ff,0xff3fbaff,0xff40bcff,0xff40bdff,0xff40bdff,0xff41bdff,0xff41c0ff,0xff62ccff,0xff63ccff,0xff52c6ff,
+ 0xff63ccff,0xff43c1ff,0xff43c2ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff46c3ff,0xff46c2ff,0xff47c3ff,0xff47c3ff,0xff48c3ff,0xff48c5ff,0xff68cfff,0xff48c3ff,
+ 0xff77d4ff,0xff46c3ff,0xff65ceff,0xff65ceff,0xff54c7ff,0xff44c2ff,0xff64ceff,0xff63ccff,0xff42c0ff,0xff63ccff,0xff42c0ff,0xff62ccff,0xff41bfff,0xff41bfff,
+ 0xff41bdff,0xff60cbff,0xff3fbdff,0xff3fbcff,0xff3fbdff,0xff5fc9ff,0xff3ebbff,0xff6fcfff,0xff3dbbff,0xff5dc7ff,0xff3bbaff,0xff3bbaff,0xff5cc7ff,0xff3ab9ff,
+ 0xff5bc6ff,0xff3ab9ff,0xff5bc6ff,0xff5bc6ff,0xff38b8ff,0xff38b7ff,0xff59c5ff,0xff37b7ff,0xff58c3ff,0xff36b7ff,0xff58c3ff,0xff34b4ff,0xff57c2ff,0xff45bbff,
+ 0xff56c2ff,0xff55c1ff,0xff55c1ff,0xff55c1ff,0xff32b2ff,0xff32b2ff,0xff54c0ff,0xff31b2ff,0xff30b1ff,0xff30b1ff,0xff2fb0ff,0xff51c0ff,0xff51bfff,0xff2eaeff,
+ 0xff3fb8ff,0xff50bdff,0xff3eb7ff,0xff4fbdff,0xff2cadff,0xff2bacff,0xff2bacff,0xff2bacff,0xff2aacff,0xff29abff,0xff29abff,0xff28aaff,0xff28aaff,0xff28aaff,
+ 0xff28aaff,0xff28a9ff,0xff27a9ff,0xff26a9ff,0xff49b9ff,0xff49b8ff,0xff37b0ff,0xff49b8ff,0xff24a7ff,0xff24a7ff,0xff23a7ff,0xff24a5ff,0xff47b7ff,0xff23a4ff,
+ 0xff5abfff,0xff21a4ff,0xff45b4ff,0xff46b5ff,0xff20a3ff,0xff20a3ff,0xff43b3ff,0xff43b4ff,0xff42b3ff,0xff42b3ff,0xff41b3ff,0xff1ea1ff,0xff1ca0ff,0xff41b2ff,
+ 0xff1ba0ff,0xff41b1ff,0xff1ca0ff,0xff41b2ff,0xff1da1ff,0xff2faaff,0xff41b3ff,0xff31aaff,0xff1ea2ff,0xff44b3ff,0xff4fcaff,0xff50caff,0xff51cbff,0xff51cbff,
+ 0xff52cbff,0xff52ccff,0xff53ccff,0xff53ccff,0xff76d6ff,0xff55cdff,0xff54cdff,0xff56cdff,0xff55ceff,0xff57ceff,0xff57cfff,0xff57cfff,0xff57cfff,0xff58cfff,
+ 0xff59d0ff,0xff7bd9ff,0xff59d0ff,0xff58cfff,0xff79d9ff,0xff57ceff,0xff79d8ff,0xff78d8ff,0xff56ceff,0xff55cdff,0xff77d7ff,0xff87dcff,0xff76d6ff,0xff76d6ff,
+ 0xff53ccff,0xff75d6ff,0xff52cbff,0xff51cbff,0xff51caff,0xff73d5ff,0xff50caff,0xff4fcaff,0xff4fc9ff,0xff72d4ff,0xff4ec8ff,0xff71d3ff,0xff4cc8ff,0xff70d2ff,
+ 0xff4cc8ff,0xff6fd2ff,0xff4ac7ff,0xff4ac7ff,0xff6ed1ff,0xff49c5ff,0xff6ed1ff,0xff6dd1ff,0xff47c5ff,0xff47c4ff,0xff6bd0ff,0xff46c4ff,0xff6bcfff,0xff45c3ff,
+ 0xff6acfff,0xff44c2ff,0xff43c2ff,0xff68ceff,0xff68ceff,0xff42c1ff,0xff8ddaff,0xff67cdff,0xff40c0ff,0xff3fc0ff,0xff66ccff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,
+ 0xff50c5ff,0xff3cbeff,0xff3cbeff,0xff63cbff,0xff50c4ff,0xff3bbdff,0xff62caff,0xff61caff,0xff39bcff,0xff38bbff,0xff38bbff,0xff38bbff,0xff37bbff,0xff36bbff,
+ 0xff36baff,0xff36baff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff33b9ff,0xff33b8ff,0xff32b7ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff5ac5ff,0xff30b6ff,0xff2fb5ff,
+ 0xff2eb6ff,0xff58c4ff,0xff2eb5ff,0xff2db4ff,0xff57c3ff,0xff2cb4ff,0xff57c3ff,0xff56c3ff,0xff2bb3ff,0xff2ab2ff,0xff55c2ff,0xff54c1ff,0xff54c1ff,0xff54c1ff,
+ 0xff53c1ff,0xff52c0ff,0xff52c0ff,0xff3cb8ff,0xff25b0ff,0xff51bfff,0xff25b0ff,0xff52c0ff,0xff27b1ff,0xff27b1ff,0xff52c1ff,0xff54c1ff,0xff54c1ff,0xff6ac9ff,
+ 0xff3fbdff,0xff40bdff,0xff40bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff43c0ff,0xff74d2ff,0xff63cdff,0xff64cdff,0xff44c2ff,0xff55c8ff,0xff76d4ff,
+ 0xff46c2ff,0xff46c3ff,0xff77d4ff,0xff57c9ff,0xff48c5ff,0xff68cfff,0xff47c3ff,0xff47c3ff,0xff76d4ff,0xff67ceff,0xff65ceff,0xff66ceff,0xff45c2ff,0xff44c2ff,
+ 0xff63cdff,0xff63ccff,0xff63cdff,0xff63ccff,0xff41bfff,0xff51c6ff,0xff61ccff,0xff50c3ff,0xff50c5ff,0xff71d0ff,0xff5fcbff,0xff3fbcff,0xff5fc9ff,0xff70cfff,
+ 0xff4dc2ff,0xff6fcfff,0xff5ec8ff,0xff5dc8ff,0xff3cbaff,0xff5cc7ff,0xff3ab9ff,0xff3ab9ff,0xff6dcdff,0xff5bc6ff,0xff49bfff,0xff49bfff,0xff5ac6ff,0xff5ac5ff,
+ 0xff48bdff,0xff36b7ff,0xff58c5ff,0xff58c3ff,0xff46bcff,0xff58c2ff,0xff57c3ff,0xff57c2ff,0xff56c1ff,0xff33b3ff,0xff56c1ff,0xff42baff,0xff54c1ff,0xff54c1ff,
+ 0xff41b9ff,0xff31b1ff,0xff65c7ff,0xff40b8ff,0xff40b8ff,0xff51c0ff,0xff51bfff,0xff40b8ff,0xff51bdff,0xff50bdff,0xff50bdff,0xff4fbdff,0xff4fbdff,0xff4ebdff,
+ 0xff3cb5ff,0xff2babff,0xff29acff,0xff2aabff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27aaff,0xff26a9ff,0xff25a8ff,0xff25a9ff,
+ 0xff25a8ff,0xff5bc0ff,0xff49b8ff,0xff48b8ff,0xff23a5ff,0xff47b8ff,0xff23a5ff,0xff22a4ff,0xff46b5ff,0xff21a4ff,0xff46b5ff,0xff32adff,0xff45b4ff,0xff44b3ff,
+ 0xff31acff,0xff44b3ff,0xff31abff,0xff42b3ff,0xff30aaff,0xff41b3ff,0xff41b3ff,0xff2ea9ff,0xff41b2ff,0xff1b9fff,0xff1b9fff,0xff2ea9ff,0xff41b2ff,0xff41b3ff,
+ 0xff41b3ff,0xff42b3ff,0xff42b3ff,0xff57bcff,0xff50caff,0xff50cbff,0xff50caff,0xff51cbff,0xff52cbff,0xff52ccff,0xff53ccff,0xff53cdff,0xff53cdff,0xff54cdff,
+ 0xff55cdff,0xff55cdff,0xff55ceff,0xff67d3ff,0xff56ceff,0xff57cfff,0xff68d4ff,0xff59cfff,0xff7bd9ff,0xff59d0ff,0xff59d0ff,0xff58d0ff,0xff7ad9ff,0xff57cfff,
+ 0xff56ceff,0xff57ceff,0xff56ceff,0xff55ceff,0xff54ceff,0xff54cdff,0xff54cdff,0xff53ccff,0xff53ccff,0xff52ccff,0xff52ccff,0xff51cbff,0xff51caff,0xff50caff,
+ 0xff50caff,0xff4fc9ff,0xff4ec9ff,0xff4ec9ff,0xff4ec8ff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff6fd2ff,0xff4bc7ff,0xff4bc6ff,0xff49c7ff,0xff4ac6ff,0xff49c6ff,
+ 0xff48c5ff,0xff48c5ff,0xff47c5ff,0xff47c5ff,0xff47c4ff,0xff46c3ff,0xff45c3ff,0xff44c3ff,0xff45c3ff,0xff43c3ff,0xff43c2ff,0xff43c2ff,0xff42c2ff,0xff42c1ff,
+ 0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff51c5ff,0xff3ebfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3bbeff,0xff3bbeff,0xff3abdff,
+ 0xff3abcff,0xff39bcff,0xff39bcff,0xff39bbff,0xff38bbff,0xff38bbff,0xff37bbff,0xff36baff,0xff36b9ff,0xff36b9ff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff33b8ff,
+ 0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff31b6ff,0xff2fb6ff,0xff2fb5ff,0xff59c4ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2cb5ff,0xff2db4ff,
+ 0xff2cb3ff,0xff2bb4ff,0xff2bb3ff,0xff2ab2ff,0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff28b1ff,0xff27b1ff,0xff27b0ff,0xff27b0ff,0xff26b0ff,0xff52bfff,0xff25afff,
+ 0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42c0ff,
+ 0xff42c0ff,0xff42c1ff,0xff42c0ff,0xff43c1ff,0xff43c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff45c3ff,0xff46c3ff,0xff46c3ff,0xff47c3ff,0xff48c5ff,0xff48c5ff,
+ 0xff48c3ff,0xff48c5ff,0xff47c3ff,0xff46c2ff,0xff46c2ff,0xff46c2ff,0xff44c1ff,0xff44c1ff,0xff44c1ff,0xff44c0ff,0xff42c1ff,0xff42c0ff,0xff41bfff,0xff41c0ff,
+ 0xff41bfff,0xff41bfff,0xff41bfff,0xff40bfff,0xff40bcff,0xff3fbdff,0xff3ebdff,0xff3ebcff,0xff3dbbff,0xff3dbbff,0xff3cbbff,0xff3cbbff,0xff3cbaff,0xff3bbaff,
+ 0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff39b8ff,0xff38b8ff,0xff38b7ff,0xff37b7ff,0xff37b7ff,0xff36b7ff,0xff36b5ff,0xff35b5ff,0xff35b4ff,
+ 0xff34b4ff,0xff33b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,0xff2fb0ff,0xff2fb0ff,
+ 0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2daeff,0xff2cadff,0xff2cadff,0xff2cacff,0xff2bacff,0xff2bacff,0xff2aabff,0xff29abff,0xff29abff,0xff29abff,
+ 0xff28abff,0xff28aaff,0xff28aaff,0xff27aaff,0xff27a9ff,0xff26a8ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff24a5ff,
+ 0xff23a5ff,0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,
+ 0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,0xff1b9fff,0xff1b9fff,0xff1ca1ff,0xff1da0ff,0xff1da1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa1ff,0xff1fa2ff,0xff4fcaff,0xff50cbff,
+ 0xff50caff,0xff51cbff,0xff52cbff,0xff52cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff54cdff,0xff55cdff,0xff55cdff,0xff56ceff,0xff56ceff,0xff57cfff,0xff58ceff,
+ 0xff68d4ff,0xff69d4ff,0xff59d0ff,0xff5ad0ff,0xff58cfff,0xff58d0ff,0xff58cfff,0xff7ad8ff,0xff57ceff,0xff56ceff,0xff56ceff,0xff66d2ff,0xff55cdff,0xff65d2ff,
+ 0xff54cdff,0xff53ccff,0xff53ccff,0xff75d6ff,0xff75d6ff,0xff51cbff,0xff74d6ff,0xff73d5ff,0xff73d5ff,0xff61cfff,0xff4fcaff,0xff4ec9ff,0xff4dc9ff,0xff4dc8ff,
+ 0xff4dc8ff,0xff4cc8ff,0xff4bc7ff,0xff4bc7ff,0xff4ac7ff,0xff4ac7ff,0xff49c6ff,0xff49c6ff,0xff48c6ff,0xff47c5ff,0xff47c5ff,0xff46c5ff,0xff47c4ff,0xff46c4ff,
+ 0xff45c3ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff42c2ff,0xff42c2ff,0xff42c1ff,0xff41c1ff,0xff40c1ff,0xff40c0ff,0xff3fc0ff,0xff3fc0ff,0xff3fbfff,
+ 0xff3ebfff,0xff3dbfff,0xff3dbfff,0xff3dbeff,0xff3cbdff,0xff3cbeff,0xff3bbeff,0xff3abdff,0xff3abdff,0xff39bdff,0xff39bcff,0xff38bbff,0xff38bbff,0xff38bbff,
+ 0xff37bbff,0xff37baff,0xff36baff,0xff35baff,0xff35baff,0xff34b9ff,0xff33b9ff,0xff34b8ff,0xff33b8ff,0xff33b8ff,0xff31b7ff,0xff32b7ff,0xff31b7ff,0xff30b7ff,
+ 0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb6ff,0xff2db5ff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2cb3ff,0xff2cb3ff,0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,
+ 0xff29b1ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff25b0ff,0xff26b0ff,0xff26b1ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,
+ 0xff28b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff43c1ff,0xff43c1ff,0xff45c2ff,
+ 0xff45c2ff,0xff45c2ff,0xff45c3ff,0xff46c3ff,0xff67cfff,0xff57c9ff,0xff48c3ff,0xff48c5ff,0xff47c5ff,0xff47c5ff,0xff47c3ff,0xff66cfff,0xff45c2ff,0xff45c2ff,
+ 0xff45c2ff,0xff54c8ff,0xff43c1ff,0xff63cdff,0xff43c1ff,0xff42c1ff,0xff63ccff,0xff41c0ff,0xff41c0ff,0xff61ccff,0xff40bdff,0xff60cbff,0xff40bcff,0xff3fbcff,
+ 0xff3ebcff,0xff3ebcff,0xff3dbbff,0xff3dbcff,0xff3cbaff,0xff3cbaff,0xff3bbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff39b8ff,0xff39b8ff,
+ 0xff38b8ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff35b5ff,0xff34b5ff,0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b4ff,0xff33b3ff,0xff32b2ff,
+ 0xff33b2ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2daeff,0xff2dadff,0xff2cadff,
+ 0xff2cadff,0xff2cadff,0xff2badff,0xff2bacff,0xff2aacff,0xff2aabff,0xff29abff,0xff29abff,0xff28abff,0xff28aaff,0xff28a9ff,0xff27a9ff,0xff27a9ff,0xff27a9ff,
+ 0xff26a8ff,0xff26a8ff,0xff25a7ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff21a4ff,0xff22a4ff,0xff21a3ff,0xff21a4ff,
+ 0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1fa2ff,0xff1fa2ff,0xff1ea2ff,0xff1da1ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,0xff1ba0ff,0xff1b9fff,0xff1ba0ff,0xff1ca1ff,
+ 0xff1ca0ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff84daff,0xff73d6ff,0xff74d6ff,0xff51cbff,0xff86dbff,0xff76d6ff,0xff64d1ff,
+ 0xff53ccff,0xff54cdff,0xff55cdff,0xff55cdff,0xff56ceff,0xff56ceff,0xff56ceff,0xff79d9ff,0xff8addff,0xff69d5ff,0xff59d0ff,0xff59d0ff,0xff59cfff,0xff58cfff,
+ 0xff57cfff,0xff79d9ff,0xff57cfff,0xff56ceff,0xff67d3ff,0xff77d7ff,0xff55cdff,0xff87dcff,0xff76d6ff,0xff76d6ff,0xff76d6ff,0xff52cbff,0xff52ccff,0xff51cbff,
+ 0xff51caff,0xff73d6ff,0xff50caff,0xff72d4ff,0xff4fcaff,0xff4ec9ff,0xff71d4ff,0xff82d9ff,0xff70d3ff,0xff70d3ff,0xff5dcdff,0xff6fd2ff,0xff6fd1ff,0xff5bccff,
+ 0xff49c7ff,0xff49c5ff,0xff49c5ff,0xff5acbff,0xff6cd0ff,0xff6cd0ff,0xff59caff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff43c2ff,0xff42c2ff,
+ 0xff43c1ff,0xff42c2ff,0xff41c1ff,0xff40c1ff,0xff40c0ff,0xff40c0ff,0xff3fbfff,0xff3ec0ff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3cbdff,0xff3bbdff,
+ 0xff3bbeff,0xff3abdff,0xff3abdff,0xff39bcff,0xff39bcff,0xff38bcff,0xff38bbff,0xff37bbff,0xff37bbff,0xff37baff,0xff36baff,0xff35baff,0xff35baff,0xff34b9ff,
+ 0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff32b7ff,0xff31b7ff,0xff30b7ff,0xff31b6ff,0xff30b6ff,0xff2fb5ff,0xff2fb6ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,
+ 0xff2cb4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff29b1ff,0xff28b1ff,0xff28b2ff,0xff27b1ff,0xff26b1ff,0xff26b0ff,
+ 0xff25b0ff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff27b1ff,0xff28b2ff,0xff28b2ff,0xff29b2ff,0xff40bdff,0xff61ccff,0xff41bdff,0xff50c5ff,
+ 0xff41bfff,0xff62ccff,0xff62ccff,0xff63ccff,0xff43c0ff,0xff44c1ff,0xff44c1ff,0xff44c2ff,0xff65ceff,0xff66ceff,0xff56c9ff,0xff46c2ff,0xff67cfff,0xff47c3ff,
+ 0xff47c3ff,0xff48c5ff,0xff48c3ff,0xff47c3ff,0xff47c3ff,0xff66cfff,0xff46c2ff,0xff45c2ff,0xff45c2ff,0xff65cdff,0xff44c1ff,0xff64cdff,0xff42c0ff,0xff63ccff,
+ 0xff62ccff,0xff41c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff60ccff,0xff3fbcff,0xff5fcbff,0xff3fbdff,0xff3ebcff,0xff5fc9ff,0xff5ec9ff,0xff3cbbff,0xff5dc7ff,
+ 0xff5dc7ff,0xff5cc7ff,0xff5cc6ff,0xff5cc6ff,0xff3ab9ff,0xff39b9ff,0xff39b8ff,0xff38b8ff,0xff5bc6ff,0xff5ac6ff,0xff5ac6ff,0xff36b7ff,0xff36b7ff,0xff36b5ff,
+ 0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff33b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff31b2ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,
+ 0xff2fb1ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2aacff,0xff2aabff,0xff2aacff,
+ 0xff29abff,0xff29aaff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,
+ 0xff24a7ff,0xff23a5ff,0xff22a5ff,0xff22a4ff,0xff22a5ff,0xff21a4ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1fa1ff,0xff1ea2ff,
+ 0xff1da1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,0xff1b9fff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1ea1ff,0xff1ea2ff,0xff1ea2ff,0xff1fa2ff,
+ 0xff50caff,0xff74d5ff,0xff51cbff,0xff51cbff,0xff51cbff,0xff75d6ff,0xff76d6ff,0xff76d6ff,0xff53cdff,0xff54ccff,0xff55cdff,0xff55ceff,0xff55ceff,0xff56ceff,
+ 0xff56ceff,0xff58cfff,0xff79d9ff,0xff58cfff,0xff59d0ff,0xff59d0ff,0xff59d0ff,0xff58cfff,0xff58cfff,0xff7ad9ff,0xff56ceff,0xff56ceff,0xff56ceff,0xff77d7ff,
+ 0xff55cdff,0xff87dcff,0xff53ccff,0xff76d6ff,0xff76d6ff,0xff52cbff,0xff52cbff,0xff74d5ff,0xff51cbff,0xff73d5ff,0xff50caff,0xff61ceff,0xff72d4ff,0xff72d4ff,
+ 0xff71d3ff,0xff82d9ff,0xff4cc8ff,0xff6fd3ff,0xff6fd2ff,0xff4bc7ff,0xff4ac6ff,0xff5cccff,0xff49c6ff,0xff5bccff,0xff48c5ff,0xff6cd1ff,0xff47c5ff,0xff47c4ff,
+ 0xff6bd0ff,0xff46c4ff,0xff46c3ff,0xff45c4ff,0xff44c3ff,0xff44c3ff,0xff43c3ff,0xff43c2ff,0xff43c2ff,0xff42c2ff,0xff41c1ff,0xff40c1ff,0xff40c1ff,0xff40c0ff,
+ 0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3bbeff,0xff3bbdff,0xff3abdff,0xff3abcff,0xff39bcff,0xff39bcff,0xff38bbff,
+ 0xff38bbff,0xff37bbff,0xff37baff,0xff37baff,0xff36baff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff32b7ff,
+ 0xff31b7ff,0xff30b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb5ff,0xff2db4ff,0xff2db5ff,0xff2db4ff,0xff2db4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,
+ 0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff28b1ff,0xff28b1ff,0xff27b0ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff25afff,0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,
+ 0xff28b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff50c3ff,0xff40bdff,0xff41bfff,0xff41c0ff,0xff51c5ff,0xff41c0ff,0xff52c6ff,0xff42c0ff,0xff43c1ff,
+ 0xff43c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff46c3ff,0xff57c9ff,0xff48c3ff,0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff47c3ff,0xff57c9ff,0xff66cfff,
+ 0xff65ceff,0xff45c2ff,0xff64ceff,0xff64cdff,0xff54c7ff,0xff53c7ff,0xff63ccff,0xff52c6ff,0xff41c0ff,0xff62ccff,0xff61ccff,0xff41bdff,0xff40bfff,0xff50c3ff,
+ 0xff3fbcff,0xff4fc3ff,0xff3fbdff,0xff3ebcff,0xff5ec9ff,0xff5ec8ff,0xff5ec8ff,0xff4cc1ff,0xff3bbaff,0xff5cc7ff,0xff5cc7ff,0xff3ab9ff,0xff3ab9ff,0xff6dcdff,
+ 0xff49c0ff,0xff39b8ff,0xff5bc5ff,0xff5ac6ff,0xff49bdff,0xff36b7ff,0xff36b7ff,0xff36b5ff,0xff35b5ff,0xff35b5ff,0xff34b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,
+ 0xff33b3ff,0xff33b2ff,0xff32b2ff,0xff31b2ff,0xff31b2ff,0xff30b2ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2fb0ff,0xff2eaeff,0xff2eb0ff,0xff2eaeff,0xff2dadff,
+ 0xff2daeff,0xff2cadff,0xff2cacff,0xff2cacff,0xff2badff,0xff2aacff,0xff2aacff,0xff2aabff,0xff29abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27aaff,0xff28a9ff,
+ 0xff27aaff,0xff26a8ff,0xff26a8ff,0xff26a8ff,0xff24a7ff,0xff24a7ff,0xff24a8ff,0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff22a5ff,0xff22a5ff,0xff22a5ff,0xff21a4ff,
+ 0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea2ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,
+ 0xff1ca0ff,0xff1ca0ff,0xff1da1ff,0xff1da1ff,0xff1da1ff,0xff1ea2ff,0xff1fa1ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff51caff,0xff51cbff,0xff52cbff,0xff52cbff,
+ 0xff53ccff,0xff53ccff,0xff54ccff,0xff54cdff,0xff55cdff,0xff55ceff,0xff56cdff,0xff56ceff,0xff57cfff,0xff58cfff,0xff58cfff,0xff58cfff,0xff58d0ff,0xff59d0ff,
+ 0xff58d0ff,0xff59cfff,0xff57cfff,0xff57ceff,0xff57cfff,0xff56ceff,0xff56cdff,0xff55ceff,0xff55cdff,0xff54cdff,0xff54ccff,0xff53ccff,0xff53cbff,0xff52cbff,
+ 0xff52cbff,0xff51caff,0xff50cbff,0xff50cbff,0xff4fc9ff,0xff4fcaff,0xff72d4ff,0xff72d4ff,0xff4dc8ff,0xff5fcdff,0xff4dc8ff,0xff4cc7ff,0xff4bc8ff,0xff4bc7ff,
+ 0xff4bc7ff,0xff4ac6ff,0xff4ac6ff,0xff49c5ff,0xff49c6ff,0xff48c5ff,0xff47c5ff,0xff46c4ff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff44c3ff,0xff44c3ff,0xff43c2ff,
+ 0xff43c2ff,0xff43c2ff,0xff42c2ff,0xff42c1ff,0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff3fbfff,0xff3ec0ff,0xff3dbfff,0xff3dbfff,0xff3cbeff,
+ 0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff3abdff,0xff3abdff,0xff39bcff,0xff39bbff,0xff38bcff,0xff38bbff,0xff37bbff,0xff37baff,0xff36baff,0xff36baff,0xff36b9ff,
+ 0xff35baff,0xff35b9ff,0xff34b9ff,0xff33b9ff,0xff32b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff31b6ff,0xff31b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb5ff,
+ 0xff2eb5ff,0xff2db5ff,0xff2cb4ff,0xff2db4ff,0xff2cb4ff,0xff2bb4ff,0xff2ab3ff,0xff2ab3ff,0xff2ab3ff,0xff29b2ff,0xff28b2ff,0xff28b2ff,0xff27b1ff,0xff27b1ff,
+ 0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff25afff,0xff25b0ff,0xff26b0ff,0xff26b1ff,0xff27b0ff,0xff28b1ff,0xff28b1ff,0xff29b1ff,0xff29b2ff,0xff40bdff,0xff40bdff,
+ 0xff40bdff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff42c1ff,0xff43c1ff,0xff44c1ff,0xff44c2ff,0xff45c1ff,0xff46c2ff,0xff45c2ff,0xff46c3ff,
+ 0xff46c3ff,0xff47c3ff,0xff48c5ff,0xff48c5ff,0xff48c3ff,0xff47c5ff,0xff46c3ff,0xff46c3ff,0xff46c2ff,0xff45c2ff,0xff45c1ff,0xff45c1ff,0xff43c1ff,0xff43c1ff,
+ 0xff43c0ff,0xff42c0ff,0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff40bdff,0xff40bdff,0xff40bdff,0xff3fbdff,0xff3ebcff,0xff3ebcff,0xff3ebcff,0xff3dbbff,
+ 0xff3dbbff,0xff3cbbff,0xff3bbbff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff3ab8ff,0xff3ab8ff,0xff39b8ff,0xff38b8ff,0xff38b7ff,0xff37b7ff,0xff37b7ff,
+ 0xff36b5ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff34b5ff,0xff33b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff31b2ff,0xff32b2ff,0xff30b1ff,
+ 0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2eaeff,0xff2dadff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2bacff,
+ 0xff2aacff,0xff2aabff,0xff29abff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff26a9ff,0xff26a9ff,0xff25a9ff,0xff25a7ff,0xff24a8ff,
+ 0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff22a5ff,0xff22a4ff,0xff21a4ff,0xff20a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,
+ 0xff1fa1ff,0xff1ea2ff,0xff1ea1ff,0xff1da1ff,0xff1da0ff,0xff1ca0ff,0xff1ba0ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,0xff1da1ff,0xff1ea1ff,0xff1ea2ff,
+ 0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff50cbff,0xff51cbff,0xff52cbff,0xff52ccff,0xff53cbff,0xff53cdff,0xff53ccff,0xff54cdff,0xff55cdff,0xff55cdff,
+ 0xff56ceff,0xff57ceff,0xff57cfff,0xff57ceff,0xff58cfff,0xff58cfff,0xff58d0ff,0xff59d0ff,0xff59d0ff,0xff58cfff,0xff58cfff,0xff57cfff,0xff57cfff,0xff56ceff,
+ 0xff67d2ff,0xff77d7ff,0xff54cdff,0xff54ccff,0xff76d7ff,0xff53cdff,0xff76d6ff,0xff52cbff,0xff52cbff,0xff51cbff,0xff74d6ff,0xff73d5ff,0xff73d5ff,0xff61cfff,
+ 0xff72d4ff,0xff83d9ff,0xff71d4ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,0xff4bc7ff,0xff4bc7ff,0xff4ac7ff,0xff4ac7ff,0xff49c6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,
+ 0xff47c5ff,0xff47c5ff,0xff46c4ff,0xff46c4ff,0xff45c3ff,0xff44c4ff,0xff44c3ff,0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff42c2ff,0xff42c2ff,0xff41c1ff,0xff40c0ff,
+ 0xff40c1ff,0xff40c0ff,0xff3fbfff,0xff3fc0ff,0xff65cdff,0xff3dbfff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff3abcff,
+ 0xff39bcff,0xff38bcff,0xff38bbff,0xff37bbff,0xff37bbff,0xff37baff,0xff36baff,0xff35baff,0xff35baff,0xff34b9ff,0xff33b8ff,0xff34b8ff,0xff32b8ff,0xff32b8ff,
+ 0xff32b7ff,0xff32b7ff,0xff31b7ff,0xff30b7ff,0xff5ac5ff,0xff2fb6ff,0xff2eb6ff,0xff2eb5ff,0xff2eb5ff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2cb3ff,0xff2bb3ff,
+ 0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff28b2ff,0xff28b1ff,0xff27b1ff,0xff26b1ff,0xff26b0ff,0xff26afff,0xff25afff,0xff26b0ff,0xff26b0ff,
+ 0xff26b0ff,0xff27b1ff,0xff27b2ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff50c3ff,0xff61cbff,0xff50c3ff,0xff51c5ff,0xff51c5ff,0xff62ccff,0xff42c0ff,
+ 0xff43c0ff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff65cdff,0xff65ceff,0xff46c2ff,0xff56c8ff,0xff67cfff,0xff57c9ff,0xff58c9ff,0xff49c5ff,0xff48c3ff,0xff57cbff,
+ 0xff47c3ff,0xff46c3ff,0xff45c2ff,0xff45c2ff,0xff45c2ff,0xff65cdff,0xff44c1ff,0xff43c0ff,0xff63cdff,0xff43c0ff,0xff63ccff,0xff51c6ff,0xff62ccff,0xff41bfff,
+ 0xff61ccff,0xff40bfff,0xff50c3ff,0xff3fbdff,0xff3fbcff,0xff5fc9ff,0xff3dbbff,0xff4dc1ff,0xff3cbbff,0xff4cc1ff,0xff4bc1ff,0xff4bc1ff,0xff5cc7ff,0xff3abaff,
+ 0xff49c0ff,0xff5bc6ff,0xff49bfff,0xff38b8ff,0xff39b8ff,0xff38b8ff,0xff38b7ff,0xff48bdff,0xff58c3ff,0xff47bcff,0xff35b5ff,0xff34b4ff,0xff34b5ff,0xff33b4ff,
+ 0xff44bbff,0xff33b3ff,0xff43baff,0xff33b3ff,0xff55c1ff,0xff54c1ff,0xff31b2ff,0xff53c0ff,0xff65c7ff,0xff41b8ff,0xff40b8ff,0xff2eb0ff,0xff2eb0ff,0xff40b7ff,
+ 0xff3fb8ff,0xff50bdff,0xff3eb7ff,0xff2dadff,0xff4fbdff,0xff4fbdff,0xff2bacff,0xff2aacff,0xff2aacff,0xff29acff,0xff29abff,0xff4cbaff,0xff4cbaff,0xff28aaff,
+ 0xff28aaff,0xff27aaff,0xff27a9ff,0xff26a9ff,0xff49b9ff,0xff49b8ff,0xff25a8ff,0xff49b8ff,0xff5bc0ff,0xff35aeff,0xff35adff,0xff23a5ff,0xff23a5ff,0xff33adff,
+ 0xff33adff,0xff46b5ff,0xff32acff,0xff20a4ff,0xff45b4ff,0xff44b4ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff41b3ff,0xff41b3ff,0xff1ca0ff,
+ 0xff1ca0ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff50caff,0xff62cfff,0xff51caff,0xff74d6ff,
+ 0xff74d6ff,0xff63d1ff,0xff52ccff,0xff76d6ff,0xff53cdff,0xff54ccff,0xff55cdff,0xff77d8ff,0xff56ceff,0xff56ceff,0xff67d4ff,0xff89ddff,0xff58cfff,0xff7ad9ff,
+ 0xff7bd9ff,0xff59d0ff,0xff59d0ff,0xff7ad9ff,0xff58cfff,0xff57ceff,0xff57ceff,0xff56ceff,0xff56ceff,0xff78d7ff,0xff54ceff,0xff54cdff,0xff76d7ff,0xff53ccff,
+ 0xff76d6ff,0xff63d1ff,0xff52cbff,0xff74d6ff,0xff73d5ff,0xff50cbff,0xff50caff,0xff4fc9ff,0xff4fc9ff,0xff72d4ff,0xff4dc9ff,0xff71d3ff,0xff4dc8ff,0xff70d3ff,
+ 0xff6fd2ff,0xff5dcdff,0xff4bc7ff,0xff6fd2ff,0xff6fd1ff,0xff49c6ff,0xff6dd1ff,0xff48c6ff,0xff48c5ff,0xff47c5ff,0xff47c5ff,0xff59caff,0xff45c4ff,0xff6acfff,
+ 0xff44c3ff,0xff44c3ff,0xff44c2ff,0xff42c2ff,0xff68ceff,0xff54c8ff,0xff67cdff,0xff66cdff,0xff40c0ff,0xff3fc0ff,0xff52c6ff,0xff3fc0ff,0xff65ccff,0xff3ebfff,
+ 0xff65ccff,0xff3dbeff,0xff3dbeff,0xff63cbff,0xff76d1ff,0xff3abdff,0xff62caff,0xff62caff,0xff39bcff,0xff39bcff,0xff5fc9ff,0xff37bbff,0xff37baff,0xff37baff,
+ 0xff5ec8ff,0xff36b9ff,0xff35baff,0xff5ec7ff,0xff34b9ff,0xff33b9ff,0xff33b9ff,0xff5bc6ff,0xff32b7ff,0xff31b7ff,0xff46beff,0xff30b6ff,0xff5ac5ff,0xff2fb5ff,
+ 0xff59c4ff,0xff2eb5ff,0xff2eb5ff,0xff57c4ff,0xff6ccbff,0xff2cb4ff,0xff57c3ff,0xff56c2ff,0xff2bb3ff,0xff2ab3ff,0xff55c1ff,0xff29b2ff,0xff29b1ff,0xff28b2ff,
+ 0xff52c1ff,0xff27b1ff,0xff26b0ff,0xff52c0ff,0xff26b0ff,0xff25afff,0xff25b0ff,0xff26b0ff,0xff27b1ff,0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,
+ 0xff40bdff,0xff60cbff,0xff60ccff,0xff72d0ff,0xff62ccff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff43c1ff,0xff43c1ff,0xff64ceff,0xff45c2ff,0xff45c2ff,
+ 0xff46c3ff,0xff67ceff,0xff47c3ff,0xff48c3ff,0xff67cfff,0xff48c5ff,0xff48c5ff,0xff67cfff,0xff46c3ff,0xff46c2ff,0xff46c3ff,0xff45c2ff,0xff45c2ff,0xff65cdff,
+ 0xff43c1ff,0xff43c1ff,0xff63cdff,0xff43c0ff,0xff63ccff,0xff41bfff,0xff41bfff,0xff61ccff,0xff61cbff,0xff40bdff,0xff4fc3ff,0xff3fbcff,0xff3ebcff,0xff5fc9ff,
+ 0xff3dbcff,0xff5ec8ff,0xff3dbbff,0xff6eceff,0xff5cc8ff,0xff3bbaff,0xff3abaff,0xff5cc7ff,0xff6dcdff,0xff5bc6ff,0xff5bc6ff,0xff39b8ff,0xff38b8ff,0xff38b7ff,
+ 0xff38b7ff,0xff58c3ff,0xff58c5ff,0xff69cbff,0xff35b5ff,0xff34b5ff,0xff34b4ff,0xff34b4ff,0xff57c2ff,0xff55c1ff,0xff55c1ff,0xff55c1ff,0xff32b2ff,0xff32b2ff,
+ 0xff31b2ff,0xff30b2ff,0xff53c0ff,0xff30b1ff,0xff52bfff,0xff2eb0ff,0xff40b8ff,0xff51bfff,0xff51bdff,0xff2daeff,0xff50bdff,0xff4fbdff,0xff4fbcff,0xff4ebdff,
+ 0xff3cb4ff,0xff2bacff,0xff2aabff,0xff2aabff,0xff4cbbff,0xff28abff,0xff28abff,0xff4bbaff,0xff28aaff,0xff28a9ff,0xff27a9ff,0xff49b9ff,0xff26a9ff,0xff25a8ff,
+ 0xff25a8ff,0xff24a7ff,0xff48b8ff,0xff24a7ff,0xff48b7ff,0xff23a5ff,0xff34adff,0xff46b7ff,0xff46b5ff,0xff21a4ff,0xff46b4ff,0xff45b4ff,0xff44b4ff,0xff44b4ff,
+ 0xff31abff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff42b3ff,0xff1da1ff,0xff1ca1ff,0xff41b2ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,0xff1ca1ff,0xff1da1ff,
+ 0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff73d5ff,0xff74d5ff,0xff85daff,0xff75d6ff,0xff52cbff,0xff52ccff,0xff53ccff,0xff54ccff,0xff54cdff,
+ 0xff55cdff,0xff67d3ff,0xff78d8ff,0xff78d8ff,0xff67d3ff,0xff79d8ff,0xff58cfff,0xff58d0ff,0xff6ad4ff,0xff7bd9ff,0xff7bd9ff,0xff7ad9ff,0xff58cfff,0xff57ceff,
+ 0xff56cfff,0xff57ceff,0xff78d7ff,0xff88dcff,0xff65d2ff,0xff65d2ff,0xff87dcff,0xff76d6ff,0xff75d6ff,0xff75d6ff,0xff75d6ff,0xff62d0ff,0xff73d5ff,0xff73d6ff,
+ 0xff72d5ff,0xff4fcaff,0xff4ecaff,0xff72d3ff,0xff4dc9ff,0xff5fcdff,0xff70d3ff,0xff70d2ff,0xff70d2ff,0xff6fd2ff,0xff6fd2ff,0xff5bccff,0xff6ed1ff,0xff6ed1ff,
+ 0xff6dd1ff,0xff47c5ff,0xff5acbff,0xff7ed6ff,0xff47c4ff,0xff6bd0ff,0xff6ad0ff,0xff7dd5ff,0xff45c3ff,0xff43c3ff,0xff43c2ff,0xff43c2ff,0xff55c7ff,0xff68cdff,
+ 0xff67cdff,0xff54c7ff,0xff66cdff,0xff66cdff,0xff52c6ff,0xff3ebfff,0xff65ccff,0xff64ccff,0xff3ebeff,0xff63cbff,0xff50c5ff,0xff63cbff,0xff76d2ff,0xff62caff,
+ 0xff62caff,0xff4dc3ff,0xff61caff,0xff60c9ff,0xff4cc2ff,0xff37bbff,0xff73cfff,0xff4ac2ff,0xff4ac1ff,0xff5ec7ff,0xff5ec8ff,0xff48c0ff,0xff34b8ff,0xff33b8ff,
+ 0xff33b8ff,0xff47bfff,0xff5ac5ff,0xff5ac5ff,0xff46beff,0xff30b6ff,0xff5ac5ff,0xff59c5ff,0xff2fb6ff,0xff59c4ff,0xff42bcff,0xff57c4ff,0xff6bcbff,0xff57c2ff,
+ 0xff56c3ff,0xff40bcff,0xff56c2ff,0xff55c1ff,0xff3fbaff,0xff29b2ff,0xff69c9ff,0xff3ebaff,0xff3db9ff,0xff52c1ff,0xff52c0ff,0xff3cb8ff,0xff26afff,0xff25b0ff,
+ 0xff26afff,0xff26b0ff,0xff26b0ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff28b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff40bfff,0xff41bfff,0xff41bfff,0xff41c0ff,
+ 0xff42c0ff,0xff42c0ff,0xff42c1ff,0xff43c0ff,0xff44c1ff,0xff44c1ff,0xff44c2ff,0xff45c2ff,0xff46c2ff,0xff47c3ff,0xff46c3ff,0xff48c5ff,0xff47c5ff,0xff48c5ff,
+ 0xff47c5ff,0xff47c3ff,0xff47c3ff,0xff46c3ff,0xff45c3ff,0xff45c2ff,0xff44c2ff,0xff44c2ff,0xff43c1ff,0xff43c1ff,0xff43c1ff,0xff42c0ff,0xff42bfff,0xff41bfff,
+ 0xff41c0ff,0xff41bdff,0xff40bfff,0xff40bdff,0xff40bdff,0xff3fbcff,0xff3fbcff,0xff3ebcff,0xff3dbcff,0xff5ec9ff,0xff5dc8ff,0xff5dc8ff,0xff5dc8ff,0xff3bbaff,
+ 0xff3bb9ff,0xff3abaff,0xff3abaff,0xff39b8ff,0xff39b8ff,0xff39b8ff,0xff38b8ff,0xff49bfff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff36b7ff,0xff35b5ff,0xff34b5ff,
+ 0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff32b3ff,0xff31b2ff,0xff32b1ff,0xff30b2ff,0xff30b1ff,0xff30b1ff,0xff40b8ff,0xff51bfff,
+ 0xff51bfff,0xff40b8ff,0xff51bdff,0xff2daeff,0xff2daeff,0xff2cadff,0xff2cadff,0xff2badff,0xff2badff,0xff2bacff,0xff3bb4ff,0xff29abff,0xff29abff,0xff28abff,
+ 0xff28abff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff25a8ff,0xff24a7ff,0xff24a5ff,0xff35adff,0xff47b7ff,
+ 0xff46b7ff,0xff33adff,0xff46b5ff,0xff21a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff30abff,0xff1ea2ff,0xff1ea1ff,0xff1da1ff,
+ 0xff1ca1ff,0xff1ca0ff,0xff1c9fff,0xff1b9fff,0xff1ca0ff,0xff1ca0ff,0xff1da1ff,0xff1da1ff,0xff1ea2ff,0xff1ea2ff,0xff1ea1ff,0xff1fa2ff,0xff50caff,0xff50caff,
+ 0xff51cbff,0xff51cbff,0xff52ccff,0xff52cbff,0xff53ccff,0xff53ccff,0xff53cdff,0xff54cdff,0xff54cdff,0xff55cdff,0xff56ceff,0xff56cfff,0xff56ceff,0xff58cfff,
+ 0xff57cfff,0xff58cfff,0xff59d0ff,0xff59d0ff,0xff59cfff,0xff58d0ff,0xff58cfff,0xff57cfff,0xff57ceff,0xff56ceff,0xff56ceff,0xff55cdff,0xff55ceff,0xff54ccff,
+ 0xff54ccff,0xff53ccff,0xff53ccff,0xff52cbff,0xff52cbff,0xff51caff,0xff51cbff,0xff50caff,0xff50caff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,0xff4ec8ff,0xff4dc8ff,
+ 0xff4dc8ff,0xff4cc8ff,0xff4bc7ff,0xff4bc7ff,0xff4bc7ff,0xff4ac6ff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,0xff48c5ff,0xff48c4ff,0xff47c4ff,0xff46c4ff,0xff46c3ff,
+ 0xff45c3ff,0xff45c3ff,0xff44c2ff,0xff44c2ff,0xff43c3ff,0xff43c2ff,0xff42c2ff,0xff42c1ff,0xff41c1ff,0xff41c0ff,0xff40c0ff,0xff3fc0ff,0xff3fc0ff,0xff3fc0ff,
+ 0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3abcff,0xff3abcff,0xff39bcff,0xff38bbff,0xff38bcff,0xff37bbff,
+ 0xff37baff,0xff37baff,0xff36baff,0xff36b9ff,0xff35baff,0xff34b9ff,0xff33b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff30b7ff,0xff30b7ff,
+ 0xff30b6ff,0xff30b6ff,0xff2fb6ff,0xff2eb5ff,0xff2eb5ff,0xff2db4ff,0xff2db5ff,0xff2cb4ff,0xff2cb3ff,0xff2bb3ff,0xff2ab3ff,0xff2ab2ff,0xff2ab2ff,0xff29b2ff,
+ 0xff28b2ff,0xff28b2ff,0xff27b1ff,0xff27b1ff,0xff26b1ff,0xff26b0ff,0xff26b0ff,0xff25afff,0xff25b0ff,0xff26b0ff,0xff26b1ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,
+ 0xff28b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff40bfff,0xff61ccff,0xff51c5ff,0xff41bfff,0xff41bfff,0xff42c1ff,0xff42c1ff,0xff43c1ff,0xff44c1ff,0xff44c1ff,
+ 0xff45c2ff,0xff45c2ff,0xff45c3ff,0xff46c2ff,0xff47c3ff,0xff47c5ff,0xff47c5ff,0xff48c5ff,0xff48c5ff,0xff68cfff,0xff46c3ff,0xff46c2ff,0xff56c8ff,0xff45c2ff,
+ 0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,0xff42c1ff,0xff42c0ff,0xff42c0ff,0xff41c0ff,0xff51c5ff,0xff41bfff,0xff41bfff,0xff41bdff,0xff50c3ff,0xff3fbdff,
+ 0xff3fbcff,0xff3ebcff,0xff5fc9ff,0xff3dbcff,0xff3cbbff,0xff4cc1ff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,0xff3abaff,0xff3ab9ff,0xff49c0ff,0xff3ab8ff,0xff39b8ff,
+ 0xff38b7ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,0xff37b5ff,0xff36b5ff,0xff36b5ff,0xff35b4ff,0xff34b4ff,0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff55c1ff,0xff32b3ff,
+ 0xff32b3ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,0xff30b1ff,0xff2fb0ff,0xff2eb1ff,0xff2eaeff,0xff2eaeff,0xff2eb0ff,0xff3fb5ff,0xff2daeff,0xff2dadff,
+ 0xff4fbdff,0xff4fbdff,0xff2bacff,0xff2aacff,0xff2aacff,0xff4dbbff,0xff29abff,0xff28aaff,0xff28abff,0xff28aaff,0xff27aaff,0xff28aaff,0xff26aaff,0xff26a8ff,
+ 0xff26a9ff,0xff26a8ff,0xff49b8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,
+ 0xff32acff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1ea1ff,0xff42b3ff,0xff1ea1ff,0xff1da1ff,0xff2eaaff,0xff1ca0ff,0xff1ca0ff,0xff41b1ff,0xff1b9fff,0xff1ca0ff,
+ 0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa1ff,0xff1fa2ff,0xff4fcaff,0xff50cbff,0xff51caff,0xff74d5ff,0xff75d6ff,0xff52ccff,0xff53ccff,0xff53ccff,
+ 0xff53ccff,0xff54cdff,0xff55cdff,0xff55ceff,0xff56ceff,0xff56ceff,0xff57cfff,0xff57ceff,0xff57cfff,0xff58cfff,0xff59d0ff,0xff59d0ff,0xff7bd9ff,0xff59cfff,
+ 0xff57cfff,0xff57cfff,0xff79d9ff,0xff56ceff,0xff55ceff,0xff55cdff,0xff54ceff,0xff55ccff,0xff53cdff,0xff53ccff,0xff53ccff,0xff52cbff,0xff63d0ff,0xff51cbff,
+ 0xff50cbff,0xff50caff,0xff73d5ff,0xff4fc9ff,0xff4fc9ff,0xff72d4ff,0xff4ec9ff,0xff4dc9ff,0xff4dc8ff,0xff6fd3ff,0xff4cc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac7ff,
+ 0xff4ac6ff,0xff6ed1ff,0xff48c6ff,0xff48c5ff,0xff47c4ff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff44c2ff,0xff43c3ff,0xff43c2ff,0xff43c2ff,
+ 0xff43c2ff,0xff42c2ff,0xff68cdff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff40c0ff,0xff3ec0ff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3bbdff,
+ 0xff3bbdff,0xff62caff,0xff3abcff,0xff62caff,0xff39bbff,0xff39bcff,0xff60c9ff,0xff38bbff,0xff37bbff,0xff5fc8ff,0xff36baff,0xff35baff,0xff35b9ff,0xff35b9ff,
+ 0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff5bc5ff,0xff31b7ff,0xff30b6ff,0xff2fb7ff,0xff2fb6ff,0xff2fb5ff,0xff2fb6ff,0xff2db5ff,0xff2db4ff,
+ 0xff2db4ff,0xff2db4ff,0xff2cb4ff,0xff2bb3ff,0xff56c2ff,0xff2ab3ff,0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff53c1ff,0xff28b1ff,0xff28b1ff,0xff3db9ff,0xff27b0ff,
+ 0xff26b0ff,0xff51c0ff,0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff61cbff,0xff41bfff,
+ 0xff62ccff,0xff62ccff,0xff62ccff,0xff52c6ff,0xff63ccff,0xff63ccff,0xff64ceff,0xff44c2ff,0xff76d4ff,0xff65ceff,0xff56c8ff,0xff66ceff,0xff67cfff,0xff67cfff,
+ 0xff47c3ff,0xff48c5ff,0xff67cfff,0xff47c3ff,0xff66cfff,0xff66cfff,0xff76d4ff,0xff55c8ff,0xff65ceff,0xff65ceff,0xff54c7ff,0xff63ccff,0xff42c0ff,0xff63ccff,
+ 0xff42bfff,0xff51c6ff,0xff62ccff,0xff41bdff,0xff60cbff,0xff60cbff,0xff71d0ff,0xff3fbcff,0xff3ebcff,0xff5fc9ff,0xff3ebbff,0xff5ec8ff,0xff5dc8ff,0xff6ecfff,
+ 0xff4bc1ff,0xff5cc7ff,0xff5cc6ff,0xff4ac1ff,0xff5bc6ff,0xff6dccff,0xff49bfff,0xff49bfff,0xff5bc6ff,0xff5ac5ff,0xff48bdff,0xff6accff,0xff59c5ff,0xff58c3ff,
+ 0xff58c2ff,0xff35b4ff,0xff34b4ff,0xff56c2ff,0xff33b4ff,0xff56c1ff,0xff33b3ff,0xff54c1ff,0xff55c1ff,0xff54c1ff,0xff41b9ff,0xff66c7ff,0xff53c0ff,0xff53c0ff,
+ 0xff40b8ff,0xff52bfff,0xff51bdff,0xff40b8ff,0xff51bdff,0xff62c6ff,0xff3eb5ff,0xff4fbdff,0xff2cadff,0xff2cacff,0xff2bacff,0xff2bacff,0xff4cbcff,0xff29abff,
+ 0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27aaff,0xff26a9ff,0xff26a8ff,0xff49b8ff,0xff25a8ff,0xff5cc0ff,0xff49b8ff,0xff48b8ff,
+ 0xff48b7ff,0xff47b7ff,0xff46b7ff,0xff34adff,0xff46b5ff,0xff46b5ff,0xff45b5ff,0xff32acff,0xff59bdff,0xff45b4ff,0xff20a2ff,0xff1fa2ff,0xff43b3ff,0xff1ea1ff,
+ 0xff1da1ff,0xff2faaff,0xff41b3ff,0xff1ca0ff,0xff1c9fff,0xff41b2ff,0xff1ba0ff,0xff41b2ff,0xff41b3ff,0xff41b3ff,0xff30aaff,0xff42b3ff,0xff43b3ff,0xff43b3ff,
+ 0xff50caff,0xff51caff,0xff73d5ff,0xff51cbff,0xff74d6ff,0xff52ccff,0xff53ccff,0xff76d7ff,0xff76d7ff,0xff55cdff,0xff77d7ff,0xff56cdff,0xff78d8ff,0xff79d8ff,
+ 0xff79d8ff,0xff89ddff,0xff79d9ff,0xff8addff,0xff59cfff,0xff6ad5ff,0xff6ad5ff,0xff58cfff,0xff79d9ff,0xff57cfff,0xff78d9ff,0xff56ceff,0xff77d8ff,0xff77d7ff,
+ 0xff77d8ff,0xff65d2ff,0xff64d1ff,0xff76d7ff,0xff53ccff,0xff52cbff,0xff75d6ff,0xff51cbff,0xff74d6ff,0xff50cbff,0xff73d5ff,0xff4fc9ff,0xff61ceff,0xff60ceff,
+ 0xff4dc9ff,0xff71d4ff,0xff4dc8ff,0xff70d2ff,0xff6fd2ff,0xff4bc7ff,0xff4ac7ff,0xff6fd1ff,0xff49c6ff,0xff6ed1ff,0xff49c6ff,0xff6cd1ff,0xff47c5ff,0xff6bd0ff,
+ 0xff47c4ff,0xff6bd0ff,0xff46c4ff,0xff6ad0ff,0xff6acfff,0xff43c3ff,0xff43c3ff,0xff69ceff,0xff42c2ff,0xff68cdff,0xff41c1ff,0xff67cdff,0xff40c0ff,0xff3fc0ff,
+ 0xff66cdff,0xff65cdff,0xff3ebfff,0xff64cbff,0xff64ccff,0xff63cbff,0xff63cbff,0xff63cbff,0xff3bbdff,0xff63caff,0xff3abdff,0xff61caff,0xff39bcff,0xff38bcff,
+ 0xff38bcff,0xff38baff,0xff5fc8ff,0xff36baff,0xff35baff,0xff35baff,0xff34b9ff,0xff35b9ff,0xff34b9ff,0xff33b9ff,0xff33b8ff,0xff33b8ff,0xff46beff,0xff46beff,
+ 0xff30b7ff,0xff5ac5ff,0xff30b6ff,0xff5ac5ff,0xff58c5ff,0xff2eb6ff,0xff2eb5ff,0xff57c4ff,0xff6ccbff,0xff57c3ff,0xff6bcaff,0xff2bb4ff,0xff56c2ff,0xff2bb2ff,
+ 0xff2ab2ff,0xff2ab2ff,0xff53c1ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff52c0ff,0xff26b0ff,0xff26b0ff,0xff51c0ff,0xff25b0ff,0xff52c0ff,0xff27b1ff,0xff27b1ff,
+ 0xff3eb9ff,0xff3eb9ff,0xff53c1ff,0xff69c9ff,0xff3fbdff,0xff50c5ff,0xff50c3ff,0xff41bfff,0xff62ccff,0xff42bfff,0xff41c0ff,0xff63ccff,0xff63cdff,0xff43c1ff,
+ 0xff64cdff,0xff44c1ff,0xff65ceff,0xff65ceff,0xff66ceff,0xff66cfff,0xff47c3ff,0xff57cbff,0xff48c3ff,0xff68cfff,0xff48c5ff,0xff47c3ff,0xff67cfff,0xff46c3ff,
+ 0xff76d4ff,0xff65ceff,0xff44c2ff,0xff44c2ff,0xff63cdff,0xff43c1ff,0xff63ccff,0xff52c6ff,0xff41c0ff,0xff41c0ff,0xff62ccff,0xff41bfff,0xff61ccff,0xff40bdff,
+ 0xff71d0ff,0xff3fbdff,0xff5fc9ff,0xff3ebcff,0xff3dbcff,0xff5ec8ff,0xff3cbbff,0xff6ecfff,0xff5cc8ff,0xff3bbaff,0xff3abaff,0xff5cc6ff,0xff3ab9ff,0xff5bc6ff,
+ 0xff49bfff,0xff39b8ff,0xff6cccff,0xff48bdff,0xff37b7ff,0xff59c5ff,0xff36b5ff,0xff58c3ff,0xff58c3ff,0xff35b5ff,0xff45bbff,0xff57c2ff,0xff45baff,0xff44bbff,
+ 0xff33b3ff,0xff55c1ff,0xff42baff,0xff31b2ff,0xff54c1ff,0xff54c0ff,0xff31b1ff,0xff52c0ff,0xff52bfff,0xff2eb0ff,0xff2fb0ff,0xff40b7ff,0xff2eaeff,0xff50bdff,
+ 0xff3eb5ff,0xff50bdff,0xff2cadff,0xff2cacff,0xff4ebcff,0xff3cb4ff,0xff3ab4ff,0xff2aabff,0xff29abff,0xff28aaff,0xff3ab2ff,0xff28aaff,0xff28aaff,0xff38b1ff,
+ 0xff27a9ff,0xff26a8ff,0xff49b8ff,0xff25a8ff,0xff25a8ff,0xff5bc0ff,0xff24a7ff,0xff48b8ff,0xff48b7ff,0xff23a5ff,0xff23a5ff,0xff46b5ff,0xff46b7ff,0xff21a4ff,
+ 0xff32adff,0xff20a3ff,0xff45b4ff,0xff20a2ff,0xff31acff,0xff31abff,0xff31abff,0xff1ea1ff,0xff1ea1ff,0xff1da0ff,0xff41b2ff,0xff1ca0ff,0xff1ba0ff,0xff41b2ff,
+ 0xff1c9fff,0xff41b2ff,0xff1da1ff,0xff1da0ff,0xff1ea1ff,0xff42b3ff,0xff1fa2ff,0xff43b3ff,0xff4fcaff,0xff73d5ff,0xff50caff,0xff51cbff,0xff63d0ff,0xff52ccff,
+ 0xff53ccff,0xff64d1ff,0xff64d1ff,0xff76d7ff,0xff66d2ff,0xff55ceff,0xff66d3ff,0xff57ceff,0xff68d4ff,0xff68d4ff,0xff7ad9ff,0xff69d4ff,0xff6ad4ff,0xff6ad5ff,
+ 0xff59cfff,0xff58cfff,0xff69d4ff,0xff79d9ff,0xff68d4ff,0xff57ceff,0xff77d8ff,0xff77d8ff,0xff65d2ff,0xff54cdff,0xff64d2ff,0xff53ccff,0xff53ccff,0xff75d6ff,
+ 0xff74d6ff,0xff62d0ff,0xff62cfff,0xff73d5ff,0xff62cfff,0xff61ceff,0xff60ceff,0xff4ec9ff,0xff4ec9ff,0xff5fceff,0xff71d3ff,0xff5ecdff,0xff4bc7ff,0xff6fd2ff,
+ 0xff6fd1ff,0xff4ac6ff,0xff49c6ff,0xff5acbff,0xff5acbff,0xff6dd1ff,0xff5acbff,0xff6cd1ff,0xff5acaff,0xff59caff,0xff45c4ff,0xff58caff,0xff44c3ff,0xff6acfff,
+ 0xff56c8ff,0xff56c8ff,0xff68ceff,0xff42c1ff,0xff41c1ff,0xff66cdff,0xff53c6ff,0xff66cdff,0xff3fc0ff,0xff52c5ff,0xff3ebfff,0xff51c5ff,0xff3ebfff,0xff64cbff,
+ 0xff63cbff,0xff3bbeff,0xff3bbdff,0xff4fc4ff,0xff4ec4ff,0xff39bcff,0xff61caff,0xff61c9ff,0xff38bcff,0xff5fc9ff,0xff37bbff,0xff37baff,0xff36baff,0xff4ac0ff,
+ 0xff72ceff,0xff35b9ff,0xff34b9ff,0xff70ceff,0xff47bfff,0xff47beff,0xff47beff,0xff31b7ff,0xff31b7ff,0xff5ac5ff,0xff5ac5ff,0xff44bcff,0xff43bcff,0xff2eb5ff,
+ 0xff2db5ff,0xff43bcff,0xff42bcff,0xff57c3ff,0xff41bbff,0xff2cb3ff,0xff2bb3ff,0xff55c2ff,0xff2ab2ff,0xff54c1ff,0xff28b1ff,0xff28b2ff,0xff27b1ff,0xff52c1ff,
+ 0xff52c0ff,0xff3cb9ff,0xff3bb8ff,0xff51c0ff,0xff52c0ff,0xff3cb8ff,0xff26b0ff,0xff27b1ff,0xff28b1ff,0xff3eb9ff,0xff54c1ff,0xff54c1ff,0xff3fbdff,0xff50c3ff,
+ 0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff43c0ff,0xff43c1ff,0xff43c1ff,0xff45c1ff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff46c3ff,
+ 0xff47c3ff,0xff48c3ff,0xff57cbff,0xff48c5ff,0xff48c5ff,0xff47c5ff,0xff47c3ff,0xff46c2ff,0xff46c2ff,0xff45c2ff,0xff45c1ff,0xff45c2ff,0xff43c1ff,0xff43c1ff,
+ 0xff43c0ff,0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff40bfff,0xff40bdff,0xff4fc2ff,0xff3ebcff,0xff3ebcff,0xff3ebbff,0xff3dbcff,
+ 0xff3cbbff,0xff3cbaff,0xff3cbbff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff39b8ff,0xff5bc6ff,0xff5ac5ff,0xff37b7ff,0xff37b7ff,
+ 0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff33b4ff,0xff44bbff,0xff33b3ff,0xff33b3ff,0xff43baff,0xff33b2ff,0xff32b2ff,0xff31b1ff,0xff31b2ff,
+ 0xff30b1ff,0xff2fb1ff,0xff30b1ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2eadff,0xff2daeff,0xff2dadff,0xff2cadff,0xff2bacff,0xff2badff,0xff3cb4ff,
+ 0xff2aacff,0xff29abff,0xff29abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27aaff,0xff27aaff,0xff27aaff,0xff38b1ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff36b0ff,
+ 0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff22a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff31abff,
+ 0xff1ea2ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,0xff1ba0ff,0xff1ca1ff,0xff1ca0ff,0xff1ea0ff,0xff1da2ff,0xff1ea1ff,
+ 0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff50cbff,0xff51caff,0xff51cbff,0xff51cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff54cdff,0xff55cdff,0xff54cdff,0xff55cdff,
+ 0xff56cdff,0xff56ceff,0xff57ceff,0xff57ceff,0xff7ad9ff,0xff7ad9ff,0xff59d0ff,0xff59d0ff,0xff59d0ff,0xff59d0ff,0xff69d4ff,0xff79d9ff,0xff67d3ff,0xff56ceff,
+ 0xff56ceff,0xff55cdff,0xff55cdff,0xff54cdff,0xff54ccff,0xff53ccff,0xff53ccff,0xff52ccff,0xff51ccff,0xff51cbff,0xff51caff,0xff50caff,0xff50caff,0xff4fc9ff,
+ 0xff4fc9ff,0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff4bc7ff,0xff4bc7ff,0xff4ac6ff,0xff4ac6ff,0xff4ac7ff,0xff49c6ff,0xff48c5ff,0xff47c5ff,
+ 0xff48c4ff,0xff47c5ff,0xff47c4ff,0xff45c4ff,0xff46c4ff,0xff45c3ff,0xff44c3ff,0xff44c2ff,0xff43c2ff,0xff43c2ff,0xff42c2ff,0xff42c1ff,0xff41c1ff,0xff40c1ff,
+ 0xff41c1ff,0xff40c0ff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3bbeff,0xff3bbdff,0xff3abcff,0xff3abcff,0xff3abcff,
+ 0xff39bcff,0xff39bcff,0xff38bbff,0xff38bbff,0xff37bbff,0xff36baff,0xff35baff,0xff35b9ff,0xff35baff,0xff34b9ff,0xff34b8ff,0xff33b8ff,0xff32b8ff,0xff33b7ff,
+ 0xff47bfff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff30b6ff,0xff44bdff,0xff2eb5ff,0xff2fb5ff,0xff2db5ff,0xff2eb5ff,0xff2db4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb4ff,
+ 0xff2ab3ff,0xff2bb2ff,0xff2ab2ff,0xff29b2ff,0xff28b1ff,0xff28b2ff,0xff28b1ff,0xff27b1ff,0xff26b0ff,0xff3cb8ff,0xff26b0ff,0xff25b0ff,0xff26b0ff,0xff26b0ff,
+ 0xff27b1ff,0xff28b0ff,0xff28b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42c0ff,0xff42c0ff,
+ 0xff63ccff,0xff43c1ff,0xff44c1ff,0xff44c2ff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff47c3ff,0xff67cfff,0xff47c3ff,0xff58cbff,0xff68cfff,0xff67cfff,0xff57cbff,
+ 0xff47c3ff,0xff46c2ff,0xff66cfff,0xff45c2ff,0xff45c2ff,0xff44c2ff,0xff44c1ff,0xff43c1ff,0xff42c0ff,0xff42c1ff,0xff63ccff,0xff41c0ff,0xff41c0ff,0xff41bfff,
+ 0xff41bfff,0xff40bdff,0xff40bdff,0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff3dbcff,0xff3dbbff,0xff3dbbff,0xff3cbaff,0xff3cbbff,0xff3bbbff,0xff5cc6ff,0xff3ab9ff,
+ 0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff39b9ff,0xff38b8ff,0xff38b8ff,0xff37b7ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff34b5ff,0xff57c2ff,
+ 0xff33b3ff,0xff55c2ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,0xff30b1ff,0xff2fb0ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,
+ 0xff2eaeff,0xff50bdff,0xff2dadff,0xff2dadff,0xff2cadff,0xff2bacff,0xff2badff,0xff2bacff,0xff2aabff,0xff2aabff,0xff29abff,0xff28aaff,0xff28aaff,0xff28aaff,
+ 0xff28aaff,0xff28aaff,0xff27a9ff,0xff26a9ff,0xff26a9ff,0xff49b8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff49b7ff,0xff48b8ff,0xff23a5ff,0xff23a5ff,0xff22a5ff,
+ 0xff22a4ff,0xff21a4ff,0xff20a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa3ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff1da0ff,0xff2fa9ff,0xff2ea9ff,
+ 0xff1ca0ff,0xff1ba0ff,0xff41b2ff,0xff1ca0ff,0xff1da1ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff50c9ff,0xff62cfff,0xff62d0ff,0xff62d0ff,
+ 0xff52cbff,0xff75d6ff,0xff75d6ff,0xff54ccff,0xff76d7ff,0xff54cdff,0xff65d2ff,0xff55ceff,0xff78d8ff,0xff78d8ff,0xff57ceff,0xff57cfff,0xff7ad9ff,0xff58cfff,
+ 0xff69d5ff,0xff59d0ff,0xff58d0ff,0xff7ad9ff,0xff58cfff,0xff57ceff,0xff78d8ff,0xff56ceff,0xff67d3ff,0xff89dcff,0xff54cdff,0xff54ccff,0xff53cdff,0xff53ccff,
+ 0xff75d6ff,0xff52cbff,0xff52cbff,0xff51cbff,0xff62cfff,0xff73d5ff,0xff61cfff,0xff4fcaff,0xff72d4ff,0xff72d4ff,0xff4dc9ff,0xff5fcdff,0xff4dc8ff,0xff5ecdff,
+ 0xff4bc7ff,0xff5dcdff,0xff5cccff,0xff4ac7ff,0xff5bccff,0xff6ed1ff,0xff5accff,0xff48c5ff,0xff6dd1ff,0xff5acaff,0xff59caff,0xff45c4ff,0xff46c4ff,0xff45c3ff,
+ 0xff44c3ff,0xff6acfff,0xff56c9ff,0xff68ceff,0xff43c1ff,0xff68ceff,0xff41c0ff,0xff54c7ff,0xff53c7ff,0xff66cdff,0xff3fbfff,0xff52c6ff,0xff66ccff,0xff51c5ff,
+ 0xff3dbeff,0xff64cbff,0xff63cbff,0xff3cbeff,0xff63cbff,0xff76d0ff,0xff4ec3ff,0xff39bcff,0xff61caff,0xff60c9ff,0xff38bbff,0xff4cc2ff,0xff5fc9ff,0xff4ac1ff,
+ 0xff4ac1ff,0xff35baff,0xff35b9ff,0xff49c0ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff45bdff,0xff44bdff,
+ 0xff59c5ff,0xff44bcff,0xff58c4ff,0xff2db4ff,0xff42bcff,0xff57c3ff,0xff41bbff,0xff2bb3ff,0xff56c2ff,0xff3fbbff,0xff2ab2ff,0xff3fbaff,0xff54c1ff,0xff3eb9ff,
+ 0xff28b1ff,0xff27b0ff,0xff52c1ff,0xff26b0ff,0xff3bb8ff,0xff51c0ff,0xff52c0ff,0xff26b0ff,0xff52c1ff,0xff52c0ff,0xff27b2ff,0xff3eb9ff,0xff28b1ff,0xff3fbaff,
+ 0xff40bdff,0xff60cbff,0xff61ccff,0xff61ccff,0xff51c5ff,0xff41bfff,0xff41c0ff,0xff63ccff,0xff63cdff,0xff63cdff,0xff43c1ff,0xff64ceff,0xff45c2ff,0xff45c2ff,
+ 0xff65cfff,0xff46c3ff,0xff67cfff,0xff47c3ff,0xff48c3ff,0xff48c5ff,0xff67cfff,0xff47c3ff,0xff46c3ff,0xff46c3ff,0xff66ceff,0xff45c2ff,0xff44c1ff,0xff54c7ff,
+ 0xff43c1ff,0xff43c1ff,0xff42c1ff,0xff42c0ff,0xff63ccff,0xff41bfff,0xff41bfff,0xff41bfff,0xff61ccff,0xff40bdff,0xff60cbff,0xff4fc2ff,0xff3ebcff,0xff3ebcff,
+ 0xff5ec9ff,0xff5ec8ff,0xff3cbbff,0xff5dc8ff,0xff3bbbff,0xff3bbaff,0xff5cc7ff,0xff3abaff,0xff6dcdff,0xff39b9ff,0xff5bc6ff,0xff5ac6ff,0xff39b8ff,0xff59c5ff,
+ 0xff37b7ff,0xff37b5ff,0xff36b5ff,0xff36b7ff,0xff58c3ff,0xff35b5ff,0xff45bbff,0xff57c2ff,0xff33b4ff,0xff56c1ff,0xff33b3ff,0xff55c1ff,0xff42b9ff,0xff32b2ff,
+ 0xff54c0ff,0xff53c0ff,0xff30b1ff,0xff53c0ff,0xff52bfff,0xff2fb0ff,0xff2eb0ff,0xff3fb8ff,0xff2eaeff,0xff50bdff,0xff2dadff,0xff50bdff,0xff2cadff,0xff2cadff,
+ 0xff4ebcff,0xff60c3ff,0xff2aacff,0xff4cbbff,0xff4cbbff,0xff28abff,0xff28aaff,0xff4bbaff,0xff28aaff,0xff27aaff,0xff26a9ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,
+ 0xff25a8ff,0xff25a7ff,0xff48b8ff,0xff24a7ff,0xff48b7ff,0xff35aeff,0xff22a5ff,0xff46b5ff,0xff46b5ff,0xff21a4ff,0xff46b5ff,0xff20a4ff,0xff44b4ff,0xff45b4ff,
+ 0xff44b3ff,0xff43b4ff,0xff1fa1ff,0xff42b3ff,0xff1da1ff,0xff1da1ff,0xff41b3ff,0xff1ca0ff,0xff41b2ff,0xff1b9fff,0xff55bbff,0xff2ea9ff,0xff1da0ff,0xff1da1ff,
+ 0xff42b3ff,0xff43b3ff,0xff1fa2ff,0xff43b3ff,0xff50caff,0xff73d5ff,0xff74d6ff,0xff74d6ff,0xff63d0ff,0xff75d6ff,0xff76d6ff,0xff76d7ff,0xff87dbff,0xff76d7ff,
+ 0xff54cdff,0xff77d8ff,0xff77d8ff,0xff78d8ff,0xff68d3ff,0xff57cfff,0xff7ad9ff,0xff59cfff,0xff59cfff,0xff6bd5ff,0xff69d4ff,0xff58cfff,0xff58cfff,0xff58cfff,
+ 0xff79d8ff,0xff56ceff,0xff56cdff,0xff66d2ff,0xff55cdff,0xff54cdff,0xff54cdff,0xff53ccff,0xff75d6ff,0xff52cbff,0xff52ccff,0xff51cbff,0xff84daff,0xff73d5ff,
+ 0xff72d5ff,0xff61cfff,0xff72d5ff,0xff72d4ff,0xff71d4ff,0xff4dc9ff,0xff71d3ff,0xff70d2ff,0xff4bc7ff,0xff4bc7ff,0xff6fd2ff,0xff4ac7ff,0xff6ed1ff,0xff49c5ff,
+ 0xff6ed1ff,0xff5accff,0xff6dd1ff,0xff6cd1ff,0xff46c4ff,0xff46c3ff,0xff45c3ff,0xff45c3ff,0xff6acfff,0xff44c2ff,0xff43c2ff,0xff69ceff,0xff42c2ff,0xff68cdff,
+ 0xff41c1ff,0xff67cdff,0xff40c0ff,0xff3fc0ff,0xff3fc0ff,0xff78d3ff,0xff65ccff,0xff64cbff,0xff65ccff,0xff3cbeff,0xff3cbdff,0xff3cbeff,0xff3bbdff,0xff63caff,
+ 0xff3abcff,0xff61caff,0xff39bcff,0xff38bbff,0xff60c9ff,0xff5fc9ff,0xff37baff,0xff36baff,0xff5ec8ff,0xff36b9ff,0xff49c1ff,0xff5ec7ff,0xff34b8ff,0xff33b8ff,
+ 0xff33b8ff,0xff32b7ff,0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff30b7ff,0xff5ac5ff,0xff2fb6ff,0xff59c4ff,0xff2eb5ff,0xff2eb5ff,0xff57c4ff,0xff57c3ff,0xff2db4ff,
+ 0xff56c3ff,0xff2bb4ff,0xff55c2ff,0xff55c2ff,0xff55c1ff,0xff69c9ff,0xff54c1ff,0xff53c1ff,0xff28b1ff,0xff52c1ff,0xff27b1ff,0xff26b0ff,0xff51c0ff,0xff25afff,
+ 0xff51c0ff,0xff3cb8ff,0xff52c0ff,0xff52c1ff,0xff53c1ff,0xff28b1ff,0xff54c1ff,0xff54c1ff,0xff40bdff,0xff60cbff,0xff50c3ff,0xff61ccff,0xff51c5ff,0xff62ccff,
+ 0xff63ccff,0xff63ccff,0xff63cdff,0xff43c1ff,0xff64ceff,0xff55c7ff,0xff65ceff,0xff65ceff,0xff56c9ff,0xff46c3ff,0xff67cfff,0xff47c3ff,0xff58c9ff,0xff78d5ff,
+ 0xff67cfff,0xff57c9ff,0xff47c3ff,0xff46c2ff,0xff66ceff,0xff45c2ff,0xff54c7ff,0xff75d3ff,0xff44c1ff,0xff43c0ff,0xff43c1ff,0xff42c0ff,0xff62ccff,0xff62ccff,
+ 0xff62ccff,0xff50c3ff,0xff60cbff,0xff60cbff,0xff5fcbff,0xff4fc3ff,0xff5fc9ff,0xff5fc9ff,0xff5fc9ff,0xff3dbcff,0xff5dc8ff,0xff3cbaff,0xff3bbaff,0xff5cc7ff,
+ 0xff6eceff,0xff4ac0ff,0xff5bc6ff,0xff3ab8ff,0xff5bc6ff,0xff49bfff,0xff5ac6ff,0xff5ac6ff,0xff37b7ff,0xff36b7ff,0xff37b5ff,0xff36b5ff,0xff46bcff,0xff58c2ff,
+ 0xff58c2ff,0xff57c2ff,0xff45bbff,0xff67c9ff,0xff55c1ff,0xff55c1ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff54c1ff,0xff53c0ff,0xff53c0ff,0xff40b8ff,0xff52bfff,
+ 0xff51bfff,0xff40b8ff,0xff2eaeff,0xff51bdff,0xff50bdff,0xff3eb5ff,0xff4fbdff,0xff4fbdff,0xff3cb4ff,0xff4ebcff,0xff29acff,0xff29abff,0xff29abff,0xff4cbaff,
+ 0xff3ab2ff,0xff4bbaff,0xff28aaff,0xff28a9ff,0xff27a9ff,0xff26a8ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff49b8ff,0xff24a8ff,0xff24a5ff,0xff48b7ff,0xff23a5ff,
+ 0xff22a5ff,0xff46b5ff,0xff46b5ff,0xff46b5ff,0xff46b5ff,0xff21a3ff,0xff44b4ff,0xff31abff,0xff44b3ff,0xff43b3ff,0xff43b3ff,0xff42b3ff,0xff1ea1ff,0xff41b2ff,
+ 0xff1da0ff,0xff1ca1ff,0xff41b2ff,0xff41b2ff,0xff55baff,0xff2eaaff,0xff41b2ff,0xff41b3ff,0xff42b3ff,0xff1ea2ff,0xff43b3ff,0xff1fa2ff,0xff4fcaff,0xff50cbff,
+ 0xff51cbff,0xff52caff,0xff52cbff,0xff53cbff,0xff53ccff,0xff53ccff,0xff54cdff,0xff54cdff,0xff55cdff,0xff55ceff,0xff55ceff,0xff56ceff,0xff56ceff,0xff57cfff,
+ 0xff8addff,0xff7ad9ff,0xff59d0ff,0xff59d0ff,0xff59d0ff,0xff59cfff,0xff68d4ff,0xff79d9ff,0xff79d9ff,0xff56ceff,0xff56ceff,0xff55cdff,0xff54cdff,0xff55cdff,
+ 0xff54ccff,0xff53ccff,0xff52ccff,0xff52cbff,0xff51cbff,0xff51cbff,0xff50cbff,0xff50caff,0xff50c9ff,0xff4fcaff,0xff4fc9ff,0xff4ec9ff,0xff4dc9ff,0xff4dc8ff,
+ 0xff4dc8ff,0xff4cc8ff,0xff4cc7ff,0xff4bc7ff,0xff4ac6ff,0xff4ac6ff,0xff4ac6ff,0xff49c6ff,0xff48c6ff,0xff5accff,0xff6cd1ff,0xff6bd0ff,0xff59caff,0xff46c4ff,
+ 0xff45c4ff,0xff45c3ff,0xff44c2ff,0xff43c3ff,0xff43c2ff,0xff43c2ff,0xff42c1ff,0xff41c1ff,0xff41c1ff,0xff41c0ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,
+ 0xff3ebfff,0xff3dbfff,0xff3ebfff,0xff3cbeff,0xff3cbeff,0xff3bbeff,0xff3bbdff,0xff3bbdff,0xff3abcff,0xff39bdff,0xff39bcff,0xff38bbff,0xff38bbff,0xff38baff,
+ 0xff37bbff,0xff36bbff,0xff4ac1ff,0xff5ec8ff,0xff5ec7ff,0xff48c0ff,0xff34b8ff,0xff33b9ff,0xff32b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff5ac5ff,
+ 0xff30b6ff,0xff30b6ff,0xff2fb5ff,0xff2eb6ff,0xff2db4ff,0xff2db5ff,0xff2db4ff,0xff2cb4ff,0xff2cb3ff,0xff2bb3ff,0xff2ab3ff,0xff2bb3ff,0xff29b2ff,0xff29b2ff,
+ 0xff29b2ff,0xff28b1ff,0xff53c1ff,0xff27b0ff,0xff26b1ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,
+ 0xff28b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bdff,0xff41bfff,0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff43c1ff,0xff43c1ff,0xff44c2ff,
+ 0xff45c2ff,0xff46c2ff,0xff46c2ff,0xff47c3ff,0xff47c3ff,0xff47c5ff,0xff48c3ff,0xff48c5ff,0xff48c5ff,0xff47c3ff,0xff47c3ff,0xff46c2ff,0xff46c2ff,0xff46c2ff,
+ 0xff44c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,0xff42c1ff,0xff42c0ff,0xff42c0ff,0xff41c0ff,0xff41c0ff,0xff41bfff,0xff40bfff,0xff40bdff,0xff40bdff,0xff3fbcff,
+ 0xff3fbdff,0xff3ebcff,0xff3dbbff,0xff3cbcff,0xff3cbbff,0xff3bbbff,0xff3cbbff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff39b8ff,
+ 0xff38b8ff,0xff38b8ff,0xff38b7ff,0xff37b7ff,0xff36b5ff,0xff36b7ff,0xff35b5ff,0xff34b5ff,0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,
+ 0xff33b2ff,0xff32b2ff,0xff31b2ff,0xff31b2ff,0xff30b1ff,0xff2fb1ff,0xff30b0ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2daeff,0xff2daeff,0xff2dadff,
+ 0xff2cadff,0xff2bacff,0xff2badff,0xff2bacff,0xff2aacff,0xff2aabff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a9ff,
+ 0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff22a4ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,
+ 0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca1ff,0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,
+ 0xff1ca0ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff50caff,0xff62cfff,0xff50cbff,0xff62d0ff,0xff51cbff,0xff52cbff,0xff52ccff,0xff53ccff,
+ 0xff65d2ff,0xff54ccff,0xff54cdff,0xff55ceff,0xff55cdff,0xff68d3ff,0xff56ceff,0xff57ceff,0xff58cfff,0xff58cfff,0xff59d0ff,0xff59d0ff,0xff58d0ff,0xff59cfff,
+ 0xff58cfff,0xff57cfff,0xff57ceff,0xff56ceff,0xff55ceff,0xff55cdff,0xff55cdff,0xff54cdff,0xff76d6ff,0xff53ccff,0xff52cbff,0xff63d0ff,0xff62d0ff,0xff51cbff,
+ 0xff50cbff,0xff50caff,0xff4fcaff,0xff4fcaff,0xff4fc9ff,0xff60ceff,0xff4dc8ff,0xff4dc9ff,0xff4cc8ff,0xff4bc8ff,0xff4bc7ff,0xff4bc7ff,0xff4bc7ff,0xff4ac6ff,
+ 0xff49c6ff,0xff49c6ff,0xff5bccff,0xff48c5ff,0xff47c5ff,0xff59cbff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff43c2ff,0xff44c2ff,0xff43c2ff,
+ 0xff43c2ff,0xff42c1ff,0xff41c1ff,0xff41c1ff,0xff53c7ff,0xff3fc0ff,0xff3fc0ff,0xff3ebfff,0xff3fbfff,0xff3ebeff,0xff3dbfff,0xff3cbeff,0xff3cbdff,0xff3cbdff,
+ 0xff3bbdff,0xff3bbdff,0xff3abcff,0xff39bcff,0xff38bcff,0xff39bcff,0xff38bbff,0xff37bbff,0xff37baff,0xff36baff,0xff36baff,0xff36b9ff,0xff35b9ff,0xff35b9ff,
+ 0xff34b9ff,0xff33b9ff,0xff32b8ff,0xff33b7ff,0xff32b7ff,0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb5ff,0xff2db4ff,
+ 0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff27b0ff,0xff26b1ff,
+ 0xff26b0ff,0xff25b0ff,0xff26afff,0xff26b1ff,0xff26b1ff,0xff27b0ff,0xff27b1ff,0xff28b2ff,0xff29b1ff,0xff29b2ff,0xff40bdff,0xff84d7ff,0xff41bfff,0xff85d8ff,
+ 0xff41bfff,0xff41c0ff,0xff41c0ff,0xff42c0ff,0xff63ccff,0xff44c1ff,0xff44c1ff,0xff44c2ff,0xff44c2ff,0xff56c8ff,0xff46c2ff,0xff46c3ff,0xff47c3ff,0xff48c3ff,
+ 0xff48c5ff,0xff48c5ff,0xff48c3ff,0xff47c3ff,0xff47c3ff,0xff46c2ff,0xff45c2ff,0xff45c2ff,0xff45c2ff,0xff44c2ff,0xff44c1ff,0xff43c1ff,0xff63ccff,0xff42c1ff,
+ 0xff42c0ff,0xff41bfff,0xff61ccff,0xff41bfff,0xff40bdff,0xff40bfff,0xff40bdff,0xff3fbdff,0xff3ebcff,0xff4ec2ff,0xff3dbbff,0xff3dbbff,0xff3dbbff,0xff3cbbff,
+ 0xff3cbbff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff3ab8ff,0xff5bc6ff,0xff39b8ff,0xff39b8ff,0xff49bfff,0xff37b7ff,0xff37b5ff,0xff37b7ff,0xff36b7ff,
+ 0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff33b2ff,0xff54c1ff,0xff31b2ff,0xff31b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,
+ 0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2caeff,0xff2cadff,0xff2badff,0xff2badff,0xff2bacff,0xff2aabff,0xff29abff,
+ 0xff29abff,0xff29abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a8ff,0xff26a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a8ff,0xff24a7ff,
+ 0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff22a5ff,0xff22a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,
+ 0xff1ea1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,0xff1ca0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,
+ 0xff4fcaff,0xff73d5ff,0xff97dfff,0xff74d6ff,0xff63d0ff,0xff75d6ff,0xff75d6ff,0xff64d1ff,0xff76d7ff,0xff65d2ff,0xff66d2ff,0xff55ceff,0xff67d3ff,0xff78d8ff,
+ 0xff56ceff,0xff89ddff,0xff79d9ff,0xff7ad9ff,0xff6ad5ff,0xff7bd9ff,0xff7bd9ff,0xff6ad4ff,0xff58cfff,0xff57ceff,0xff57cfff,0xff67d3ff,0xff78d8ff,0xff77d7ff,
+ 0xff66d2ff,0xff54cdff,0xff76d7ff,0xff53ccff,0xff52ccff,0xff52cbff,0xff75d6ff,0xff51cbff,0xff51cbff,0xff50caff,0xff50caff,0xff4fc9ff,0xff61ceff,0xff72d4ff,
+ 0xff4dc9ff,0xff82d9ff,0xff71d3ff,0xff70d3ff,0xff4cc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,0xff6ed1ff,0xff6ed1ff,0xff80d6ff,0xff48c5ff,0xff5acaff,0xff6cd0ff,
+ 0xff47c4ff,0xff7dd6ff,0xff6ad0ff,0xff6acfff,0xff57c9ff,0xff69ceff,0xff69ceff,0xff56c8ff,0xff7bd3ff,0xff68cdff,0xff67cdff,0xff54c7ff,0xff79d3ff,0xff66cdff,
+ 0xff3fbfff,0xff3fbfff,0xff3ebfff,0xff3dbfff,0xff3dbfff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3bbcff,0xff3abdff,0xff39bcff,0xff39bcff,0xff39bcff,
+ 0xff38bbff,0xff38bbff,0xff37baff,0xff36bbff,0xff36baff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,
+ 0xff30b6ff,0xff30b7ff,0xff30b7ff,0xff2fb6ff,0xff2fb6ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2cb4ff,0xff2db4ff,0xff2cb3ff,0xff2bb3ff,0xff2bb3ff,0xff2ab3ff,
+ 0xff2ab3ff,0xff29b2ff,0xff29b1ff,0xff28b2ff,0xff28b2ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff25b0ff,0xff25b0ff,0xff25b0ff,0xff26b0ff,0xff27b0ff,0xff27b0ff,
+ 0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff29b2ff,0xff3fbdff,0xff60ccff,0xff40bfff,0xff62ccff,0xff41bfff,0xff62ccff,0xff63ccff,0xff63ccff,0xff74d2ff,0xff63cdff,
+ 0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff65ceff,0xff46c3ff,0xff66ceff,0xff47c2ff,0xff67cfff,0xff68cfff,0xff49c5ff,0xff67cfff,0xff47c3ff,0xff46c3ff,0xff46c3ff,
+ 0xff46c2ff,0xff45c2ff,0xff65ceff,0xff65cdff,0xff63cdff,0xff43c1ff,0xff63ccff,0xff42c0ff,0xff41c0ff,0xff41c0ff,0xff62ccff,0xff41bdff,0xff40bfff,0xff40bdff,
+ 0xff3fbdff,0xff3fbdff,0xff3ebdff,0xff5fc9ff,0xff3dbcff,0xff5ec8ff,0xff3cbbff,0xff5dc8ff,0xff3cbbff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,0xff5bc6ff,0xff3ab9ff,
+ 0xff5bc6ff,0xff39b8ff,0xff38b8ff,0xff5ac5ff,0xff37b7ff,0xff59c5ff,0xff36b5ff,0xff47bcff,0xff58c3ff,0xff58c3ff,0xff57c3ff,0xff56c2ff,0xff57c2ff,0xff33b3ff,
+ 0xff56c1ff,0xff32b3ff,0xff54c1ff,0xff31b2ff,0xff31b2ff,0xff31b2ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2daeff,
+ 0xff2daeff,0xff2cadff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2aacff,0xff2aabff,0xff2aabff,0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28a9ff,0xff27aaff,
+ 0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff24a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff22a5ff,0xff23a4ff,0xff22a5ff,0xff22a4ff,
+ 0xff21a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff20a2ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,0xff1ca0ff,0xff1ba0ff,
+ 0xff1b9fff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff4fcaff,0xff73d6ff,0xff51cbff,0xff74d5ff,0xff75d6ff,0xff52cbff,
+ 0xff52ccff,0xff76d6ff,0xff76d6ff,0xff65d2ff,0xff65d2ff,0xff55cdff,0xff56cdff,0xff78d8ff,0xff57ceff,0xff79d9ff,0xff58cfff,0xff7ad9ff,0xff59d0ff,0xff8bdeff,
+ 0xff6ad4ff,0xff58d0ff,0xff57cfff,0xff57cfff,0xff57cfff,0xff78d8ff,0xff55ceff,0xff56cdff,0xff76d8ff,0xff55cdff,0xff76d6ff,0xff54ccff,0xff53ccff,0xff52cbff,
+ 0xff74d6ff,0xff51cbff,0xff51caff,0xff50caff,0xff50caff,0xff4fcaff,0xff4fc9ff,0xff72d4ff,0xff4dc9ff,0xff71d3ff,0xff4dc8ff,0xff70d3ff,0xff4cc8ff,0xff4bc7ff,
+ 0xff4bc7ff,0xff4ac6ff,0xff6fd1ff,0xff49c6ff,0xff7fd7ff,0xff48c5ff,0xff47c5ff,0xff6cd0ff,0xff46c4ff,0xff6bd0ff,0xff45c3ff,0xff45c3ff,0xff6acfff,0xff43c3ff,
+ 0xff44c3ff,0xff56c8ff,0xff68ceff,0xff41c2ff,0xff67cdff,0xff41c0ff,0xff66cdff,0xff40c0ff,0xff52c6ff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,0xff3dbeff,0xff3dbeff,
+ 0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3bbcff,0xff3abdff,0xff39bcff,0xff39bcff,0xff39bcff,0xff38bbff,0xff38bbff,0xff37bbff,0xff37baff,0xff36baff,0xff35baff,
+ 0xff34b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b7ff,0xff32b7ff,0xff31b7ff,0xff31b7ff,0xff2fb6ff,0xff2fb6ff,0xff2eb6ff,0xff2eb5ff,
+ 0xff2eb5ff,0xff2db4ff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab2ff,0xff2ab2ff,0xff2ab2ff,0xff28b2ff,0xff28b2ff,0xff27b1ff,0xff27b1ff,
+ 0xff27b0ff,0xff26b0ff,0xff26afff,0xff25afff,0xff25b0ff,0xff26b0ff,0xff26b1ff,0xff27b1ff,0xff28b1ff,0xff29b2ff,0xff29b1ff,0xff2ab2ff,0xff3fbdff,0xff50c3ff,
+ 0xff40bdff,0xff50c5ff,0xff41bfff,0xff62ccff,0xff62ccff,0xff53c6ff,0xff52c6ff,0xff43c1ff,0xff54c7ff,0xff44c1ff,0xff64ceff,0xff65ceff,0xff56c8ff,0xff57c9ff,
+ 0xff46c3ff,0xff57cbff,0xff68cfff,0xff58cbff,0xff68cfff,0xff58c9ff,0xff46c3ff,0xff46c2ff,0xff46c3ff,0xff45c2ff,0xff65ceff,0xff64cdff,0xff54c7ff,0xff54c6ff,
+ 0xff63ccff,0xff63ccff,0xff42c0ff,0xff62ccff,0xff62ccff,0xff50c3ff,0xff41bdff,0xff40bdff,0xff3fbdff,0xff3fbcff,0xff5fc9ff,0xff5fc9ff,0xff4ec1ff,0xff4dc1ff,
+ 0xff3cbbff,0xff4cc1ff,0xff3bbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff49c0ff,0xff5bc6ff,0xff49c0ff,0xff39b8ff,0xff5bc6ff,0xff5ac6ff,0xff48bdff,0xff48bcff,
+ 0xff37b7ff,0xff36b5ff,0xff35b5ff,0xff57c2ff,0xff58c2ff,0xff33b4ff,0xff44bbff,0xff33b4ff,0xff43baff,0xff33b3ff,0xff33b2ff,0xff54c1ff,0xff31b1ff,0xff31b2ff,
+ 0xff30b1ff,0xff30b1ff,0xff2fb0ff,0xff2fb0ff,0xff2eaeff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2dadff,0xff2cadff,0xff2badff,0xff2cacff,0xff2bacff,0xff2aacff,
+ 0xff2aacff,0xff2aacff,0xff29abff,0xff28abff,0xff28abff,0xff28aaff,0xff27aaff,0xff27a9ff,0xff27a9ff,0xff26a8ff,0xff26a8ff,0xff26a9ff,0xff25a8ff,0xff24a7ff,
+ 0xff24a8ff,0xff24a5ff,0xff24a5ff,0xff24a5ff,0xff23a4ff,0xff22a4ff,0xff21a4ff,0xff21a4ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a2ff,0xff1fa3ff,0xff1fa2ff,
+ 0xff1ea2ff,0xff1fa1ff,0xff1ea1ff,0xff1da1ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1ea2ff,
+ 0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff51caff,0xff51cbff,0xff51cbff,0xff52cbff,0xff53ccff,0xff53ccff,0xff53cdff,0xff54ccff,0xff55cdff,0xff55cdff,
+ 0xff56ceff,0xff57ceff,0xff57ceff,0xff58cfff,0xff57cfff,0xff58d0ff,0xff58cfff,0xff7bd9ff,0xff7bd9ff,0xff58cfff,0xff57cfff,0xff57cfff,0xff57ceff,0xff56ceff,
+ 0xff56ceff,0xff55cdff,0xff55cdff,0xff54ccff,0xff54cdff,0xff53ccff,0xff53cbff,0xff52ccff,0xff52cbff,0xff51cbff,0xff51cbff,0xff50caff,0xff50caff,0xff4fc9ff,
+ 0xff4ecaff,0xff4ec9ff,0xff4dc8ff,0xff4dc9ff,0xff4dc8ff,0xff4cc7ff,0xff4bc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,0xff48c6ff,0xff48c5ff,
+ 0xff47c5ff,0xff46c5ff,0xff46c4ff,0xff46c3ff,0xff46c3ff,0xff45c3ff,0xff45c3ff,0xff43c3ff,0xff43c2ff,0xff43c2ff,0xff42c1ff,0xff41c2ff,0xff41c1ff,0xff41c0ff,
+ 0xff40c1ff,0xff40c0ff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff3bbdff,0xff3abcff,0xff3abcff,
+ 0xff39bcff,0xff39bbff,0xff38bbff,0xff38bbff,0xff36bbff,0xff37bbff,0xff36baff,0xff35baff,0xff35baff,0xff34b9ff,0xff34b8ff,0xff33b8ff,0xff33b9ff,0xff33b8ff,
+ 0xff32b8ff,0xff32b7ff,0xff31b7ff,0xff30b7ff,0xff30b6ff,0xff30b6ff,0xff2fb5ff,0xff2eb6ff,0xff2eb5ff,0xff2db4ff,0xff2db5ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,
+ 0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff29b2ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff25b0ff,0xff25afff,0xff25b0ff,0xff26b0ff,
+ 0xff27b0ff,0xff27b1ff,0xff27b1ff,0xff28b2ff,0xff28b2ff,0xff29b2ff,0xff3fbcff,0xff40bdff,0xff41bdff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff41c0ff,0xff42c0ff,
+ 0xff42c1ff,0xff43c1ff,0xff43c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff46c3ff,0xff67cfff,0xff68cfff,0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff47c3ff,
+ 0xff56c9ff,0xff67ceff,0xff56c8ff,0xff45c2ff,0xff45c2ff,0xff44c1ff,0xff44c2ff,0xff43c1ff,0xff43c0ff,0xff43c0ff,0xff41c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,
+ 0xff40bdff,0xff40bdff,0xff3fbdff,0xff3fbdff,0xff3ebcff,0xff3ebcff,0xff3dbcff,0xff3dbcff,0xff3cbbff,0xff3cbbff,0xff3cbaff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,
+ 0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff39b9ff,0xff39b7ff,0xff38b8ff,0xff37b7ff,0xff37b5ff,0xff36b7ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff35b4ff,0xff33b4ff,
+ 0xff34b4ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff31b2ff,0xff31b2ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2fb1ff,0xff2eb0ff,0xff2eaeff,
+ 0xff2eaeff,0xff2daeff,0xff2daeff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2aacff,0xff2aabff,0xff29acff,0xff29abff,0xff28aaff,0xff28aaff,0xff28aaff,
+ 0xff28a9ff,0xff27a9ff,0xff26aaff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff36aeff,0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff23a5ff,0xff33adff,
+ 0xff21a4ff,0xff21a4ff,0xff20a4ff,0xff20a4ff,0xff20a3ff,0xff20a2ff,0xff20a2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca0ff,0xff1ca1ff,
+ 0xff1ca0ff,0xff1ba0ff,0xff2ea9ff,0xff1ca0ff,0xff1ca1ff,0xff1da1ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff50cbff,0xff51cbff,
+ 0xff52cbff,0xff52cbff,0xff53ccff,0xff54ccff,0xff76d7ff,0xff54cdff,0xff54cdff,0xff55cdff,0xff55ceff,0xff56ceff,0xff57ceff,0xff57cfff,0xff79d9ff,0xff58d0ff,
+ 0xff69d5ff,0xff7bd9ff,0xff7bd9ff,0xff69d4ff,0xff58cfff,0xff58ceff,0xff79d9ff,0xff56ceff,0xff56ceff,0xff55cdff,0xff55cdff,0xff54cdff,0xff53cdff,0xff53ccff,
+ 0xff75d6ff,0xff75d6ff,0xff74d6ff,0xff63d0ff,0xff51cbff,0xff50caff,0xff50caff,0xff4fcaff,0xff72d5ff,0xff4ec9ff,0xff4dc9ff,0xff4dc9ff,0xff4dc8ff,0xff4cc8ff,
+ 0xff4bc7ff,0xff4bc7ff,0xff4ac7ff,0xff4ac7ff,0xff4ac6ff,0xff6ed1ff,0xff48c5ff,0xff48c5ff,0xff47c5ff,0xff47c5ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff45c3ff,
+ 0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff43c2ff,0xff42c1ff,0xff42c1ff,0xff67cdff,0xff41c1ff,0xff41c0ff,0xff66cdff,0xff3fc0ff,0xff3fc0ff,0xff3ebfff,0xff3dbfff,
+ 0xff3dbfff,0xff3cbeff,0xff3cbdff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff3abcff,0xff3abcff,0xff61c9ff,0xff39bbff,0xff38bcff,0xff37bbff,0xff37baff,0xff36baff,
+ 0xff36baff,0xff35b9ff,0xff35b9ff,0xff35b9ff,0xff34b8ff,0xff33b9ff,0xff33b8ff,0xff33b8ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff30b6ff,0xff45beff,0xff44bdff,
+ 0xff2eb5ff,0xff2eb5ff,0xff42bcff,0xff42bcff,0xff57c3ff,0xff2db4ff,0xff2cb3ff,0xff2bb3ff,0xff2bb3ff,0xff2ab2ff,0xff2ab2ff,0xff29b2ff,0xff29b1ff,0xff28b2ff,
+ 0xff27b1ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,0xff25b0ff,0xff25afff,0xff51bfff,0xff26b0ff,0xff27b1ff,0xff28b1ff,0xff53c1ff,0xff28b2ff,0xff29b1ff,0xff29b2ff,
+ 0xff40bdff,0xff50c5ff,0xff50c5ff,0xff50c5ff,0xff41c0ff,0xff62ccff,0xff62ccff,0xff42c0ff,0xff63cdff,0xff43c1ff,0xff53c7ff,0xff44c2ff,0xff64cdff,0xff65ceff,
+ 0xff45c3ff,0xff46c2ff,0xff66cfff,0xff47c3ff,0xff57cbff,0xff48c5ff,0xff47c5ff,0xff67cfff,0xff46c3ff,0xff46c3ff,0xff66cfff,0xff45c2ff,0xff55c7ff,0xff75d3ff,
+ 0xff43c1ff,0xff43c1ff,0xff43c1ff,0xff42c0ff,0xff63ccff,0xff41bfff,0xff41bfff,0xff41bfff,0xff50c5ff,0xff60cbff,0xff50c3ff,0xff4fc3ff,0xff71d0ff,0xff5fc9ff,
+ 0xff3dbcff,0xff4dc1ff,0xff5ec8ff,0xff4cc1ff,0xff4bc1ff,0xff4bc1ff,0xff5cc6ff,0xff3ab9ff,0xff3ab9ff,0xff5bc6ff,0xff39b9ff,0xff49c0ff,0xff49bfff,0xff5ac6ff,
+ 0xff37b7ff,0xff48bdff,0xff59c3ff,0xff46bcff,0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff34b4ff,0xff44bbff,0xff56c2ff,0xff55c1ff,0xff33b3ff,0xff42b9ff,0xff42b9ff,
+ 0xff31b2ff,0xff41b8ff,0xff53c0ff,0xff40b8ff,0xff2fb1ff,0xff52bfff,0xff52bfff,0xff2eaeff,0xff3fb7ff,0xff50bdff,0xff3eb7ff,0xff3db5ff,0xff61c5ff,0xff4ebcff,
+ 0xff2badff,0xff3cb4ff,0xff4dbcff,0xff3ab3ff,0xff3ab3ff,0xff3ab2ff,0xff4cbaff,0xff28aaff,0xff39b1ff,0xff27aaff,0xff38b1ff,0xff27a9ff,0xff26a8ff,0xff25a8ff,
+ 0xff24a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff23a7ff,0xff24a7ff,0xff47b7ff,0xff23a5ff,0xff46b5ff,0xff46b5ff,0xff32acff,0xff20a3ff,0xff44b4ff,0xff44b4ff,
+ 0xff20a2ff,0xff31acff,0xff31abff,0xff30abff,0xff1ea1ff,0xff41b3ff,0xff41b2ff,0xff1ca0ff,0xff1ba0ff,0xff2ea8ff,0xff2ea9ff,0xff1ca0ff,0xff41b2ff,0xff2faaff,
+ 0xff42b3ff,0xff30aaff,0xff43b3ff,0xff31abff,0xff50caff,0xff73d5ff,0xff74d5ff,0xff74d6ff,0xff62d0ff,0xff52ccff,0xff53cbff,0xff76d6ff,0xff76d7ff,0xff76d7ff,
+ 0xff54ceff,0xff78d8ff,0xff56cdff,0xff56ceff,0xff79d8ff,0xff57ceff,0xff79d9ff,0xff59cfff,0xff59cfff,0xff59d0ff,0xff7bd9ff,0xff58d0ff,0xff58cfff,0xff57cfff,
+ 0xff79d8ff,0xff56ceff,0xff56ceff,0xff66d3ff,0xff55cdff,0xff54cdff,0xff54cdff,0xff53ccff,0xff75d6ff,0xff75d6ff,0xff63d0ff,0xff51cbff,0xff84daff,0xff50caff,
+ 0xff73d5ff,0xff4fc9ff,0xff72d4ff,0xff4ec9ff,0xff4ec9ff,0xff71d3ff,0xff4cc8ff,0xff70d2ff,0xff6fd2ff,0xff5dcdff,0xff4bc6ff,0xff6fd1ff,0xff49c6ff,0xff6ed1ff,
+ 0xff48c6ff,0xff6dd1ff,0xff5acaff,0xff47c4ff,0xff6bd0ff,0xff6bd0ff,0xff46c3ff,0xff6ad0ff,0xff44c3ff,0xff44c2ff,0xff43c2ff,0xff43c2ff,0xff68cdff,0xff41c1ff,
+ 0xff7ad3ff,0xff41c1ff,0xff41c0ff,0xff66cdff,0xff3fc0ff,0xff78d3ff,0xff3ebfff,0xff64ccff,0xff65cbff,0xff3dbeff,0xff3cbeff,0xff63cbff,0xff63caff,0xff3bbdff,
+ 0xff4ec4ff,0xff39bcff,0xff61caff,0xff39bcff,0xff38bbff,0xff60c9ff,0xff37bbff,0xff5fc9ff,0xff5ec8ff,0xff4ac1ff,0xff34baff,0xff5dc7ff,0xff5cc7ff,0xff33b9ff,
+ 0xff5cc7ff,0xff32b8ff,0xff31b8ff,0xff31b7ff,0xff31b6ff,0xff31b7ff,0xff2fb6ff,0xff2fb5ff,0xff2fb6ff,0xff2eb5ff,0xff57c4ff,0xff2db5ff,0xff6ccbff,0xff2cb4ff,
+ 0xff56c2ff,0xff56c2ff,0xff2ab3ff,0xff2ab2ff,0xff55c1ff,0xff55c1ff,0xff54c1ff,0xff53c1ff,0xff53c1ff,0xff27b0ff,0xff27b0ff,0xff52c0ff,0xff26b0ff,0xff51bfff,
+ 0xff26b0ff,0xff52c1ff,0xff26b0ff,0xff3db9ff,0xff52c1ff,0xff3eb9ff,0xff28b2ff,0xff54c1ff,0xff3fbdff,0xff60cbff,0xff61ccff,0xff62ccff,0xff50c5ff,0xff62ccff,
+ 0xff63ccff,0xff63cdff,0xff74d3ff,0xff63ccff,0xff44c1ff,0xff64cdff,0xff64ceff,0xff65cfff,0xff55c9ff,0xff46c3ff,0xff67cfff,0xff47c3ff,0xff48c3ff,0xff58cbff,
+ 0xff58c9ff,0xff47c5ff,0xff47c3ff,0xff46c3ff,0xff65cfff,0xff46c2ff,0xff45c2ff,0xff55c7ff,0xff44c1ff,0xff43c0ff,0xff43c0ff,0xff42c0ff,0xff62ccff,0xff42c0ff,
+ 0xff41c0ff,0xff41bfff,0xff60ccff,0xff40bdff,0xff5fcbff,0xff3fbcff,0xff5fc9ff,0xff3ebbff,0xff3ebbff,0xff6fcfff,0xff5ec8ff,0xff5dc8ff,0xff5dc8ff,0xff3bbaff,
+ 0xff3abaff,0xff3abaff,0xff3abaff,0xff5bc6ff,0xff39b8ff,0xff5ac6ff,0xff38b8ff,0xff37b7ff,0xff59c5ff,0xff58c3ff,0xff58c5ff,0xff47bcff,0xff36b5ff,0xff35b5ff,
+ 0xff35b4ff,0xff34b4ff,0xff57c2ff,0xff33b3ff,0xff55c1ff,0xff33b2ff,0xff32b3ff,0xff54c1ff,0xff31b2ff,0xff53c0ff,0xff30b1ff,0xff30b1ff,0xff52c0ff,0xff52bfff,
+ 0xff51bfff,0xff40b7ff,0xff51bfff,0xff2dadff,0xff2daeff,0xff2cadff,0xff4fbdff,0xff2cadff,0xff2bacff,0xff4ebcff,0xff29abff,0xff4cbbff,0xff4cbbff,0xff28abff,
+ 0xff28abff,0xff28aaff,0xff4bbaff,0xff27aaff,0xff5dc1ff,0xff27a9ff,0xff25a9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff47b7ff,
+ 0xff22a4ff,0xff22a4ff,0xff46b5ff,0xff22a4ff,0xff46b5ff,0xff45b5ff,0xff20a3ff,0xff20a3ff,0xff44b3ff,0xff43b3ff,0xff43b3ff,0xff42b3ff,0xff42b3ff,0xff41b3ff,
+ 0xff41b3ff,0xff2ea9ff,0xff1b9fff,0xff41b2ff,0xff1ba0ff,0xff41b2ff,0xff1da1ff,0xff1da1ff,0xff42b3ff,0xff42b3ff,0xff43b3ff,0xff57bcff,0xff4fcaff,0xff73d6ff,
+ 0xff62d0ff,0xff75d6ff,0xff63d0ff,0xff75d6ff,0xff76d6ff,0xff76d6ff,0xff76d7ff,0xff54ccff,0xff76d7ff,0xff66d2ff,0xff77d8ff,0xff78d8ff,0xff68d4ff,0xff58cfff,
+ 0xff79d9ff,0xff58cfff,0xff6ad5ff,0xff8bdeff,0xff7ad9ff,0xff69d4ff,0xff58cfff,0xff57cfff,0xff78d9ff,0xff56ceff,0xff67d3ff,0xff88dcff,0xff54cdff,0xff54cdff,
+ 0xff53cdff,0xff53ccff,0xff75d6ff,0xff75d6ff,0xff74d6ff,0xff62d0ff,0xff73d5ff,0xff50caff,0xff73d5ff,0xff4fcaff,0xff61ceff,0xff72d4ff,0xff5fceff,0xff71d3ff,
+ 0xff70d3ff,0xff70d3ff,0xff6fd3ff,0xff4ac8ff,0xff4ac7ff,0xff49c6ff,0xff5bccff,0xff80d7ff,0xff6dd1ff,0xff6dd1ff,0xff48c5ff,0xff46c4ff,0xff6bd0ff,0xff6bd0ff,
+ 0xff6bcfff,0xff58c9ff,0xff44c3ff,0xff44c2ff,0xff43c2ff,0xff43c2ff,0xff68cdff,0xff68ceff,0xff7ad3ff,0xff41c1ff,0xff67cdff,0xff79d3ff,0xff52c6ff,0xff65cdff,
+ 0xff3ebfff,0xff3dbfff,0xff50c5ff,0xff64cbff,0xff63cbff,0xff4fc4ff,0xff63caff,0xff63caff,0xff62caff,0xff3abcff,0xff4dc3ff,0xff61caff,0xff4cc2ff,0xff5fc9ff,
+ 0xff5fc9ff,0xff5fc8ff,0xff5ec8ff,0xff36baff,0xff35b9ff,0xff35b9ff,0xff48c0ff,0xff5cc6ff,0xff5cc6ff,0xff32b8ff,0xff31b7ff,0xff32b7ff,0xff31b7ff,0xff31b7ff,
+ 0xff30b6ff,0xff2fb6ff,0xff2fb6ff,0xff58c4ff,0xff2eb5ff,0xff2db5ff,0xff57c3ff,0xff2db4ff,0xff56c2ff,0xff41bbff,0xff56c2ff,0xff55c2ff,0xff3fbaff,0xff54c1ff,
+ 0xff3fbaff,0xff54c1ff,0xff3db9ff,0xff52c0ff,0xff52c1ff,0xff3cb8ff,0xff51c0ff,0xff25afff,0xff26afff,0xff3cb8ff,0xff52c0ff,0xff52c1ff,0xff53c1ff,0xff53c1ff,
+ 0xff54c1ff,0xff69c9ff,0xff3fbdff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff43c1ff,0xff44c1ff,0xff44c1ff,
+ 0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff46c3ff,0xff77d4ff,0xff67cfff,0xff48c5ff,0xff48c5ff,0xff48c3ff,0xff47c5ff,0xff57c9ff,0xff66cfff,0xff65ceff,0xff45c2ff,
+ 0xff44c2ff,0xff44c1ff,0xff43c1ff,0xff43c1ff,0xff43c1ff,0xff42c0ff,0xff42bfff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff40bdff,0xff40bfff,0xff40bdff,0xff3fbcff,
+ 0xff3fbcff,0xff3ebcff,0xff3dbbff,0xff3dbcff,0xff3dbbff,0xff3cbaff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff3ab8ff,0xff39b8ff,0xff39b8ff,
+ 0xff39b8ff,0xff38b7ff,0xff37b7ff,0xff59c5ff,0xff58c5ff,0xff58c3ff,0xff35b5ff,0xff35b5ff,0xff34b4ff,0xff33b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,
+ 0xff32b2ff,0xff32b2ff,0xff32b2ff,0xff31b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2cadff,
+ 0xff2cadff,0xff2badff,0xff2badff,0xff2aacff,0xff2aabff,0xff2aabff,0xff29abff,0xff29aaff,0xff28aaff,0xff28aaff,0xff4abaff,0xff4abaff,0xff4ab9ff,0xff26a9ff,
+ 0xff26a9ff,0xff25a9ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff47b8ff,0xff23a7ff,0xff22a5ff,0xff22a5ff,0xff22a4ff,0xff21a4ff,0xff21a3ff,0xff20a3ff,
+ 0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1ea2ff,0xff1ea1ff,0xff1ea1ff,0xff1da0ff,0xff1ca1ff,0xff1ca0ff,0xff41b2ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,
+ 0xff1ca0ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1ea1ff,0xff20a2ff,0xff50caff,0xff50caff,0xff51cbff,0xff51cbff,0xff52cbff,0xff52cbff,0xff53ccff,0xff53ccff,
+ 0xff54cdff,0xff54cdff,0xff55cdff,0xff55cdff,0xff56ceff,0xff56ceff,0xff57cfff,0xff58ceff,0xff57cfff,0xff58cfff,0xff58d0ff,0xff59d0ff,0xff59d0ff,0xff58cfff,
+ 0xff58cfff,0xff57cfff,0xff57cfff,0xff57ceff,0xff56cdff,0xff56cdff,0xff54cdff,0xff54cdff,0xff53ccff,0xff53ccff,0xff53ccff,0xff52ccff,0xff51cbff,0xff51cbff,
+ 0xff50caff,0xff50cbff,0xff4fcaff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,0xff4dc9ff,0xff4dc9ff,0xff4dc8ff,0xff4cc8ff,0xff4bc7ff,0xff4bc7ff,0xff4ac7ff,0xff4ac7ff,
+ 0xff4ac7ff,0xff49c6ff,0xff48c6ff,0xff48c5ff,0xff48c5ff,0xff46c5ff,0xff47c5ff,0xff46c3ff,0xff45c3ff,0xff45c3ff,0xff44c3ff,0xff43c3ff,0xff43c2ff,0xff43c2ff,
+ 0xff42c2ff,0xff42c1ff,0xff41c1ff,0xff40c1ff,0xff40c0ff,0xff40c0ff,0xff3fbfff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3cbdff,
+ 0xff3bbdff,0xff3abdff,0xff3abdff,0xff3abcff,0xff39bcff,0xff38bcff,0xff38bcff,0xff37bbff,0xff37baff,0xff37baff,0xff36baff,0xff36baff,0xff34baff,0xff34b9ff,
+ 0xff34b8ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff32b7ff,0xff31b8ff,0xff31b7ff,0xff30b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,
+ 0xff2cb5ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,0xff2bb3ff,0xff2ab3ff,0xff2ab2ff,0xff29b3ff,0xff29b1ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b0ff,0xff26b1ff,
+ 0xff26b0ff,0xff25afff,0xff25afff,0xff26b0ff,0xff27b1ff,0xff27b1ff,0xff27b2ff,0xff28b1ff,0xff28b1ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff61cbff,0xff61ccff,
+ 0xff41bfff,0xff41c0ff,0xff41c0ff,0xff63ccff,0xff52c7ff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff44c2ff,0xff45c2ff,0xff46c3ff,0xff46c3ff,0xff47c3ff,0xff47c5ff,
+ 0xff48c3ff,0xff48c5ff,0xff48c5ff,0xff47c3ff,0xff47c3ff,0xff46c3ff,0xff65ceff,0xff45c2ff,0xff45c1ff,0xff44c2ff,0xff53c7ff,0xff43c1ff,0xff42c1ff,0xff42c0ff,
+ 0xff42c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41bfff,0xff50c3ff,0xff40bdff,0xff3fbdff,0xff3fbcff,0xff3ebcff,0xff4dc2ff,0xff3dbbff,0xff3dbbff,0xff5dc8ff,
+ 0xff3bbaff,0xff3bbaff,0xff3abaff,0xff4ac0ff,0xff3ab9ff,0xff39b8ff,0xff39b9ff,0xff39b8ff,0xff49bfff,0xff38b7ff,0xff38b7ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,
+ 0xff35b5ff,0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff33b3ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff54c1ff,0xff30b1ff,0xff30b1ff,0xff30b1ff,
+ 0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff2daeff,0xff2caeff,0xff3db5ff,0xff2cacff,0xff2bacff,0xff3cb4ff,0xff4dbcff,0xff3ab3ff,
+ 0xff29abff,0xff28abff,0xff28aaff,0xff4bbaff,0xff28aaff,0xff28a9ff,0xff26a9ff,0xff26a9ff,0xff26a9ff,0xff26a9ff,0xff25a7ff,0xff24a7ff,0xff24a7ff,0xff49b8ff,
+ 0xff23a5ff,0xff23a7ff,0xff23a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff21a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1fa2ff,0xff31abff,0xff1ea2ff,
+ 0xff1da1ff,0xff1da0ff,0xff1da0ff,0xff41b2ff,0xff1ba0ff,0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,
+ 0xff50caff,0xff50caff,0xff74d6ff,0xff74d6ff,0xff52cbff,0xff53cbff,0xff76d6ff,0xff53ccff,0xff76d6ff,0xff55ccff,0xff55ceff,0xff55ceff,0xff55ceff,0xff56ceff,
+ 0xff57ceff,0xff57cfff,0xff58cfff,0xff59cfff,0xff59cfff,0xff59d0ff,0xff59cfff,0xff58d0ff,0xff58cfff,0xff57cfff,0xff79d8ff,0xff57ceff,0xff55ceff,0xff55cdff,
+ 0xff76d7ff,0xff54cdff,0xff53cdff,0xff53cdff,0xff52ccff,0xff52cbff,0xff52cbff,0xff51cbff,0xff51cbff,0xff62cfff,0xff4fcaff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,
+ 0xff71d3ff,0xff4dc8ff,0xff4cc8ff,0xff70d2ff,0xff4bc7ff,0xff4bc7ff,0xff4bc7ff,0xff6fd1ff,0xff49c6ff,0xff49c6ff,0xff48c6ff,0xff48c6ff,0xff6dd0ff,0xff47c5ff,
+ 0xff46c4ff,0xff46c3ff,0xff46c3ff,0xff44c3ff,0xff45c3ff,0xff43c3ff,0xff44c2ff,0xff43c2ff,0xff42c2ff,0xff42c2ff,0xff42c1ff,0xff40c1ff,0xff40c1ff,0xff66cdff,
+ 0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3dbfff,0xff3dbfff,0xff3cbeff,0xff3dbeff,0xff3cbeff,0xff3bbeff,0xff3abdff,0xff3abcff,0xff39bcff,0xff61caff,0xff39bbff,
+ 0xff38bbff,0xff60c9ff,0xff37bbff,0xff5fc8ff,0xff36baff,0xff36baff,0xff5ec7ff,0xff35b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff31b8ff,0xff32b7ff,
+ 0xff31b6ff,0xff30b7ff,0xff2fb6ff,0xff59c5ff,0xff2eb5ff,0xff2fb5ff,0xff2eb4ff,0xff2db5ff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,0xff2bb2ff,
+ 0xff2ab3ff,0xff29b2ff,0xff53c1ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff52c1ff,0xff26b0ff,0xff26b0ff,0xff25afff,0xff26b0ff,0xff26b0ff,0xff27b1ff,0xff27b1ff,
+ 0xff27b2ff,0xff28b1ff,0xff29b1ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff41bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff63ccff,0xff42c0ff,0xff74d3ff,0xff63cdff,
+ 0xff64cdff,0xff55c7ff,0xff64ceff,0xff66ceff,0xff56c8ff,0xff67cfff,0xff66cfff,0xff67cfff,0xff58cbff,0xff68cfff,0xff68cfff,0xff57cbff,0xff47c3ff,0xff66cfff,
+ 0xff45c3ff,0xff56c8ff,0xff65cdff,0xff64cdff,0xff64cdff,0xff63cdff,0xff63ccff,0xff63ccff,0xff42c0ff,0xff63ccff,0xff41c0ff,0xff61ccff,0xff40bdff,0xff71d0ff,
+ 0xff3fbdff,0xff4fc3ff,0xff5fcbff,0xff5fc9ff,0xff5fc9ff,0xff3dbcff,0xff5dc8ff,0xff3cbbff,0xff4bc1ff,0xff5cc7ff,0xff5cc7ff,0xff5cc7ff,0xff5bc6ff,0xff5bc6ff,
+ 0xff5bc6ff,0xff49bfff,0xff6cccff,0xff5ac6ff,0xff38b7ff,0xff59c5ff,0xff59c5ff,0xff58c3ff,0xff58c3ff,0xff58c3ff,0xff57c2ff,0xff45bbff,0xff56c1ff,0xff33b3ff,
+ 0xff55c1ff,0xff33b3ff,0xff32b3ff,0xff54c1ff,0xff31b2ff,0xff65c7ff,0xff53c0ff,0xff52bfff,0xff52bfff,0xff52bfff,0xff51bfff,0xff40b7ff,0xff51bfff,0xff51bdff,
+ 0xff50bdff,0xff3eb5ff,0xff61c5ff,0xff4fbcff,0xff2bacff,0xff4dbcff,0xff2aacff,0xff29abff,0xff29abff,0xff29aaff,0xff4cbbff,0xff28aaff,0xff28aaff,0xff27a9ff,
+ 0xff27a9ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff48b8ff,0xff24a7ff,0xff48b8ff,0xff47b7ff,0xff47b7ff,0xff33adff,0xff59bfff,0xff46b5ff,
+ 0xff45b5ff,0xff32acff,0xff45b4ff,0xff44b3ff,0xff31abff,0xff43b3ff,0xff56bcff,0xff30aaff,0xff1da2ff,0xff1da1ff,0xff41b2ff,0xff1ca0ff,0xff41b2ff,0xff41b1ff,
+ 0xff41b2ff,0xff2ea9ff,0xff41b2ff,0xff41b3ff,0xff2faaff,0xff42b3ff,0xff42b3ff,0xff43b3ff,0xff4fcaff,0xff50cbff,0xff51caff,0xff51caff,0xff52cbff,0xff63d1ff,
+ 0xff63d1ff,0xff53ccff,0xff76d6ff,0xff54cdff,0xff76d7ff,0xff77d8ff,0xff55ceff,0xff57ceff,0xff79d9ff,0xff79d8ff,0xff79d9ff,0xff7ad9ff,0xff7ad9ff,0xff7bd9ff,
+ 0xff7ad9ff,0xff7ad9ff,0xff58cfff,0xff7ad8ff,0xff57ceff,0xff78d8ff,0xff55cdff,0xff55ceff,0xff76d7ff,0xff65d2ff,0xff76d6ff,0xff87dbff,0xff53cbff,0xff75d6ff,
+ 0xff63d0ff,0xff62d0ff,0xff51cbff,0xff73d5ff,0xff50caff,0xff72d5ff,0xff4fcaff,0xff4ec9ff,0xff71d4ff,0xff4dc9ff,0xff71d3ff,0xff4cc8ff,0xff6fd2ff,0xff4bc7ff,
+ 0xff4bc7ff,0xff6fd1ff,0xff6fd1ff,0xff48c6ff,0xff6ed1ff,0xff48c5ff,0xff6cd1ff,0xff47c5ff,0xff47c4ff,0xff6bd0ff,0xff45c4ff,0xff6ad0ff,0xff6acfff,0xff43c3ff,
+ 0xff43c2ff,0xff69ceff,0xff69ceff,0xff42c2ff,0xff67cdff,0xff40c0ff,0xff53c7ff,0xff53c6ff,0xff40c0ff,0xff65ccff,0xff3ebfff,0xff64ccff,0xff64ccff,0xff3dbeff,
+ 0xff3cbdff,0xff63cbff,0xff76d1ff,0xff63caff,0xff75d1ff,0xff3abcff,0xff61c9ff,0xff39bbff,0xff38bbff,0xff5fc9ff,0xff37baff,0xff36baff,0xff35baff,0xff49c0ff,
+ 0xff49c1ff,0xff34b9ff,0xff33b9ff,0xff34b9ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff5ac5ff,0xff2fb6ff,0xff58c5ff,0xff2eb5ff,
+ 0xff2eb5ff,0xff57c4ff,0xff57c3ff,0xff2cb4ff,0xff57c2ff,0xff56c2ff,0xff55c2ff,0xff55c1ff,0xff55c1ff,0xff2ab2ff,0xff53c1ff,0xff28b2ff,0xff28b1ff,0xff3db8ff,
+ 0xff3db9ff,0xff26b1ff,0xff52c0ff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff52c1ff,0xff3db9ff,0xff28b1ff,0xff53c1ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,
+ 0xff40bfff,0xff41bfff,0xff41bfff,0xff62ccff,0xff41c0ff,0xff42c0ff,0xff63cdff,0xff43c0ff,0xff63cdff,0xff65cdff,0xff44c2ff,0xff45c2ff,0xff66ceff,0xff67cfff,
+ 0xff67cfff,0xff67cfff,0xff68cfff,0xff48c5ff,0xff47c3ff,0xff58c9ff,0xff57c9ff,0xff56c9ff,0xff45c2ff,0xff65ceff,0xff44c2ff,0xff54c8ff,0xff64cdff,0xff63cdff,
+ 0xff43c0ff,0xff63ccff,0xff42c0ff,0xff51c5ff,0xff61ccff,0xff41bfff,0xff40bdff,0xff60ccff,0xff40bdff,0xff5fc9ff,0xff3ebdff,0xff4ec2ff,0xff5fc9ff,0xff4dc1ff,
+ 0xff4cc1ff,0xff3cbbff,0xff5cc7ff,0xff3bbaff,0xff4ac0ff,0xff5cc6ff,0xff5bc6ff,0xff3ab9ff,0xff5bc6ff,0xff39b8ff,0xff5ac6ff,0xff38b7ff,0xff48bdff,0xff59c5ff,
+ 0xff58c3ff,0xff36b5ff,0xff58c3ff,0xff35b5ff,0xff35b4ff,0xff57c2ff,0xff56c2ff,0xff33b3ff,0xff67c8ff,0xff33b3ff,0xff54c1ff,0xff32b2ff,0xff31b2ff,0xff66c7ff,
+ 0xff30b1ff,0xff52c0ff,0xff52bfff,0xff2fb1ff,0xff2eb0ff,0xff51bdff,0xff51bdff,0xff2daeff,0xff3eb7ff,0xff2dadff,0xff4fbdff,0xff2bacff,0xff3cb4ff,0xff4ebcff,
+ 0xff2aacff,0xff4cbcff,0xff29abff,0xff4cbbff,0xff28abff,0xff28aaff,0xff28aaff,0xff38b1ff,0xff27a9ff,0xff26a8ff,0xff26a8ff,0xff37b0ff,0xff25a8ff,0xff36aeff,
+ 0xff36aeff,0xff24a7ff,0xff47b7ff,0xff34adff,0xff23a5ff,0xff46b7ff,0xff46b5ff,0xff21a4ff,0xff46b4ff,0xff45b4ff,0xff20a3ff,0xff20a3ff,0xff31acff,0xff1fa2ff,
+ 0xff43b3ff,0xff30abff,0xff1da1ff,0xff41b3ff,0xff1da0ff,0xff1ca0ff,0xff41b2ff,0xff1b9fff,0xff2ea8ff,0xff2eaaff,0xff1da1ff,0xff2fa9ff,0xff30aaff,0xff42b3ff,
+ 0xff1fa2ff,0xff31abff,0xff50caff,0xff50cbff,0xff51cbff,0xff51cbff,0xff63d0ff,0xff63d0ff,0xff53ccff,0xff54ccff,0xff65d1ff,0xff55cdff,0xff66d2ff,0xff55cdff,
+ 0xff78d7ff,0xff78d8ff,0xff57ceff,0xff69d4ff,0xff58cfff,0xff6ad4ff,0xff59d0ff,0xff7bd9ff,0xff7bd9ff,0xff58cfff,0xff79d9ff,0xff58cfff,0xff57ceff,0xff56ceff,
+ 0xff78d8ff,0xff67d3ff,0xff66d2ff,0xff65d2ff,0xff76d7ff,0xff76d7ff,0xff52ccff,0xff52cbff,0xff63d0ff,0xff51cbff,0xff62d0ff,0xff73d5ff,0xff72d5ff,0xff4fc9ff,
+ 0xff72d4ff,0xff60ceff,0xff5fceff,0xff71d3ff,0xff4dc8ff,0xff4cc8ff,0xff4bc8ff,0xff6fd2ff,0xff5cccff,0xff5cccff,0xff5bccff,0xff6dd1ff,0xff5acbff,0xff48c6ff,
+ 0xff48c5ff,0xff6bd1ff,0xff47c4ff,0xff6bd0ff,0xff6acfff,0xff6acfff,0xff57c9ff,0xff44c3ff,0xff43c2ff,0xff56c8ff,0xff55c7ff,0xff68cdff,0xff54c7ff,0xff53c7ff,
+ 0xff53c6ff,0xff40c0ff,0xff40bfff,0xff66ccff,0xff65ccff,0xff51c5ff,0xff50c5ff,0xff3cbeff,0xff3cbeff,0xff50c5ff,0xff4fc4ff,0xff62caff,0xff4ec4ff,0xff3abdff,
+ 0xff39bbff,0xff60caff,0xff38bbff,0xff4bc2ff,0xff5fc8ff,0xff4bc1ff,0xff4ac1ff,0xff49c1ff,0xff35b9ff,0xff35b9ff,0xff34b8ff,0xff70cdff,0xff47bfff,0xff32b7ff,
+ 0xff47beff,0xff6fccff,0xff31b7ff,0xff5ac5ff,0xff30b7ff,0xff2fb6ff,0xff58c4ff,0xff43bcff,0xff58c4ff,0xff2db5ff,0xff41bcff,0xff2db4ff,0xff41bbff,0xff2bb3ff,
+ 0xff56c2ff,0xff55c2ff,0xff29b2ff,0xff29b2ff,0xff3eb9ff,0xff3eb9ff,0xff3ebaff,0xff3db9ff,0xff26b1ff,0xff26b0ff,0xff3bb8ff,0xff51c0ff,0xff3cb8ff,0xff26b0ff,
+ 0xff52c1ff,0xff53c0ff,0xff28b1ff,0xff3eb9ff,0xff54c1ff,0xff3fbaff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff50c5ff,0xff41c0ff,0xff42c0ff,0xff42c0ff,
+ 0xff42c1ff,0xff43c1ff,0xff43c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff46c3ff,0xff46c2ff,0xff47c3ff,0xff48c5ff,0xff48c3ff,0xff48c5ff,0xff48c3ff,0xff47c3ff,
+ 0xff56c8ff,0xff46c3ff,0xff46c3ff,0xff45c3ff,0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,0xff43c1ff,0xff42c0ff,0xff42c0ff,0xff41bfff,0xff41bfff,0xff41bfff,
+ 0xff41bfff,0xff40bdff,0xff3fbdff,0xff3fbdff,0xff3fbcff,0xff3ebcff,0xff3ebbff,0xff4dc1ff,0xff3cbbff,0xff3cbaff,0xff3bbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,
+ 0xff3abaff,0xff3ab9ff,0xff39b9ff,0xff39b8ff,0xff38b7ff,0xff37b7ff,0xff37b7ff,0xff48bdff,0xff59c3ff,0xff47bdff,0xff35b5ff,0xff34b4ff,0xff35b4ff,0xff34b3ff,
+ 0xff33b3ff,0xff33b3ff,0xff33b2ff,0xff43baff,0xff33b2ff,0xff32b2ff,0xff31b1ff,0xff41b8ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,
+ 0xff2eaeff,0xff2dadff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2badff,0xff2bacff,0xff2bacff,0xff2aacff,0xff29abff,0xff3ab3ff,0xff28abff,0xff28abff,0xff28aaff,
+ 0xff28aaff,0xff27aaff,0xff27a9ff,0xff26a9ff,0xff26a8ff,0xff25a8ff,0xff24a8ff,0xff37aeff,0xff24a7ff,0xff24a7ff,0xff34aeff,0xff23a5ff,0xff22a5ff,0xff22a5ff,
+ 0xff21a4ff,0xff21a4ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff20a2ff,0xff1fa2ff,0xff1ea1ff,0xff30aaff,0xff1da0ff,0xff1ca0ff,0xff1ca1ff,
+ 0xff1ca0ff,0xff1ba0ff,0xff1b9fff,0xff1ca0ff,0xff1ca1ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff51cbff,0xff51caff,0xff51caff,
+ 0xff51cbff,0xff52ccff,0xff52cbff,0xff53ccff,0xff54ccff,0xff54cdff,0xff55cdff,0xff56cdff,0xff56ceff,0xff56ceff,0xff57ceff,0xff57cfff,0xff58cfff,0xff58cfff,
+ 0xff59d0ff,0xff59d0ff,0xff58cfff,0xff58cfff,0xff58cfff,0xff58cfff,0xff57ceff,0xff56ceff,0xff56ceff,0xff55cdff,0xff54cdff,0xff54cdff,0xff54ccff,0xff53ccff,
+ 0xff52ccff,0xff52cbff,0xff51cbff,0xff51cbff,0xff50caff,0xff50caff,0xff50caff,0xff4fcaff,0xff4fc9ff,0xff4ec9ff,0xff4ec9ff,0xff4dc9ff,0xff4dc8ff,0xff4cc7ff,
+ 0xff4bc7ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,0xff47c5ff,0xff46c5ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff45c3ff,
+ 0xff45c3ff,0xff44c2ff,0xff44c2ff,0xff42c2ff,0xff42c2ff,0xff42c1ff,0xff42c1ff,0xff41c1ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff52c6ff,0xff3ebfff,0xff3ebfff,
+ 0xff3dbfff,0xff50c5ff,0xff50c5ff,0xff3bbdff,0xff4fc4ff,0xff3bbdff,0xff3abdff,0xff39bcff,0xff4dc3ff,0xff4dc3ff,0xff38bbff,0xff37bbff,0xff37bbff,0xff37bbff,
+ 0xff36baff,0xff36baff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff31b8ff,0xff31b7ff,0xff30b6ff,0xff2fb6ff,0xff30b6ff,
+ 0xff2eb5ff,0xff2eb5ff,0xff2db4ff,0xff2eb5ff,0xff2cb5ff,0xff2db4ff,0xff2cb4ff,0xff2bb4ff,0xff2ab3ff,0xff2ab3ff,0xff29b2ff,0xff29b2ff,0xff29b1ff,0xff28b1ff,
+ 0xff28b1ff,0xff27b1ff,0xff26b0ff,0xff26b0ff,0xff25afff,0xff25b0ff,0xff25b0ff,0xff3cb8ff,0xff27b0ff,0xff27b1ff,0xff28b2ff,0xff28b1ff,0xff3fbaff,0xff3fbaff,
+ 0xff3fbdff,0xff40bdff,0xff40bdff,0xff41bdff,0xff61ccff,0xff62ccff,0xff62ccff,0xff42c0ff,0xff74d2ff,0xff63ccff,0xff64cdff,0xff44c1ff,0xff65ceff,0xff65cfff,
+ 0xff46c2ff,0xff66cfff,0xff66cfff,0xff67cfff,0xff67cfff,0xff48c5ff,0xff57cbff,0xff58c9ff,0xff56c9ff,0xff66cfff,0xff56c9ff,0xff55c8ff,0xff65cdff,0xff64cdff,
+ 0xff53c7ff,0xff74d2ff,0xff63cdff,0xff63ccff,0xff41c0ff,0xff41c0ff,0xff41c0ff,0xff41bfff,0xff72d0ff,0xff60ccff,0xff50c3ff,0xff5fc9ff,0xff3ebcff,0xff3ebcff,
+ 0xff5ec8ff,0xff5ec8ff,0xff5dc8ff,0xff5dc8ff,0xff5dc7ff,0xff5cc7ff,0xff5cc7ff,0xff4ac0ff,0xff6dceff,0xff5bc6ff,0xff5bc6ff,0xff5bc6ff,0xff5bc6ff,0xff59c5ff,
+ 0xff49bfff,0xff58c5ff,0xff59c3ff,0xff58c3ff,0xff58c3ff,0xff58c3ff,0xff57c2ff,0xff44bbff,0xff57c2ff,0xff67c8ff,0xff55c1ff,0xff42b9ff,0xff32b2ff,0xff32b2ff,
+ 0xff31b2ff,0xff53c1ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff51bfff,0xff51bfff,0xff2eaeff,0xff51bdff,0xff2dadff,0xff2daeff,0xff2cadff,0xff4fbcff,0xff4ebcff,
+ 0xff2badff,0xff2aacff,0xff2aacff,0xff29acff,0xff29abff,0xff29abff,0xff28aaff,0xff28aaff,0xff5ec2ff,0xff4bb9ff,0xff38b1ff,0xff4ab8ff,0xff49b8ff,0xff49b8ff,
+ 0xff37b0ff,0xff36b0ff,0xff49b8ff,0xff35aeff,0xff35aeff,0xff47b7ff,0xff47b7ff,0xff34adff,0xff46b5ff,0xff21a4ff,0xff46b5ff,0xff21a3ff,0xff45b4ff,0xff44b3ff,
+ 0xff20a2ff,0xff43b3ff,0xff43b3ff,0xff42b3ff,0xff42b3ff,0xff41b3ff,0xff41b3ff,0xff2ea9ff,0xff1ca0ff,0xff1b9fff,0xff1ca0ff,0xff2eaaff,0xff2eaaff,0xff1da1ff,
+ 0xff1da1ff,0xff1fa1ff,0xff43b3ff,0xff43b3ff,0xff50caff,0xff50caff,0xff51cbff,0xff51cbff,0xff74d6ff,0xff52cbff,0xff53ccff,0xff76d6ff,0xff76d6ff,0xff55cdff,
+ 0xff76d7ff,0xff77d8ff,0xff55ceff,0xff56ceff,0xff78d8ff,0xff7ad8ff,0xff58cfff,0xff69d4ff,0xff7bd9ff,0xff6ad5ff,0xff6ad5ff,0xff58cfff,0xff7ad9ff,0xff57cfff,
+ 0xff78d9ff,0xff79d8ff,0xff56ceff,0xff56cdff,0xff66d2ff,0xff76d7ff,0xff54cdff,0xff53ccff,0xff53ccff,0xff52cbff,0xff52cbff,0xff51cbff,0xff74d5ff,0xff50cbff,
+ 0xff73d5ff,0xff72d5ff,0xff4fcaff,0xff4ec9ff,0xff72d4ff,0xff71d3ff,0xff4dc8ff,0xff5ecdff,0xff6fd3ff,0xff4bc7ff,0xff4bc7ff,0xff6fd2ff,0xff6ed1ff,0xff49c6ff,
+ 0xff49c5ff,0xff6dd1ff,0xff47c5ff,0xff47c5ff,0xff6bd0ff,0xff6bd0ff,0xff45c4ff,0xff6acfff,0xff6acfff,0xff44c3ff,0xff43c2ff,0xff69ceff,0xff42c2ff,0xff68cdff,
+ 0xff41c1ff,0xff54c7ff,0xff66cdff,0xff66cdff,0xff52c6ff,0xff52c5ff,0xff51c5ff,0xff3ebeff,0xff3dbfff,0xff50c5ff,0xff50c5ff,0xff3cbdff,0xff4fc4ff,0xff4ec4ff,
+ 0xff3abdff,0xff39bcff,0xff4dc3ff,0xff4cc3ff,0xff38bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff5dc7ff,0xff33b8ff,
+ 0xff5cc6ff,0xff5bc6ff,0xff32b7ff,0xff32b7ff,0xff5ac5ff,0xff5ac5ff,0xff30b6ff,0xff59c4ff,0xff59c5ff,0xff2fb6ff,0xff2eb5ff,0xff43bcff,0xff57c3ff,0xff57c3ff,
+ 0xff2cb4ff,0xff56c3ff,0xff2bb3ff,0xff2bb2ff,0xff55c2ff,0xff54c1ff,0xff29b1ff,0xff3ebaff,0xff53c1ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,0xff51c0ff,0xff51c0ff,
+ 0xff52c0ff,0xff26b0ff,0xff52c0ff,0xff27b1ff,0xff27b1ff,0xff28b2ff,0xff3ebaff,0xff3fbaff,0xff3fbcff,0xff50c3ff,0xff61ccff,0xff61cbff,0xff62ccff,0xff41bfff,
+ 0xff42bfff,0xff63ccff,0xff74d3ff,0xff63cdff,0xff64cdff,0xff65ceff,0xff65ceff,0xff65ceff,0xff65ceff,0xff67cfff,0xff46c3ff,0xff47c3ff,0xff68cfff,0xff68cfff,
+ 0xff47c5ff,0xff47c3ff,0xff77d4ff,0xff66ceff,0xff76d4ff,0xff65ceff,0xff45c2ff,0xff64cdff,0xff53c7ff,0xff74d2ff,0xff63ccff,0xff42c0ff,0xff42bfff,0xff41bfff,
+ 0xff41c0ff,0xff41bdff,0xff72d0ff,0xff60cbff,0xff4fc3ff,0xff5fcbff,0xff3fbdff,0xff3ebcff,0xff5ec8ff,0xff5ec8ff,0xff4dc1ff,0xff5dc7ff,0xff5dc7ff,0xff5cc7ff,
+ 0xff5cc7ff,0xff49c0ff,0xff6dcdff,0xff5bc6ff,0xff39b9ff,0xff5bc6ff,0xff5ac6ff,0xff59c6ff,0xff48bdff,0xff59c5ff,0xff36b5ff,0xff58c3ff,0xff58c3ff,0xff58c3ff,
+ 0xff57c2ff,0xff44bbff,0xff33b3ff,0xff56c2ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff32b2ff,0xff31b1ff,0xff53c0ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,
+ 0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff51bdff,0xff2daeff,0xff2daeff,0xff2cacff,0xff2badff,0xff2badff,0xff2bacff,0xff2aabff,0xff29abff,0xff29abff,0xff4cbaff,
+ 0xff4cbbff,0xff39b2ff,0xff4bbaff,0xff27aaff,0xff4ab9ff,0xff4ab9ff,0xff49b9ff,0xff49b9ff,0xff36b0ff,0xff5bc0ff,0xff49b8ff,0xff5bc0ff,0xff47b8ff,0xff23a5ff,
+ 0xff23a5ff,0xff23a5ff,0xff5abfff,0xff33adff,0xff20a4ff,0xff45b5ff,0xff44b4ff,0xff44b4ff,0xff44b3ff,0xff43b3ff,0xff30abff,0xff42b3ff,0xff41b3ff,0xff41b3ff,
+ 0xff2eaaff,0xff1ca1ff,0xff1ba0ff,0xff1ba0ff,0xff1ba0ff,0xff1ca1ff,0xff41b2ff,0xff1da1ff,0xff1ea2ff,0xff1ea1ff,0xff1fa1ff,0xff1fa2ff,0xff50caff,0xff50caff,
+ 0xff50caff,0xff51cbff,0xff75d6ff,0xff53ccff,0xff52ccff,0xff76d6ff,0xff76d6ff,0xff55cdff,0xff54cdff,0xff77d7ff,0xff56ceff,0xff56ceff,0xff78d9ff,0xff79d9ff,
+ 0xff57cfff,0xff69d5ff,0xff7bd9ff,0xff5ad0ff,0xff7bd9ff,0xff59cfff,0xff79d9ff,0xff57cfff,0xff78d9ff,0xff78d8ff,0xff55ceff,0xff55ceff,0xff76d7ff,0xff76d6ff,
+ 0xff54ccff,0xff53ccff,0xff53ccff,0xff52cbff,0xff52cbff,0xff52cbff,0xff74d5ff,0xff50caff,0xff73d4ff,0xff72d5ff,0xff4ec9ff,0xff4ec9ff,0xff71d4ff,0xff71d3ff,
+ 0xff4cc8ff,0xff70d3ff,0xff70d3ff,0xff4bc7ff,0xff6fd1ff,0xff4ac6ff,0xff6ed1ff,0xff49c5ff,0xff48c5ff,0xff6dd1ff,0xff47c5ff,0xff47c5ff,0xff46c4ff,0xff6ad0ff,
+ 0xff45c4ff,0xff6acfff,0xff6acfff,0xff44c2ff,0xff69ceff,0xff42c2ff,0xff42c1ff,0xff68cdff,0xff41c1ff,0xff54c7ff,0xff66cdff,0xff66cdff,0xff52c6ff,0xff3fbfff,
+ 0xff65ccff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff63caff,0xff3abdff,0xff39bcff,0xff39bcff,0xff39bbff,0xff37bbff,0xff38bbff,
+ 0xff36bbff,0xff37baff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff5dc7ff,0xff33b8ff,0xff5cc6ff,0xff5bc6ff,0xff31b7ff,0xff31b7ff,0xff31b7ff,0xff5ac5ff,
+ 0xff30b6ff,0xff59c5ff,0xff59c4ff,0xff2eb6ff,0xff2eb5ff,0xff42bcff,0xff57c3ff,0xff41bcff,0xff41bcff,0xff56c2ff,0xff2ab3ff,0xff2ab2ff,0xff55c2ff,0xff55c1ff,
+ 0xff29b2ff,0xff53c1ff,0xff52c1ff,0xff27b1ff,0xff27b1ff,0xff26b1ff,0xff52c0ff,0xff51c0ff,0xff51c0ff,0xff26b0ff,0xff27b1ff,0xff52c1ff,0xff28b1ff,0xff28b2ff,
+ 0xff28b1ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff41bdff,0xff41bfff,0xff62ccff,0xff62ccff,0xff62ccff,0xff43c0ff,0xff63ccff,0xff43c0ff,0xff43c1ff,0xff64ceff,
+ 0xff45c2ff,0xff45c2ff,0xff66cfff,0xff66cfff,0xff67cfff,0xff67cfff,0xff67cfff,0xff48c5ff,0xff48c5ff,0xff67cfff,0xff67cfff,0xff46c3ff,0xff65cfff,0xff55c8ff,
+ 0xff65cdff,0xff64ceff,0xff64cdff,0xff74d2ff,0xff63cdff,0xff63ccff,0xff41c0ff,0xff42c0ff,0xff41bfff,0xff41bfff,0xff71d0ff,0xff60cbff,0xff50c3ff,0xff4fc2ff,
+ 0xff5fc9ff,0xff5fc8ff,0xff4ec1ff,0xff5ec9ff,0xff5ec8ff,0xff6ecfff,0xff5cc8ff,0xff3bbaff,0xff3abaff,0xff5cc6ff,0xff6dcdff,0xff5bc6ff,0xff5bc6ff,0xff5bc6ff,
+ 0xff39b7ff,0xff38b7ff,0xff37b7ff,0xff59c5ff,0xff58c3ff,0xff58c5ff,0xff58c3ff,0xff35b5ff,0xff35b4ff,0xff57c2ff,0xff33b4ff,0xff55c1ff,0xff33b3ff,0xff33b2ff,
+ 0xff32b3ff,0xff32b2ff,0xff31b2ff,0xff30b2ff,0xff30b1ff,0xff52c0ff,0xff30b1ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2eaeff,0xff50bdff,0xff2daeff,
+ 0xff2cadff,0xff2cadff,0xff2bacff,0xff2aacff,0xff2aacff,0xff2aabff,0xff29abff,0xff28aaff,0xff28abff,0xff28aaff,0xff5ec1ff,0xff4ab9ff,0xff38b2ff,0xff4ab9ff,
+ 0xff26a9ff,0xff25a8ff,0xff24a7ff,0xff49b8ff,0xff24a7ff,0xff48b8ff,0xff35aeff,0xff48b8ff,0xff47b7ff,0xff33adff,0xff46b5ff,0xff21a4ff,0xff46b5ff,0xff45b4ff,
+ 0xff20a3ff,0xff20a2ff,0xff43b3ff,0xff43b3ff,0xff43b3ff,0xff56bcff,0xff41b3ff,0xff41b3ff,0xff41b3ff,0xff2ea9ff,0xff1ba0ff,0xff1ba0ff,0xff1ca0ff,0xff1ca0ff,
+ 0xff1da0ff,0xff41b3ff,0xff1ea1ff,0xff1ea2ff,0xff1fa2ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff51caff,0xff51cbff,0xff52cbff,0xff52ccff,0xff52ccff,0xff53ccff,
+ 0xff54cdff,0xff54cdff,0xff55cdff,0xff55ceff,0xff56ceff,0xff56ceff,0xff57ceff,0xff58cfff,0xff57cfff,0xff59cfff,0xff59d0ff,0xff59d0ff,0xff59cfff,0xff58d0ff,
+ 0xff58cfff,0xff57ceff,0xff56ceff,0xff56ceff,0xff55ceff,0xff55cdff,0xff55cdff,0xff55cdff,0xff53cdff,0xff53ccff,0xff64d1ff,0xff75d6ff,0xff75d6ff,0xff62d0ff,
+ 0xff50cbff,0xff50caff,0xff4fc9ff,0xff4fc9ff,0xff4fc9ff,0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,0xff4cc7ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,
+ 0xff4ac6ff,0xff49c5ff,0xff48c6ff,0xff48c5ff,0xff48c5ff,0xff47c4ff,0xff47c4ff,0xff46c3ff,0xff45c4ff,0xff44c4ff,0xff44c3ff,0xff43c3ff,0xff43c2ff,0xff42c2ff,
+ 0xff42c2ff,0xff42c2ff,0xff41c1ff,0xff41c1ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3ec0ff,0xff64cbff,0xff3dbfff,0xff3cbeff,0xff3cbdff,0xff3cbdff,
+ 0xff3bbdff,0xff3abdff,0xff62caff,0xff3abdff,0xff39bcff,0xff39bcff,0xff38bbff,0xff37baff,0xff37bbff,0xff36baff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,
+ 0xff33b9ff,0xff34b8ff,0xff33b8ff,0xff32b8ff,0xff32b8ff,0xff32b7ff,0xff31b7ff,0xff31b6ff,0xff30b6ff,0xff2fb5ff,0xff2fb6ff,0xff2eb5ff,0xff2eb5ff,0xff2eb5ff,
+ 0xff2cb4ff,0xff2cb4ff,0xff2bb4ff,0xff2bb3ff,0xff2ab3ff,0xff2ab3ff,0xff2ab3ff,0xff29b2ff,0xff28b1ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff26b1ff,
+ 0xff25b0ff,0xff25afff,0xff25b0ff,0xff26b1ff,0xff27b0ff,0xff27b1ff,0xff52c1ff,0xff29b1ff,0xff28b1ff,0xff29b2ff,0xff40bcff,0xff40bdff,0xff41bfff,0xff41bdff,
+ 0xff41bfff,0xff41bfff,0xff42c0ff,0xff42c1ff,0xff43c0ff,0xff43c1ff,0xff44c1ff,0xff45c1ff,0xff45c2ff,0xff46c3ff,0xff45c3ff,0xff46c2ff,0xff47c3ff,0xff47c5ff,
+ 0xff48c3ff,0xff49c5ff,0xff48c3ff,0xff47c3ff,0xff47c3ff,0xff46c3ff,0xff46c2ff,0xff45c2ff,0xff45c2ff,0xff44c2ff,0xff44c1ff,0xff43c1ff,0xff42c0ff,0xff42c0ff,
+ 0xff41bfff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff40bdff,0xff40bdff,0xff40bdff,0xff3fbdff,0xff3fbdff,0xff3ebcff,0xff3ebcff,0xff3dbbff,0xff3cbbff,0xff3cbbff,
+ 0xff3bbaff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3abaff,0xff3ab8ff,0xff3ab9ff,0xff39b8ff,0xff38b8ff,0xff38b8ff,0xff37b8ff,0xff37b7ff,0xff36b7ff,0xff35b5ff,
+ 0xff35b5ff,0xff35b5ff,0xff34b5ff,0xff34b4ff,0xff33b4ff,0xff33b4ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff32b2ff,0xff31b2ff,0xff30b2ff,0xff30b1ff,0xff2fb1ff,
+ 0xff2fb0ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2daeff,0xff2daeff,0xff2cadff,0xff2cadff,0xff2bacff,0xff2aacff,0xff2aabff,0xff29abff,
+ 0xff29abff,0xff28abff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27a9ff,0xff27a9ff,0xff26a8ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,
+ 0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff22a5ff,0xff22a5ff,0xff21a4ff,0xff21a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff1fa3ff,0xff1fa2ff,0xff1ea1ff,0xff1ea2ff,
+ 0xff1ea1ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,0xff1c9fff,0xff1b9fff,0xff1ca0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,0xff1da1ff,0xff1ea1ff,0xff1ea1ff,0xff1fa2ff,
+ 0xff4fcaff,0xff50caff,0xff51cbff,0xff51cbff,0xff52cbff,0xff63d0ff,0xff64d1ff,0xff53ccff,0xff64d2ff,0xff77d7ff,0xff66d3ff,0xff55ceff,0xff56ceff,0xff56ceff,
+ 0xff57ceff,0xff57ceff,0xff58cfff,0xff58cfff,0xff58cfff,0xff5ad0ff,0xff59d0ff,0xff59cfff,0xff69d4ff,0xff7ad8ff,0xff68d4ff,0xff56ceff,0xff55ceff,0xff55ceff,
+ 0xff55cdff,0xff54cdff,0xff53cdff,0xff53cdff,0xff52cbff,0xff63d1ff,0xff52cbff,0xff51cbff,0xff50cbff,0xff50caff,0xff4fcaff,0xff4fc9ff,0xff4fc9ff,0xff4ec9ff,
+ 0xff4ec9ff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff4cc7ff,0xff6fd2ff,0xff6fd1ff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,0xff48c5ff,0xff47c5ff,0xff48c4ff,0xff47c4ff,
+ 0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff42c2ff,0xff43c2ff,0xff42c1ff,0xff41c1ff,0xff40c1ff,0xff40c0ff,0xff3fc0ff,
+ 0xff3fbfff,0xff3ec0ff,0xff3fbfff,0xff3ebfff,0xff3dbfff,0xff64ccff,0xff63cbff,0xff3cbdff,0xff3bbdff,0xff3bbdff,0xff3abcff,0xff3abcff,0xff39bcff,0xff60c9ff,
+ 0xff38bbff,0xff37bbff,0xff37baff,0xff36baff,0xff36baff,0xff49c0ff,0xff49c0ff,0xff34b9ff,0xff34b8ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff32b7ff,0xff31b7ff,
+ 0xff30b7ff,0xff30b6ff,0xff44bdff,0xff2fb6ff,0xff2fb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db5ff,0xff2cb5ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,0xff2ab2ff,
+ 0xff2ab2ff,0xff29b3ff,0xff28b1ff,0xff28b2ff,0xff27b1ff,0xff27b0ff,0xff26b1ff,0xff26b0ff,0xff25afff,0xff25afff,0xff25b0ff,0xff26b1ff,0xff3db8ff,0xff28b1ff,
+ 0xff27b1ff,0xff3eb9ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff42c0ff,0xff62ccff,0xff42c0ff,0xff63cdff,0xff43c1ff,
+ 0xff64cdff,0xff44c2ff,0xff45c1ff,0xff45c2ff,0xff46c2ff,0xff46c3ff,0xff47c3ff,0xff48c3ff,0xff48c5ff,0xff48c3ff,0xff47c5ff,0xff47c3ff,0xff66cfff,0xff46c2ff,
+ 0xff66ceff,0xff46c2ff,0xff45c2ff,0xff44c1ff,0xff44c1ff,0xff43c1ff,0xff42c0ff,0xff42c0ff,0xff41c0ff,0xff62ccff,0xff41bfff,0xff41bfff,0xff40bdff,0xff40bdff,
+ 0xff40bdff,0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff3dbbff,0xff3dbbff,0xff3dbbff,0xff3cbbff,0xff5dc7ff,0xff3abaff,0xff3ab9ff,0xff5cc7ff,0xff3ab9ff,0xff3ab9ff,
+ 0xff39b8ff,0xff38b8ff,0xff38b7ff,0xff38b7ff,0xff37b8ff,0xff37b5ff,0xff37b5ff,0xff36b5ff,0xff36b5ff,0xff35b4ff,0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,
+ 0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b2ff,0xff31b1ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff51bfff,0xff51bfff,0xff2eaeff,0xff2eaeff,0xff2eaeff,
+ 0xff2daeff,0xff2dadff,0xff4fbdff,0xff2cadff,0xff3cb4ff,0xff2aacff,0xff2aacff,0xff2aacff,0xff29abff,0xff29aaff,0xff4bbaff,0xff28aaff,0xff28aaff,0xff27aaff,
+ 0xff27a9ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff25a7ff,0xff35aeff,0xff24a7ff,0xff24a7ff,0xff23a5ff,0xff23a5ff,0xff23a5ff,0xff22a4ff,0xff21a4ff,
+ 0xff21a3ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa2ff,0xff1fa2ff,0xff1ea2ff,0xff1ea1ff,0xff1da1ff,0xff1ca1ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,
+ 0xff1ca0ff,0xff1ca0ff,0xff41b3ff,0xff1da1ff,0xff1ea1ff,0xff42b3ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff50cbff,0xff51cbff,0xff51cbff,0xff51cbff,0xff52ccff,
+ 0xff75d6ff,0xff53ccff,0xff76d6ff,0xff54cdff,0xff77d7ff,0xff77d7ff,0xff78d8ff,0xff78d8ff,0xff67d3ff,0xff7ad9ff,0xff7ad9ff,0xff7ad9ff,0xff7bd9ff,0xff7bd9ff,
+ 0xff7bd9ff,0xff69d4ff,0xff79d9ff,0xff68d4ff,0xff56cfff,0xff78d8ff,0xff55ceff,0xff55cdff,0xff77d7ff,0xff76d7ff,0xff76d6ff,0xff76d6ff,0xff63d0ff,0xff86dbff,
+ 0xff74d6ff,0xff51cbff,0xff73d5ff,0xff73d5ff,0xff73d4ff,0xff4fcaff,0xff83d9ff,0xff72d4ff,0xff5fcdff,0xff4dc9ff,0xff4dc8ff,0xff4bc8ff,0xff6fd2ff,0xff4bc7ff,
+ 0xff4ac6ff,0xff4ac6ff,0xff4ac6ff,0xff49c6ff,0xff48c6ff,0xff48c5ff,0xff47c5ff,0xff47c5ff,0xff47c4ff,0xff6bd0ff,0xff46c4ff,0xff6ad0ff,0xff44c3ff,0xff43c3ff,
+ 0xff43c2ff,0xff43c2ff,0xff68ceff,0xff68cdff,0xff67cdff,0xff40c0ff,0xff40c1ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,0xff3dbeff,0xff3dbeff,
+ 0xff3cbeff,0xff3bbeff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff4dc3ff,0xff74d0ff,0xff61caff,0xff38bbff,0xff73cfff,0xff5fc9ff,0xff5fc9ff,0xff36baff,0xff35baff,
+ 0xff5ec7ff,0xff35b9ff,0xff5cc6ff,0xff34b8ff,0xff5cc6ff,0xff47bfff,0xff5bc5ff,0xff5ac6ff,0xff46beff,0xff30b6ff,0xff6eccff,0xff2fb6ff,0xff59c5ff,0xff58c4ff,
+ 0xff58c4ff,0xff42bcff,0xff2cb4ff,0xff2cb4ff,0xff2cb3ff,0xff40bbff,0xff56c2ff,0xff55c2ff,0xff3fbbff,0xff29b2ff,0xff29b1ff,0xff28b1ff,0xff53c1ff,0xff52c1ff,
+ 0xff52c1ff,0xff3cb8ff,0xff51c0ff,0xff51bfff,0xff51bfff,0xff3cb8ff,0xff67c8ff,0xff52c1ff,0xff28b1ff,0xff69c8ff,0xff53c1ff,0xff54c1ff,0xff3fbdff,0xff50c5ff,
+ 0xff61cbff,0xff61ccff,0xff41bfff,0xff41bfff,0xff62ccff,0xff43c0ff,0xff63ccff,0xff44c1ff,0xff64cdff,0xff64cdff,0xff44c2ff,0xff45c2ff,0xff66ceff,0xff76d4ff,
+ 0xff67cfff,0xff77d4ff,0xff68cfff,0xff49c5ff,0xff48c5ff,0xff68cfff,0xff47c3ff,0xff56c9ff,0xff66cfff,0xff65ceff,0xff44c2ff,0xff44c1ff,0xff64cdff,0xff53c6ff,
+ 0xff63ccff,0xff42c0ff,0xff42bfff,0xff62ccff,0xff41bfff,0xff41bfff,0xff71d0ff,0xff60cbff,0xff71d0ff,0xff3fbdff,0xff5fc9ff,0xff5fc9ff,0xff5fc8ff,0xff3dbbff,
+ 0xff3cbbff,0xff3cbbff,0xff5dc7ff,0xff3bbaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff3ab8ff,0xff39b8ff,0xff5ac5ff,0xff5ac6ff,0xff48bfff,0xff48bcff,
+ 0xff58c3ff,0xff46bcff,0xff36b4ff,0xff35b4ff,0xff34b5ff,0xff33b4ff,0xff56c2ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff32b2ff,0xff32b2ff,0xff30b1ff,
+ 0xff30b1ff,0xff2fb1ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff3fb7ff,0xff51bdff,0xff50bdff,0xff2cadff,0xff4fbcff,0xff2bacff,0xff2bacff,0xff4dbcff,
+ 0xff2aabff,0xff4cbbff,0xff29abff,0xff28aaff,0xff4cbbff,0xff28aaff,0xff4bb9ff,0xff27a9ff,0xff49baff,0xff49b9ff,0xff25a8ff,0xff49b8ff,0xff24a8ff,0xff24a8ff,
+ 0xff49b8ff,0xff24a5ff,0xff47b7ff,0xff23a5ff,0xff23a5ff,0xff46b5ff,0xff33adff,0xff46b5ff,0xff46b5ff,0xff45b4ff,0xff20a3ff,0xff20a2ff,0xff1fa3ff,0xff31abff,
+ 0xff43b3ff,0xff42b3ff,0xff41b3ff,0xff1da0ff,0xff1ca1ff,0xff41b2ff,0xff2ea9ff,0xff41b1ff,0xff55bbff,0xff1ca0ff,0xff41b3ff,0xff1da1ff,0xff1da1ff,0xff42b3ff,
+ 0xff1fa2ff,0xff43b3ff,0xff4fcaff,0xff50caff,0xff51cbff,0xff51cbff,0xff52cbff,0xff52ccff,0xff76d6ff,0xff53cdff,0xff76d6ff,0xff54cdff,0xff77d7ff,0xff77d7ff,
+ 0xff66d3ff,0xff56ceff,0xff79d8ff,0xff79d9ff,0xff58cfff,0xff6ad4ff,0xff7bd9ff,0xff59d0ff,0xff59cfff,0xff7bd9ff,0xff7ad9ff,0xff58cfff,0xff79d9ff,0xff67d3ff,
+ 0xff78d7ff,0xff77d8ff,0xff76d7ff,0xff65d2ff,0xff54cdff,0xff76d6ff,0xff52ccff,0xff75d6ff,0xff52cbff,0xff62d0ff,0xff74d6ff,0xff50caff,0xff62cfff,0xff4fc9ff,
+ 0xff72d4ff,0xff72d4ff,0xff72d4ff,0xff4dc9ff,0xff5fcdff,0xff4cc7ff,0xff6fd2ff,0xff4bc7ff,0xff4ac7ff,0xff6fd1ff,0xff49c6ff,0xff49c6ff,0xff49c5ff,0xff48c5ff,
+ 0xff47c5ff,0xff46c4ff,0xff47c4ff,0xff6bd0ff,0xff45c4ff,0xff6acfff,0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff43c2ff,0xff69cdff,0xff41c1ff,0xff54c7ff,0xff41c1ff,
+ 0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3abcff,0xff3abcff,
+ 0xff61caff,0xff39bcff,0xff38bbff,0xff73cfff,0xff37bbff,0xff5fc8ff,0xff36baff,0xff36baff,0xff5ec8ff,0xff34b9ff,0xff5dc7ff,0xff34b9ff,0xff70cdff,0xff32b8ff,
+ 0xff6fccff,0xff46beff,0xff31b7ff,0xff30b7ff,0xff59c5ff,0xff2fb6ff,0xff59c5ff,0xff2eb5ff,0xff2eb5ff,0xff57c4ff,0xff2db4ff,0xff2cb4ff,0xff2cb4ff,0xff56c2ff,
+ 0xff2ab3ff,0xff2ab3ff,0xff3fbaff,0xff29b2ff,0xff29b2ff,0xff28b1ff,0xff53c1ff,0xff3db9ff,0xff27b0ff,0xff52c1ff,0xff52c0ff,0xff25b0ff,0xff52c0ff,0xff26b0ff,
+ 0xff52c0ff,0xff27b1ff,0xff3eb9ff,0xff54c1ff,0xff29b2ff,0xff54c1ff,0xff40bdff,0xff40bdff,0xff40bdff,0xff41bdff,0xff41bfff,0xff62ccff,0xff62ccff,0xff52c6ff,
+ 0xff52c7ff,0xff63ccff,0xff54c7ff,0xff64ceff,0xff55c8ff,0xff66ceff,0xff46c2ff,0xff56c9ff,0xff66cfff,0xff57c9ff,0xff57cbff,0xff48c5ff,0xff48c3ff,0xff57c9ff,
+ 0xff57c9ff,0xff67ceff,0xff56c8ff,0xff55c8ff,0xff45c2ff,0xff44c1ff,0xff63cdff,0xff53c7ff,0xff63ccff,0xff52c7ff,0xff41bfff,0xff42c0ff,0xff61ccff,0xff41bfff,
+ 0xff50c3ff,0xff60cbff,0xff4fc3ff,0xff3fbcff,0xff4fc2ff,0xff3ebcff,0xff4dc1ff,0xff3dbbff,0xff6ecfff,0xff4cc1ff,0xff3cbaff,0xff5cc7ff,0xff5cc7ff,0xff3ab9ff,
+ 0xff3ab9ff,0xff3ab9ff,0xff39b9ff,0xff39b8ff,0xff38b7ff,0xff38b7ff,0xff38b8ff,0xff47bdff,0xff37b5ff,0xff46bcff,0xff35b4ff,0xff35b4ff,0xff34b4ff,0xff34b3ff,
+ 0xff44bbff,0xff55c1ff,0xff43baff,0xff33b3ff,0xff32b3ff,0xff32b2ff,0xff31b2ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2fb0ff,0xff2fb0ff,0xff2eb0ff,0xff2eb0ff,
+ 0xff2eb0ff,0xff2daeff,0xff2dadff,0xff2daeff,0xff3db5ff,0xff2badff,0xff2bacff,0xff4ebcff,0xff4dbcff,0xff3ab3ff,0xff29abff,0xff4cbbff,0xff4cbaff,0xff39b2ff,
+ 0xff39b2ff,0xff4ab9ff,0xff38b1ff,0xff4ab9ff,0xff38b0ff,0xff49b8ff,0xff37b0ff,0xff37b0ff,0xff49b8ff,0xff48b8ff,0xff35aeff,0xff23a5ff,0xff22a5ff,0xff33adff,
+ 0xff22a4ff,0xff21a4ff,0xff21a3ff,0xff20a3ff,0xff45b4ff,0xff45b4ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1ea1ff,0xff41b3ff,0xff2faaff,0xff41b2ff,0xff1ca0ff,
+ 0xff2ea9ff,0xff41b2ff,0xff41b2ff,0xff1ca0ff,0xff1da1ff,0xff41b3ff,0xff1ea1ff,0xff30aaff,0xff1ea2ff,0xff31abff,0xff50caff,0xff50caff,0xff50caff,0xff51cbff,
+ 0xff51cbff,0xff53ccff,0xff53ccff,0xff53ccff,0xff54cdff,0xff54cdff,0xff55cdff,0xff66d3ff,0xff55ceff,0xff57ceff,0xff56ceff,0xff57cfff,0xff58cfff,0xff58cfff,
+ 0xff58cfff,0xff5ad0ff,0xff59d0ff,0xff58cfff,0xff57cfff,0xff57cfff,0xff57cfff,0xff56ceff,0xff78d7ff,0xff77d8ff,0xff55cdff,0xff54cdff,0xff54ccff,0xff53cdff,
+ 0xff52ccff,0xff52ccff,0xff51cbff,0xff51cbff,0xff51caff,0xff50cbff,0xff50c9ff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,0xff4dc9ff,0xff4dc9ff,0xff4dc8ff,0xff4cc7ff,
+ 0xff4bc8ff,0xff4bc7ff,0xff4bc6ff,0xff4ac6ff,0xff49c6ff,0xff49c5ff,0xff48c6ff,0xff47c6ff,0xff48c5ff,0xff47c5ff,0xff46c4ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,
+ 0xff45c3ff,0xff44c3ff,0xff44c3ff,0xff43c2ff,0xff42c1ff,0xff41c1ff,0xff41c1ff,0xff41c1ff,0xff41c0ff,0xff40c0ff,0xff3fbfff,0xff3fc0ff,0xff3ebfff,0xff3dbfff,
+ 0xff3dbfff,0xff3cbeff,0xff3cbeff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff3abcff,0xff39bcff,0xff39bcff,0xff38bcff,0xff38bbff,0xff4cc2ff,0xff37baff,0xff36baff,
+ 0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff34b8ff,0xff34b9ff,0xff32b8ff,0xff33b8ff,0xff5bc6ff,0xff5ac5ff,0xff31b7ff,0xff30b6ff,0xff30b6ff,0xff2fb5ff,
+ 0xff2eb6ff,0xff2eb6ff,0xff2db5ff,0xff2db5ff,0xff2db4ff,0xff2cb4ff,0xff2cb3ff,0xff2bb3ff,0xff2ab3ff,0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff28b2ff,0xff28b1ff,
+ 0xff3db9ff,0xff28b1ff,0xff26b0ff,0xff26b0ff,0xff26afff,0xff25b0ff,0xff26b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff28b1ff,0xff29b2ff,
+ 0xff40bdff,0xff40bdff,0xff50c5ff,0xff50c3ff,0xff41c0ff,0xff41bfff,0xff42c0ff,0xff42c0ff,0xff42c0ff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,
+ 0xff46c2ff,0xff46c2ff,0xff47c3ff,0xff47c3ff,0xff47c5ff,0xff48c5ff,0xff47c5ff,0xff47c3ff,0xff47c3ff,0xff46c3ff,0xff46c2ff,0xff45c2ff,0xff45c1ff,0xff44c2ff,
+ 0xff44c1ff,0xff43c0ff,0xff43c0ff,0xff42c0ff,0xff41bfff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff41bfff,0xff40bfff,0xff40bdff,0xff3fbcff,0xff3fbcff,0xff3ebcff,
+ 0xff3ebbff,0xff3dbbff,0xff3dbbff,0xff3cbaff,0xff3cbbff,0xff3bbaff,0xff3bbaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff3ab8ff,0xff39b9ff,0xff38b7ff,0xff38b7ff,
+ 0xff38b7ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff35b4ff,0xff35b4ff,0xff34b4ff,0xff34b4ff,0xff34b3ff,0xff33b3ff,0xff43baff,0xff32b3ff,0xff32b3ff,0xff31b2ff,
+ 0xff31b1ff,0xff31b1ff,0xff30b1ff,0xff2fb0ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eb0ff,0xff2eaeff,0xff2dadff,0xff2cadff,0xff2cadff,0xff2cacff,
+ 0xff3cb5ff,0xff2bacff,0xff2aacff,0xff29acff,0xff29aaff,0xff28aaff,0xff28aaff,0xff28aaff,0xff28aaff,0xff27aaff,0xff27a9ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,
+ 0xff25a8ff,0xff25a8ff,0xff24a7ff,0xff24a7ff,0xff23a7ff,0xff23a5ff,0xff22a5ff,0xff33adff,0xff22a5ff,0xff21a4ff,0xff21a3ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,
+ 0xff20a2ff,0xff1fa2ff,0xff1ea2ff,0xff1ea1ff,0xff1ea2ff,0xff1da0ff,0xff1da0ff,0xff1ca0ff,0xff1ba0ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1da1ff,0xff1da1ff,
+ 0xff1da1ff,0xff1ea2ff,0xff1fa2ff,0xff31acff,0xff4fcaff,0xff50caff,0xff73d6ff,0xff74d6ff,0xff52cbff,0xff52cbff,0xff53cbff,0xff54ccff,0xff54ccff,0xff76d6ff,
+ 0xff76d7ff,0xff55cdff,0xff56ceff,0xff56ceff,0xff57cfff,0xff57cfff,0xff8addff,0xff59cfff,0xff58d0ff,0xff59d0ff,0xff59cfff,0xff58cfff,0xff57cfff,0xff57cfff,
+ 0xff57ceff,0xff56ceff,0xff55ceff,0xff77d7ff,0xff54cdff,0xff54cdff,0xff54ccff,0xff53ccff,0xff52ccff,0xff52ccff,0xff51ccff,0xff51cbff,0xff50caff,0xff50caff,
+ 0xff50caff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,0xff4dc8ff,0xff4dc8ff,0xff4cc8ff,0xff4cc7ff,0xff4bc8ff,0xff4bc7ff,0xff4ac6ff,0xff4ac7ff,0xff49c7ff,0xff49c5ff,
+ 0xff48c6ff,0xff48c5ff,0xff6dd0ff,0xff47c4ff,0xff47c4ff,0xff6bd0ff,0xff45c3ff,0xff45c3ff,0xff44c3ff,0xff44c2ff,0xff43c2ff,0xff43c2ff,0xff42c2ff,0xff41c2ff,
+ 0xff67cdff,0xff67cdff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3ebfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff3bbeff,0xff3bbdff,0xff3bbdff,
+ 0xff3abdff,0xff3abdff,0xff39bcff,0xff4cc2ff,0xff4cc2ff,0xff37bbff,0xff36baff,0xff5fc8ff,0xff36baff,0xff36b9ff,0xff35baff,0xff34b9ff,0xff34b9ff,0xff33b8ff,
+ 0xff33b9ff,0xff32b8ff,0xff32b7ff,0xff5ac5ff,0xff30b7ff,0xff30b7ff,0xff2fb6ff,0xff59c5ff,0xff2eb6ff,0xff2fb6ff,0xff43bcff,0xff42bcff,0xff2cb5ff,0xff2cb4ff,
+ 0xff56c3ff,0xff2cb3ff,0xff2ab3ff,0xff2ab2ff,0xff2ab3ff,0xff29b2ff,0xff53c1ff,0xff28b1ff,0xff28b1ff,0xff28b1ff,0xff27b0ff,0xff26b0ff,0xff25afff,0xff25afff,
+ 0xff25b0ff,0xff26b1ff,0xff27b1ff,0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff55c1ff,0xff40bdff,0xff40bfff,0xff50c5ff,0xff50c5ff,0xff41bfff,0xff41bfff,
+ 0xff42c0ff,0xff42c0ff,0xff42c1ff,0xff63cdff,0xff44c1ff,0xff54c7ff,0xff55c7ff,0xff65ceff,0xff46c3ff,0xff46c3ff,0xff67cfff,0xff47c3ff,0xff57cbff,0xff48c5ff,
+ 0xff48c3ff,0xff57c9ff,0xff57c9ff,0xff66cfff,0xff55c8ff,0xff45c2ff,0xff55c8ff,0xff55c8ff,0xff44c1ff,0xff53c7ff,0xff63ccff,0xff52c6ff,0xff41bfff,0xff41bfff,
+ 0xff41bfff,0xff41bfff,0xff50c5ff,0xff60cbff,0xff50c3ff,0xff3fbdff,0xff5fc9ff,0xff5fc9ff,0xff3ebbff,0xff3dbcff,0xff3cbbff,0xff3cbaff,0xff4bc1ff,0xff4bc1ff,
+ 0xff5cc6ff,0xff3ab9ff,0xff49c0ff,0xff5bc6ff,0xff49c0ff,0xff49bfff,0xff6bccff,0xff5ac6ff,0xff37b7ff,0xff59c3ff,0xff58c3ff,0xff47bcff,0xff46bcff,0xff58c3ff,
+ 0xff57c2ff,0xff45bbff,0xff33b4ff,0xff43baff,0xff43baff,0xff55c1ff,0xff43baff,0xff54c1ff,0xff32b2ff,0xff41b8ff,0xff53c0ff,0xff41b8ff,0xff2fb1ff,0xff52bfff,
+ 0xff40b8ff,0xff2eb0ff,0xff3fb7ff,0xff51bdff,0xff3eb5ff,0xff2dadff,0xff2cadff,0xff4fbdff,0xff2bacff,0xff3bb4ff,0xff4dbbff,0xff4cbbff,0xff29abff,0xff4cbbff,
+ 0xff4cbbff,0xff28aaff,0xff39b1ff,0xff28aaff,0xff38b1ff,0xff27a9ff,0xff38b0ff,0xff37b0ff,0xff25a8ff,0xff36aeff,0xff49b8ff,0xff48b7ff,0xff24a7ff,0xff23a7ff,
+ 0xff47b7ff,0xff22a5ff,0xff33adff,0xff46b5ff,0xff45b4ff,0xff21a3ff,0xff45b4ff,0xff44b4ff,0xff20a3ff,0xff43b3ff,0xff57bcff,0xff30aaff,0xff1ea1ff,0xff41b2ff,
+ 0xff2eaaff,0xff2eaaff,0xff2ea9ff,0xff41b2ff,0xff2ea9ff,0xff2ea9ff,0xff1ca0ff,0xff1da1ff,0xff2faaff,0xff1ea1ff,0xff31abff,0xff31abff,0xff4fcaff,0xff50caff,
+ 0xff50caff,0xff51cbff,0xff52cbff,0xff75d6ff,0xff76d6ff,0xff64d1ff,0xff76d7ff,0xff87dcff,0xff66d2ff,0xff78d7ff,0xff67d3ff,0xff56ceff,0xff79d9ff,0xff57ceff,
+ 0xff79d9ff,0xff59cfff,0xff7ad9ff,0xff59d0ff,0xff58d0ff,0xff7bd9ff,0xff79d9ff,0xff57cfff,0xff78d8ff,0xff57ceff,0xff55ceff,0xff77d8ff,0xff54cdff,0xff88dcff,
+ 0xff53ccff,0xff76d6ff,0xff52cbff,0xff75d6ff,0xff74d6ff,0xff62cfff,0xff74d5ff,0xff50caff,0xff62cfff,0xff61cfff,0xff60ceff,0xff4ec9ff,0xff5fceff,0xff5fceff,
+ 0xff70d3ff,0xff70d3ff,0xff70d2ff,0xff5dcdff,0xff4bc7ff,0xff6fd1ff,0xff5bccff,0xff49c5ff,0xff6ed1ff,0xff47c6ff,0xff6cd1ff,0xff46c5ff,0xff46c4ff,0xff7dd6ff,
+ 0xff45c3ff,0xff6acfff,0xff45c3ff,0xff44c2ff,0xff43c3ff,0xff43c2ff,0xff42c2ff,0xff68ceff,0xff41c1ff,0xff66cdff,0xff53c7ff,0xff40c0ff,0xff66cdff,0xff66cdff,
+ 0xff3ebfff,0xff65cbff,0xff3ebfff,0xff63cbff,0xff63cbff,0xff63caff,0xff63caff,0xff3abcff,0xff62caff,0xff3abcff,0xff39bcff,0xff61c9ff,0xff38bbff,0xff60c9ff,
+ 0xff37bbff,0xff73cfff,0xff4ac1ff,0xff35baff,0xff35baff,0xff5dc7ff,0xff5dc6ff,0xff33b8ff,0xff5cc6ff,0xff33b7ff,0xff31b7ff,0xff5ac5ff,0xff31b7ff,0xff5ac5ff,
+ 0xff30b6ff,0xff6dccff,0xff2fb5ff,0xff2eb5ff,0xff57c4ff,0xff2db5ff,0xff57c3ff,0xff2db3ff,0xff6bcbff,0xff56c2ff,0xff2bb3ff,0xff2ab3ff,0xff54c1ff,0xff29b2ff,
+ 0xff53c1ff,0xff28b1ff,0xff52c1ff,0xff27b0ff,0xff52c0ff,0xff26b1ff,0xff67c8ff,0xff25afff,0xff51bfff,0xff52c1ff,0xff27b0ff,0xff27b1ff,0xff53c1ff,0xff28b1ff,
+ 0xff53c1ff,0xff29b2ff,0xff40bdff,0xff40bfff,0xff41bdff,0xff41bdff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff43c1ff,0xff63ccff,0xff43c1ff,0xff64cdff,
+ 0xff44c2ff,0xff45c2ff,0xff66ceff,0xff47c3ff,0xff66cfff,0xff48c5ff,0xff67cfff,0xff49c5ff,0xff48c5ff,0xff68cfff,0xff67cfff,0xff67cfff,0xff56c8ff,0xff45c2ff,
+ 0xff44c1ff,0xff64cdff,0xff43c1ff,0xff63cdff,0xff43c1ff,0xff63ccff,0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff60cbff,0xff40bdff,0xff40bdff,0xff3fbcff,
+ 0xff4fc2ff,0xff5fc9ff,0xff3ebbff,0xff3dbbff,0xff3cbbff,0xff3cbbff,0xff5dc7ff,0xff3bbaff,0xff3abaff,0xff5cc7ff,0xff5bc6ff,0xff5bc6ff,0xff6dccff,0xff39b8ff,
+ 0xff5ac6ff,0xff38b7ff,0xff37b8ff,0xff59c5ff,0xff37b5ff,0xff58c5ff,0xff47bcff,0xff58c2ff,0xff57c3ff,0xff45bbff,0xff33b3ff,0xff56c1ff,0xff33b3ff,0xff54c1ff,
+ 0xff33b2ff,0xff31b2ff,0xff54c0ff,0xff54c1ff,0xff30b1ff,0xff53c0ff,0xff2fb0ff,0xff52bfff,0xff51bfff,0xff51bdff,0xff63c6ff,0xff50bdff,0xff50bdff,0xff2cadff,
+ 0xff4fbdff,0xff2cadff,0xff2bacff,0xff4ebcff,0xff2aabff,0xff4dbbff,0xff3ab3ff,0xff4cbaff,0xff4bbbff,0xff4cbaff,0xff28aaff,0xff4bbaff,0xff4ab9ff,0xff27a9ff,
+ 0xff25a9ff,0xff49b8ff,0xff25a8ff,0xff49b8ff,0xff24a7ff,0xff48b8ff,0xff24a5ff,0xff48b8ff,0xff23a5ff,0xff22a4ff,0xff46b5ff,0xff21a4ff,0xff45b5ff,0xff45b5ff,
+ 0xff20a3ff,0xff20a3ff,0xff44b3ff,0xff1fa2ff,0xff42b3ff,0xff1ea1ff,0xff30aaff,0xff41b3ff,0xff41b2ff,0xff1ca0ff,0xff41b2ff,0xff1b9fff,0xff41b2ff,0xff41b3ff,
+ 0xff1da0ff,0xff1da1ff,0xff42b3ff,0xff1ea2ff,0xff43b3ff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff50cbff,0xff51cbff,0xff51cbff,0xff52ccff,0xff53ccff,0xff53cdff,
+ 0xff54cdff,0xff76d6ff,0xff54cdff,0xff78d7ff,0xff78d8ff,0xff78d8ff,0xff68d4ff,0xff68d4ff,0xff8addff,0xff7bd9ff,0xff6ad5ff,0xff7bd9ff,0xff7bd9ff,0xff7bd9ff,
+ 0xff79d9ff,0xff79d9ff,0xff68d4ff,0xff57cfff,0xff78d8ff,0xff88dcff,0xff65d2ff,0xff76d7ff,0xff54ccff,0xff76d6ff,0xff53cbff,0xff52ccff,0xff52cbff,0xff51cbff,
+ 0xff73d6ff,0xff73d5ff,0xff73d5ff,0xff61ceff,0xff72d5ff,0xff71d4ff,0xff5fceff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff6fd3ff,0xff6fd2ff,0xff6fd1ff,0xff5bccff,
+ 0xff6ed1ff,0xff6ed1ff,0xff7fd6ff,0xff48c5ff,0xff5acbff,0xff6bd1ff,0xff59caff,0xff6bd0ff,0xff45c4ff,0xff6acfff,0xff44c3ff,0xff43c2ff,0xff44c3ff,0xff43c2ff,
+ 0xff68ceff,0xff41c1ff,0xff42c1ff,0xff66cdff,0xff40c0ff,0xff40c0ff,0xff66ccff,0xff65cdff,0xff65ccff,0xff65ccff,0xff3dbeff,0xff64cbff,0xff50c4ff,0xff63cbff,
+ 0xff63caff,0xff63caff,0xff62caff,0xff3abcff,0xff61caff,0xff39bcff,0xff37bbff,0xff5fc9ff,0xff5fc9ff,0xff72cfff,0xff4ac1ff,0xff5ec7ff,0xff5ec8ff,0xff5dc8ff,
+ 0xff34b9ff,0xff5dc7ff,0xff33b8ff,0xff32b7ff,0xff5bc5ff,0xff6fcdff,0xff46bdff,0xff5ac5ff,0xff59c5ff,0xff6dccff,0xff2fb6ff,0xff58c5ff,0xff2db5ff,0xff2db5ff,
+ 0xff57c3ff,0xff57c3ff,0xff6bcbff,0xff40bcff,0xff56c2ff,0xff55c2ff,0xff3fbbff,0xff29b2ff,0xff54c1ff,0xff54c1ff,0xff3ebaff,0xff53c1ff,0xff52c1ff,0xff26b0ff,
+ 0xff51c0ff,0xff25b0ff,0xff51c0ff,0xff3cb9ff,0xff52c1ff,0xff52c1ff,0xff53c1ff,0xff53c1ff,0xff28b1ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff40bdff,0xff41bfff,
+ 0xff41bfff,0xff41c0ff,0xff42bfff,0xff42c0ff,0xff43c0ff,0xff43c0ff,0xff44c1ff,0xff64cdff,0xff45c2ff,0xff45c2ff,0xff46c2ff,0xff46c3ff,0xff46c3ff,0xff47c3ff,
+ 0xff47c5ff,0xff49c5ff,0xff48c5ff,0xff47c5ff,0xff66cfff,0xff66cfff,0xff66cfff,0xff45c2ff,0xff44c2ff,0xff44c1ff,0xff43c1ff,0xff43c0ff,0xff43c0ff,0xff42c1ff,
+ 0xff42c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff41bdff,0xff40bdff,0xff40bdff,0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff3ebcff,0xff3dbcff,0xff3cbbff,0xff3cbbff,
+ 0xff5cc7ff,0xff3abaff,0xff3abaff,0xff3abaff,0xff3ab9ff,0xff3ab9ff,0xff3ab9ff,0xff39b8ff,0xff38b7ff,0xff38b7ff,0xff37b8ff,0xff37b7ff,0xff36b7ff,0xff35b7ff,
+ 0xff35b5ff,0xff35b4ff,0xff34b4ff,0xff33b4ff,0xff56c1ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff32b3ff,0xff31b2ff,0xff31b1ff,0xff30b2ff,0xff30b1ff,0xff2fb1ff,
+ 0xff2fb0ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff2eb0ff,0xff2daeff,0xff2dadff,0xff4fbdff,0xff2badff,0xff2badff,0xff2bacff,0xff2bacff,0xff2aabff,0xff29abff,
+ 0xff29abff,0xff29abff,0xff28aaff,0xff28aaff,0xff27aaff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff25a8ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,
+ 0xff48b7ff,0xff23a5ff,0xff23a5ff,0xff22a4ff,0xff22a4ff,0xff22a4ff,0xff20a3ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff1fa3ff,0xff20a2ff,0xff1fa1ff,0xff1ea1ff,
+ 0xff30aaff,0xff41b2ff,0xff41b2ff,0xff2ea9ff,0xff1ca0ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1da1ff,0xff1da0ff,0xff1da2ff,0xff42b3ff,0xff1ea2ff,0xff1fa2ff,
+ 0xff50caff,0xff50caff,0xff51caff,0xff51cbff,0xff51cbff,0xff52cbff,0xff52ccff,0xff53ccff,0xff54cdff,0xff54ccff,0xff54cdff,0xff55ceff,0xff56cdff,0xff57ceff,
+ 0xff57ceff,0xff57cfff,0xff58cfff,0xff58cfff,0xff59d0ff,0xff59cfff,0xff59d0ff,0xff59cfff,0xff58cfff,0xff58ceff,0xff57ceff,0xff56ceff,0xff56ceff,0xff55cdff,
+ 0xff54cdff,0xff54cdff,0xff53cdff,0xff54ccff,0xff53ccff,0xff52ccff,0xff51cbff,0xff51caff,0xff51cbff,0xff50caff,0xff4fcaff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,
+ 0xff4dc9ff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff4bc8ff,0xff4bc7ff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,0xff49c6ff,0xff48c5ff,0xff48c5ff,0xff48c5ff,0xff47c4ff,
+ 0xff46c4ff,0xff45c4ff,0xff46c4ff,0xff44c3ff,0xff45c3ff,0xff43c2ff,0xff43c2ff,0xff43c2ff,0xff42c1ff,0xff42c1ff,0xff41c1ff,0xff41c0ff,0xff40c1ff,0xff40c0ff,
+ 0xff3fc0ff,0xff3fbfff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3cbeff,0xff3cbeff,0xff3bbeff,0xff3bbdff,0xff3bbdff,0xff3abdff,0xff39bcff,0xff39bcff,0xff38bcff,
+ 0xff38bbff,0xff38bbff,0xff37bbff,0xff36baff,0xff36baff,0xff35baff,0xff35b9ff,0xff34b9ff,0xff34b9ff,0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff32b7ff,0xff31b7ff,
+ 0xff31b6ff,0xff30b6ff,0xff2fb6ff,0xff30b6ff,0xff2fb5ff,0xff2eb5ff,0xff2eb5ff,0xff2db4ff,0xff2cb5ff,0xff2cb4ff,0xff2cb4ff,0xff2bb3ff,0xff2bb3ff,0xff2ab2ff,
+ 0xff2ab2ff,0xff29b2ff,0xff29b2ff,0xff28b1ff,0xff28b1ff,0xff27b1ff,0xff27b1ff,0xff26b0ff,0xff25afff,0xff25b0ff,0xff25b0ff,0xff26b0ff,0xff26b1ff,0xff27b1ff,
+ 0xff27b1ff,0xff28b1ff,0xff28b2ff,0xff29b2ff,0xff3fbdff,0xff40bfff,0xff61ccff,0xff61cbff,0xff41bfff,0xff41c0ff,0xff42bfff,0xff42c0ff,0xff52c6ff,0xff43c1ff,
+ 0xff44c1ff,0xff44c1ff,0xff45c2ff,0xff45c2ff,0xff66ceff,0xff56c9ff,0xff47c3ff,0xff47c5ff,0xff47c5ff,0xff48c5ff,0xff48c3ff,0xff48c5ff,0xff47c3ff,0xff46c2ff,
+ 0xff46c3ff,0xff46c2ff,0xff45c2ff,0xff44c1ff,0xff43c1ff,0xff43c1ff,0xff43c1ff,0xff63ccff,0xff42c0ff,0xff41bfff,0xff41bfff,0xff50c5ff,0xff40bdff,0xff40bdff,
+ 0xff40bdff,0xff3fbdff,0xff3fbdff,0xff3ebcff,0xff3dbcff,0xff3dbcff,0xff4cc1ff,0xff3cbaff,0xff3bbaff,0xff3bbaff,0xff3bbaff,0xff4ac1ff,0xff3ab9ff,0xff3ab9ff,
+ 0xff5bc6ff,0xff39b8ff,0xff38b8ff,0xff38b8ff,0xff48bfff,0xff37b7ff,0xff36b5ff,0xff36b5ff,0xff35b5ff,0xff46bbff,0xff34b4ff,0xff34b4ff,0xff33b4ff,0xff33b3ff,
+ 0xff33b2ff,0xff33b3ff,0xff32b2ff,0xff32b2ff,0xff31b1ff,0xff31b1ff,0xff30b1ff,0xff2fb0ff,0xff2fb1ff,0xff2eb0ff,0xff2eb0ff,0xff51bdff,0xff2eaeff,0xff2daeff,
+ 0xff2daeff,0xff2cadff,0xff2cadff,0xff2badff,0xff2badff,0xff2bacff,0xff2aacff,0xff29acff,0xff28abff,0xff3ab3ff,0xff28abff,0xff28aaff,0xff39b2ff,0xff4bb9ff,
+ 0xff38b1ff,0xff26a8ff,0xff26a8ff,0xff25a8ff,0xff49b8ff,0xff24a7ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff24a5ff,0xff23a5ff,0xff22a4ff,0xff22a5ff,0xff21a4ff,
+ 0xff45b4ff,0xff20a3ff,0xff20a3ff,0xff20a2ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1ea1ff,0xff1da1ff,0xff1da1ff,0xff1ca0ff,0xff1ca1ff,0xff1ca0ff,0xff2ea9ff,
+ 0xff1ca0ff,0xff1ca0ff,0xff2fa9ff,0xff2faaff,0xff1ea1ff,0xff1ea2ff,0xff31abff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff74d5ff,0xff74d6ff,0xff51ccff,0xff52ccff,
+ 0xff53ccff,0xff53ccff,0xff76d7ff,0xff54ccff,0xff54cdff,0xff55cdff,0xff55ceff,0xff78d8ff,0xff56ceff,0xff7ad9ff,0xff58cfff,0xff59cfff,0xff59cfff,0xff59d0ff,
+ 0xff58cfff,0xff58cfff,0xff58cfff,0xff58cfff,0xff57ceff,0xff56ceff,0xff56ceff,0xff55ceff,0xff55cdff,0xff54cdff,0xff54ccff,0xff76d6ff,0xff52ccff,0xff52cbff,
+ 0xff51cbff,0xff74d6ff,0xff50cbff,0xff50caff,0xff4fcaff,0xff4fc9ff,0xff4ecaff,0xff4ec9ff,0xff4ec8ff,0xff4dc8ff,0xff5ecdff,0xff4cc7ff,0xff4cc7ff,0xff4bc7ff,
+ 0xff4ac7ff,0xff6fd1ff,0xff49c6ff,0xff49c6ff,0xff6dd1ff,0xff48c5ff,0xff47c5ff,0xff46c4ff,0xff6bd0ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff6acfff,
+ 0xff43c2ff,0xff42c2ff,0xff42c1ff,0xff42c1ff,0xff41c1ff,0xff41c1ff,0xff40c1ff,0xff40c0ff,0xff40c0ff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3cbeff,
+ 0xff63cbff,0xff3cbdff,0xff3bbdff,0xff3abdff,0xff3abdff,0xff39bcff,0xff39bcff,0xff38bbff,0xff38bbff,0xff37bbff,0xff37bbff,0xff36baff,0xff36baff,0xff5ec7ff,
+ 0xff35b9ff,0xff34baff,0xff5dc6ff,0xff33b9ff,0xff5cc6ff,0xff32b8ff,0xff32b8ff,0xff5ac5ff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2eb5ff,
+ 0xff2eb4ff,0xff2db5ff,0xff2cb4ff,0xff2cb4ff,0xff57c2ff,0xff2bb3ff,0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff2ab2ff,0xff29b2ff,0xff28b1ff,0xff27b1ff,0xff28b1ff,
+ 0xff27b0ff,0xff26b0ff,0xff26afff,0xff51c0ff,0xff26b0ff,0xff26b1ff,0xff27b0ff,0xff52c1ff,0xff27b1ff,0xff28b2ff,0xff3ebaff,0xff29b2ff,0xff3fbcff,0xff40bdff,
+ 0xff41bdff,0xff41bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff63cdff,0xff43c0ff,0xff43c1ff,0xff44c2ff,0xff44c2ff,0xff65ceff,0xff45c2ff,0xff76d4ff,
+ 0xff66cfff,0xff67cfff,0xff57c9ff,0xff68cfff,0xff68cfff,0xff58cbff,0xff67cfff,0xff66cfff,0xff66ceff,0xff56c8ff,0xff64ceff,0xff64ceff,0xff53c7ff,0xff43c1ff,
+ 0xff63cdff,0xff42c0ff,0xff52c6ff,0xff62ccff,0xff62ccff,0xff61ccff,0xff60cbff,0xff60ccff,0xff60cbff,0xff3fbdff,0xff5fc9ff,0xff3ebcff,0xff5ec8ff,0xff3dbbff,
+ 0xff6ecfff,0xff3cbbff,0xff4cc1ff,0xff5cc7ff,0xff5cc7ff,0xff5cc7ff,0xff3ab9ff,0xff5bc6ff,0xff3ab9ff,0xff49bfff,0xff5ac6ff,0xff59c5ff,0xff59c5ff,0xff58c5ff,
+ 0xff58c3ff,0xff58c3ff,0xff46bcff,0xff69c9ff,0xff58c2ff,0xff33b4ff,0xff56c1ff,0xff56c1ff,0xff56c1ff,0xff55c1ff,0xff54c1ff,0xff54c1ff,0xff41b8ff,0xff54c1ff,
+ 0xff30b1ff,0xff52c0ff,0xff2fb0ff,0xff2eb0ff,0xff51bdff,0xff2eaeff,0xff63c6ff,0xff51bdff,0xff50bdff,0xff4fbdff,0xff4fbdff,0xff4fbdff,0xff3cb4ff,0xff4dbcff,
+ 0xff4dbcff,0xff4cbbff,0xff3ab3ff,0xff5fc2ff,0xff4cbaff,0xff28aaff,0xff4bbaff,0xff27a9ff,0xff27a9ff,0xff26a9ff,0xff25a8ff,0xff49b8ff,0xff25a7ff,0xff24a7ff,
+ 0xff24a7ff,0xff24a7ff,0xff23a7ff,0xff24a5ff,0xff22a5ff,0xff22a5ff,0xff22a4ff,0xff46b5ff,0xff21a3ff,0xff45b4ff,0xff45b4ff,0xff44b4ff,0xff31acff,0xff57bcff,
+ 0xff42b3ff,0xff43b3ff,0xff30aaff,0xff41b3ff,0xff41b3ff,0xff2ea9ff,0xff41b2ff,0xff55baff,0xff2ea9ff,0xff1ca0ff,0xff1da0ff,0xff41b3ff,0xff1ea1ff,0xff1ea1ff,
+ 0xff56bcff,0xff20a2ff,0xff50caff,0xff50cbff,0xff51cbff,0xff51caff,0xff52cbff,0xff75d6ff,0xff76d6ff,0xff64d1ff,0xff76d6ff,0xff54cdff,0xff55ceff,0xff55ceff,
+ 0xff67d2ff,0xff68d3ff,0xff57ceff,0xff79d8ff,0xff58cfff,0xff7bd9ff,0xff7bd9ff,0xff59d0ff,0xff59cfff,0xff7ad9ff,0xff7ad9ff,0xff79d9ff,0xff79d9ff,0xff78d8ff,
+ 0xff78d7ff,0xff78d7ff,0xff77d7ff,0xff54cdff,0xff76d7ff,0xff53ccff,0xff75d6ff,0xff52ccff,0xff52cbff,0xff74d6ff,0xff62d0ff,0xff73d5ff,0xff84daff,0xff4fc9ff,
+ 0xff72d4ff,0xff60ceff,0xff60ceff,0xff4dc8ff,0xff71d3ff,0xff4cc8ff,0xff6fd2ff,0xff4bc7ff,0xff4bc7ff,0xff6fd2ff,0xff49c6ff,0xff6ed1ff,0xff48c5ff,0xff6dd1ff,
+ 0xff47c5ff,0xff47c5ff,0xff6bd0ff,0xff6bcfff,0xff45c3ff,0xff6ad0ff,0xff44c3ff,0xff6aceff,0xff43c2ff,0xff42c2ff,0xff68ceff,0xff41c1ff,0xff67cdff,0xff67cdff,
+ 0xff40c0ff,0xff40c0ff,0xff66ccff,0xff66ccff,0xff3ebfff,0xff65cbff,0xff3dbfff,0xff50c5ff,0xff50c4ff,0xff3bbeff,0xff63caff,0xff3abdff,0xff62caff,0xff61caff,
+ 0xff39bcff,0xff38bcff,0xff60c9ff,0xff73cfff,0xff5fc8ff,0xff72cfff,0xff36baff,0xff5ec7ff,0xff35baff,0xff34baff,0xff5dc6ff,0xff34b8ff,0xff33b8ff,0xff33b8ff,
+ 0xff47bfff,0xff46beff,0xff31b7ff,0xff31b7ff,0xff2fb7ff,0xff30b6ff,0xff2fb5ff,0xff2fb5ff,0xff2eb5ff,0xff2db5ff,0xff2db4ff,0xff57c3ff,0xff2cb4ff,0xff56c2ff,
+ 0xff2ab3ff,0xff2ab3ff,0xff55c2ff,0xff54c1ff,0xff29b2ff,0xff53c1ff,0xff53c1ff,0xff52c1ff,0xff52c1ff,0xff52c0ff,0xff26b0ff,0xff51c0ff,0xff26b0ff,0xff26b0ff,
+ 0xff26b1ff,0xff52c1ff,0xff27b1ff,0xff29b2ff,0xff54c1ff,0xff29b3ff,0xff40bdff,0xff40bdff,0xff41bdff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42bfff,0xff42c0ff,
+ 0xff63cdff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff64ceff,0xff46c2ff,0xff46c2ff,0xff66ceff,0xff46c3ff,0xff67cfff,0xff68cfff,0xff48c5ff,0xff48c3ff,0xff67cfff,
+ 0xff67cfff,0xff67cfff,0xff65ceff,0xff65ceff,0xff45c2ff,0xff44c1ff,0xff54c7ff,0xff53c7ff,0xff53c7ff,0xff43c0ff,0xff63ccff,0xff41bfff,0xff51c5ff,0xff61ccff,
+ 0xff60cbff,0xff40bdff,0xff60cbff,0xff3fbdff,0xff4ec2ff,0xff5fc9ff,0xff3dbcff,0xff3dbcff,0xff5dc8ff,0xff3cbaff,0xff5cc7ff,0xff3bbaff,0xff4ac1ff,0xff5cc6ff,
+ 0xff4ac1ff,0xff49c0ff,0xff3ab9ff,0xff5bc6ff,0xff38b8ff,0xff49bfff,0xff59c5ff,0xff59c5ff,0xff36b7ff,0xff58c5ff,0xff35b5ff,0xff58c3ff,0xff34b5ff,0xff45bbff,
+ 0xff56c1ff,0xff56c2ff,0xff33b2ff,0xff55c1ff,0xff32b2ff,0xff31b2ff,0xff54c1ff,0xff53c0ff,0xff30b1ff,0xff65c7ff,0xff30b1ff,0xff51bfff,0xff2eb0ff,0xff2eaeff,
+ 0xff63c6ff,0xff2dadff,0xff50bdff,0xff4fbdff,0xff2cadff,0xff2badff,0xff4ebcff,0xff4ebcff,0xff2aacff,0xff3ab3ff,0xff29abff,0xff4cbbff,0xff28abff,0xff39b2ff,
+ 0xff4bbaff,0xff28a9ff,0xff4ab9ff,0xff26a9ff,0xff49b9ff,0xff25a8ff,0xff25a8ff,0xff24a8ff,0xff36aeff,0xff24a7ff,0xff23a7ff,0xff23a5ff,0xff33adff,0xff22a4ff,
+ 0xff33adff,0xff33adff,0xff21a4ff,0xff45b4ff,0xff31acff,0xff20a2ff,0xff44b4ff,0xff43b3ff,0xff1ea1ff,0xff42b3ff,0xff42b3ff,0xff1da1ff,0xff1da0ff,0xff2ea9ff,
+ 0xff1ca0ff,0xff41b2ff,0xff2ea9ff,0xff1ca0ff,0xff1da1ff,0xff41b2ff,0xff1ea1ff,0xff1ea1ff,0xff43b3ff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff51cbff,0xff51cbff,
+ 0xff52ccff,0xff52cbff,0xff53cbff,0xff53ccff,0xff76d7ff,0xff76d7ff,0xff76d7ff,0xff66d2ff,0xff66d3ff,0xff56ceff,0xff56ceff,0xff68d4ff,0xff58cfff,0xff69d4ff,
+ 0xff59d0ff,0xff7bd9ff,0xff7bd9ff,0xff58cfff,0xff68d4ff,0xff57cfff,0xff68d3ff,0xff56ceff,0xff77d7ff,0xff77d7ff,0xff55cdff,0xff76d6ff,0xff54cdff,0xff53ccff,
+ 0xff52ccff,0xff75d6ff,0xff63d0ff,0xff62d0ff,0xff62cfff,0xff73d5ff,0xff72d5ff,0xff4fcaff,0xff4ec9ff,0xff60ceff,0xff4ec8ff,0xff5fcdff,0xff71d3ff,0xff70d2ff,
+ 0xff4cc7ff,0xff6fd2ff,0xff5ccdff,0xff5ccdff,0xff6ed1ff,0xff48c5ff,0xff49c6ff,0xff48c5ff,0xff6cd1ff,0xff5acbff,0xff5acaff,0xff59caff,0xff6ad0ff,0xff58c9ff,
+ 0xff44c3ff,0xff44c3ff,0xff69ceff,0xff43c2ff,0xff68cdff,0xff68cdff,0xff67cdff,0xff54c6ff,0xff40c0ff,0xff40c0ff,0xff52c5ff,0xff52c6ff,0xff65ccff,0xff50c5ff,
+ 0xff50c5ff,0xff50c5ff,0xff3dbeff,0xff3bbeff,0xff63caff,0xff63caff,0xff4ec4ff,0xff4ec3ff,0xff39bcff,0xff39bcff,0xff4cc2ff,0xff4bc2ff,0xff5fc9ff,0xff4ac1ff,
+ 0xff36baff,0xff36b9ff,0xff5ec8ff,0xff35b9ff,0xff47bfff,0xff5cc6ff,0xff47bfff,0xff47bfff,0xff47beff,0xff31b7ff,0xff31b7ff,0xff30b6ff,0xff6eccff,0xff44bdff,
+ 0xff2fb6ff,0xff43bcff,0xff6ccbff,0xff2db5ff,0xff57c4ff,0xff2cb4ff,0xff2cb4ff,0xff56c2ff,0xff3fbbff,0xff55c2ff,0xff2ab3ff,0xff3fbaff,0xff29b2ff,0xff3eb9ff,
+ 0xff27b1ff,0xff52c1ff,0xff52c0ff,0xff26b0ff,0xff25b0ff,0xff3bb8ff,0xff3bb7ff,0xff26b0ff,0xff52c1ff,0xff53c1ff,0xff3eb9ff,0xff3eb9ff,0xff54c1ff,0xff54c1ff,
+ 0xff40bdff,0xff40bfff,0xff40bfff,0xff41bfff,0xff41bfff,0xff41c0ff,0xff42c0ff,0xff42c1ff,0xff43c0ff,0xff43c1ff,0xff44c1ff,0xff54c8ff,0xff44c2ff,0xff45c2ff,
+ 0xff45c2ff,0xff46c2ff,0xff47c3ff,0xff47c3ff,0xff48c3ff,0xff48c5ff,0xff47c5ff,0xff48c3ff,0xff47c3ff,0xff47c3ff,0xff46c3ff,0xff45c2ff,0xff45c2ff,0xff45c1ff,
+ 0xff43c1ff,0xff53c7ff,0xff42c0ff,0xff42c0ff,0xff41c0ff,0xff41c0ff,0xff41bfff,0xff41bfff,0xff40bdff,0xff40bdff,0xff40bdff,0xff3fbdff,0xff3ebcff,0xff3ebcff,
+ 0xff3ebcff,0xff3dbbff,0xff3dbbff,0xff3cbaff,0xff3cbaff,0xff3abaff,0xff3abaff,0xff3abaff,0xff49c0ff,0xff3ab9ff,0xff39b8ff,0xff39b8ff,0xff38b8ff,0xff38b7ff,
+ 0xff38b7ff,0xff37b7ff,0xff36b7ff,0xff35b7ff,0xff35b5ff,0xff35b4ff,0xff35b4ff,0xff34b4ff,0xff44baff,0xff56c1ff,0xff43baff,0xff32b2ff,0xff32b2ff,0xff32b2ff,
+ 0xff31b2ff,0xff31b2ff,0xff30b1ff,0xff2fb0ff,0xff40b8ff,0xff2fb0ff,0xff2eb0ff,0xff2eaeff,0xff3fb7ff,0xff2daeff,0xff2dadff,0xff2caeff,0xff2cadff,0xff2badff,
+ 0xff2bacff,0xff2bacff,0xff2aabff,0xff29acff,0xff29abff,0xff28abff,0xff28abff,0xff28aaff,0xff27aaff,0xff27a9ff,0xff26aaff,0xff38b1ff,0xff26a9ff,0xff25a8ff,
+ 0xff25a7ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff23a5ff,0xff23a5ff,0xff33adff,0xff21a4ff,0xff20a4ff,0xff32adff,0xff20a3ff,0xff20a2ff,
+ 0xff1fa2ff,0xff1fa2ff,0xff1fa1ff,0xff1ea2ff,0xff1ea1ff,0xff1da0ff,0xff1ca0ff,0xff1ca0ff,0xff1ca0ff,0xff1b9fff,0xff1ba0ff,0xff1ca0ff,0xff1da0ff,0xff1da1ff,
+ 0xff1ea2ff,0xff1fa1ff,0xff1fa2ff,0xff1fa2ff,0xff4fcaff,0xff50caff,0xff62cfff,0xff62d0ff,0xff52cbff,0xff52ccff,0xff52cbff,0xff53ccff,0xff54ccff,0xff54cdff,
+ 0xff55cdff,0xff55cdff,0xff56ceff,0xff56ceff,0xff67d4ff,0xff58cfff,0xff57cfff,0xff58cfff,0xff59cfff,0xff59d0ff,0xff58d0ff,0xff58cfff,0xff57cfff,0xff58cfff,
+ 0xff57ceff,0xff57ceff,0xff56ceff,0xff55cdff,0xff54cdff,0xff54cdff,0xff54ccff,0xff64d1ff,0xff52ccff,0xff52cbff,0xff52cbff,0xff51caff,0xff50cbff,0xff50caff,
+ 0xff50caff,0xff4fcaff,0xff4ec9ff,0xff4ec9ff,0xff4ec8ff,0xff4dc9ff,0xff4dc8ff,0xff4cc8ff,0xff4cc8ff,0xff4bc7ff,0xff4ac7ff,0xff4ac6ff,0xff49c6ff,0xff49c6ff,
+ 0xff5accff,0xff48c5ff,0xff47c5ff,0xff47c4ff,0xff46c5ff,0xff46c4ff,0xff45c4ff,0xff45c3ff,0xff44c3ff,0xff43c2ff,0xff43c3ff,0xff42c2ff,0xff42c2ff,0xff41c1ff,
+ 0xff41c1ff,0xff40c1ff,0xff40c1ff,0xff3fc0ff,0xff3fc0ff,0xff3ebfff,0xff3ebfff,0xff3dbfff,0xff3dbeff,0xff3cbeff,0xff3cbeff,0xff50c4ff,0xff3bbdff,0xff3abdff,
+ 0xff3abcff,0xff39bcff,0xff39bcff,0xff39bcff,0xff38bcff,0xff38bbff,0xff37bbff,0xff36baff,0xff36baff,0xff35baff,0xff35baff,0xff34b9ff,0xff34b9ff,0xff33b8ff,
+ 0xff33b8ff,0xff33b8ff,0xff32b7ff,0xff31b7ff,0xff45beff,0xff31b6ff,0xff30b6ff,0xff2fb6ff,0xff2fb5ff,0xff2fb5ff,0xff2db5ff,0xff2eb4ff,0xff2db4ff,0xff2db4ff,
+ 0xff41bcff,0xff2bb4ff,0xff2ab3ff,0xff2bb3ff,0xff2ab3ff,0xff29b2ff,0xff28b1ff,0xff29b2ff,0xff27b1ff,0xff27b1ff,0xff27b0ff,0xff26b0ff,0xff26afff,0xff25afff,
+ 0xff25b0ff,0xff26b0ff,0xff27b0ff,0xff27b1ff,0xff28b1ff,0xff29b2ff,0xff29b2ff,0xff29b2ff,0xff40bdff,0xff40bdff,0xff60cbff,0xff61ccff,0xff41bfff,0xff41c0ff,
+ 0xff41c0ff,0xff42c0ff,0xff63ccff,0xff43c1ff,0xff44c1ff,0xff44c1ff,0xff44c2ff,0xff56c8ff,0xff56c8ff,0xff66cfff,0xff47c3ff,0xff47c5ff,0xff47c3ff,0xff48c5ff,
+ 0xff48c3ff,0xff47c3ff,0xff47c3ff,0xff46c3ff,0xff45c2ff,0xff46c2ff,0xff45c2ff,0xff44c1ff,0xff43c1ff,0xff43c1ff,0xff43c0ff,0xff63ccff,0xff42bfff,0xff41bfff,
+ 0xff41bfff,0xff61ccff,0xff41bdff,0xff40bdff,0xff40bdff,0xff3fbcff,0xff3ebcff,0xff3ebcff,0xff3dbcff,0xff3dbbff,0xff5dc8ff,0xff3bbaff,0xff3bbaff,0xff3bbaff,
+ 0xff3abaff,0xff5cc7ff,0xff3ab9ff,0xff3ab9ff,0xff5bc6ff,0xff39b8ff,0xff38b8ff,0xff38b8ff,0xff5ac5ff,0xff37b7ff,0xff36b5ff,0xff36b5ff,0xff36b5ff,0xff58c3ff,
+ 0xff34b4ff,0xff34b3ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff33b3ff,0xff32b3ff,0xff31b2ff,0xff31b2ff,0xff31b2ff,0xff30b1ff,0xff30b1ff,0xff2fb1ff,0xff2eb0ff,
+ 0xff40b8ff,0xff40b7ff,0xff2eaeff,0xff2eaeff,0xff2dadff,0xff2dadff,0xff2badff,0xff2bacff,0xff2bacff,0xff2aacff,0xff2aabff,0xff29abff,0xff29abff,0xff4cbbff,
+ 0xff28abff,0xff28aaff,0xff4bbaff,0xff4bb9ff,0xff49b9ff,0xff27a9ff,0xff26a9ff,0xff37b0ff,0xff37b0ff,0xff24a8ff,0xff24a8ff,0xff24a5ff,0xff24a7ff,0xff23a7ff,
+ 0xff22a5ff,0xff22a4ff,0xff22a4ff,0xff21a4ff,0xff46b5ff,0xff20a4ff,0xff20a3ff,0xff20a3ff,0xff1fa2ff,0xff1fa2ff,0xff1fa1ff,0xff1ea2ff,0xff1ea1ff,0xff1da1ff,
+ 0xff1da0ff,0xff1ca1ff,0xff1ca0ff,0xff41b1ff,0xff1ba0ff,0xff1ca0ff,0xff2ea9ff,0xff41b2ff,0xff1da1ff,0xff1ea1ff,0xff42b3ff,0xff1fa3ff,0xff50caff,0xff50caff,
+ 0xff62cfff,0xff62d0ff,0xff52cbff,0xff52ccff,0xff53ccff,0xff53ccff,0xff76d7ff,0xff54cdff,0xff55ceff,0xff55cdff,0xff56ceff,0xff79d8ff,0xff57ceff,0xff79d9ff,
+ 0xff7ad9ff,0xff69d5ff,0xff58cfff,0xff7bd9ff,0xff7bd9ff,0xff58cfff,0xff68d4ff,0xff68d3ff,0xff67d3ff,0xff56ceff,0xff77d8ff,0xff77d7ff,0xff55cdff,0xff54ccff,
+ 0xff65d1ff,0xff64d1ff,0xff52ccff,0xff75d6ff,0xff63d0ff,0xff74d5ff,0xff62cfff,0xff73d5ff,0xff61cfff,0xff4fc9ff,0xff61ceff,0xff4ec9ff,0xff60ceff,0xff4dc8ff,
+ 0xff71d3ff,0xff4cc8ff,0xff4bc8ff,0xff6fd2ff,0xff5cccff,0xff6fd2ff,0xff49c7ff,0xff5bccff,0xff5acbff,0xff47c5ff,0xff6dd1ff,0xff5acaff,0xff6bd0ff,0xff59caff,
+ 0xff6ad0ff,0xff58caff,0xff57c9ff,0xff7bd5ff,0xff69ceff,0xff43c2ff,0xff55c7ff,0xff68cdff,0xff54c7ff,0xff54c7ff,0xff53c6ff,0xff66cdff,0xff3fbfff,0xff51c5ff,
+ 0xff3ebfff,0xff51c5ff,0xff3dbfff,0xff3dbeff,0xff63caff,0xff3bbdff,0xff4fc4ff,0xff62caff,0xff4ec4ff,0xff4ec3ff,0xff4dc3ff,0xff61caff,0xff38bcff,0xff4bc2ff,
+ 0xff5fc9ff,0xff4bc1ff,0xff4ac1ff,0xff72cfff,0xff5ec7ff,0xff34b9ff,0xff5dc7ff,0xff34b8ff,0xff47bfff,0xff32b7ff,0xff32b7ff,0xff5ac5ff,0xff31b7ff,0xff30b7ff,
+ 0xff30b6ff,0xff30b6ff,0xff2fb5ff,0xff2eb5ff,0xff2db4ff,0xff2db5ff,0xff2cb4ff,0xff42bcff,0xff40bcff,0xff41bbff,0xff3fbbff,0xff55c2ff,0xff2ab3ff,0xff3fbaff,
+ 0xff54c1ff,0xff3eb9ff,0xff28b1ff,0xff52c1ff,0xff52c0ff,0xff26b0ff,0xff51c0ff,0xff67c8ff,0xff3cb8ff,0xff26b0ff,0xff26b0ff,0xff52c1ff,0xff28b2ff,0xff28b1ff,
+ 0xff54c1ff,0xff29b2ff,0xff3fbdff,0xff40bdff,0xff40bdff,0xff41bfff,0xff41bfff,0xff62ccff,0xff62ccff,0xff52c6ff,0xff63ccff,0xff43c1ff,0xff43c1ff,0xff44c1ff,
+ 0xff44c1ff,0xff65ceff,0xff46c3ff,0xff76d4ff,0xff46c3ff,0xff67cfff,0xff68cfff,0xff48c5ff,0xff48c3ff,0xff68cfff,0xff67cfff,0xff66cfff,0xff66cfff,0xff66ceff,
+ 0xff44c2ff,0xff44c1ff,0xff64cdff,0xff43c1ff,0xff63ccff,0xff43c0ff,0xff62ccff,0xff41c0ff,0xff51c5ff,0xff61cbff,0xff50c5ff,0xff40bfff,0xff5fcbff,0xff3fbdff,
+ 0xff5fc9ff,0xff3ebcff,0xff5ec8ff,0xff3dbbff,0xff5dc8ff,0xff3cbbff,0xff5dc7ff,0xff3bbaff,0xff4bc1ff,0xff5cc6ff,0xff3ab9ff,0xff5bc6ff,0xff39b8ff,0xff5bc6ff,
+ 0xff38b7ff,0xff49bdff,0xff5ac5ff,0xff59c5ff,0xff37b7ff,0xff58c3ff,0xff35b5ff,0xff58c2ff,0xff35b4ff,0xff34b4ff,0xff57c2ff,0xff33b4ff,0xff55c1ff,0xff55c1ff,
+ 0xff42b9ff,0xff31b2ff,0xff54c0ff,0xff54c0ff,0xff30b1ff,0xff53c0ff,0xff2fb0ff,0xff2eb0ff,0xff51bfff,0xff2eb0ff,0xff63c6ff,0xff2dadff,0xff50bdff,0xff4fbdff,
+ 0xff3db5ff,0xff2cadff,0xff4ebdff,0xff4ebcff,0xff2aacff,0xff4dbbff,0xff29abff,0xff4cbaff,0xff28aaff,0xff28aaff,0xff4bbaff,0xff27aaff,0xff26a9ff,0xff27a9ff,
+ 0xff26a8ff,0xff49b9ff,0xff25a7ff,0xff24a8ff,0xff24a7ff,0xff24a7ff,0xff24a5ff,0xff23a5ff,0xff23a4ff,0xff23a4ff,0xff21a5ff,0xff46b5ff,0xff21a3ff,0xff45b4ff,
+ 0xff32acff,0xff20a3ff,0xff44b4ff,0xff57bcff,0xff1fa1ff,0xff42b3ff,0xff41b3ff,0xff1da1ff,0xff1da0ff,0xff41b2ff,0xff1b9fff,0xff41b1ff,0xff1ba0ff,0xff1ca0ff,
+ 0xff1da1ff,0xff41b3ff,0xff1ea1ff,0xff1ea2ff,0xff42b3ff,0xff1fa2ff,0xff50caff,0xff50caff,0xff50caff,0xff51cbff,0xff51cbff,0xff52cbff,0xff52ccff,0xff53ccff,
+ 0xff76d6ff,0xff54ccff,0xff55cdff,0xff56cdff,0xff78d7ff,0xff56ceff,0xff57cfff,0xff7ad9ff,0xff58cfff,0xff7ad9ff,0xff7bd9ff,0xff59d0ff,0xff58d0ff,0xff7ad9ff,
+ 0xff7ad9ff,0xff7ad9ff,0xff79d8ff,0xff78d8ff,0xff77d8ff,0xff77d7ff,0xff66d2ff,0xff54ccff,0xff76d6ff,0xff53ccff,0xff76d6ff,0xff52ccff,0xff51cbff,0xff74d5ff,
+ 0xff74d6ff,0xff73d5ff,0xff84daff,0xff4fc9ff,0xff72d4ff,0xff72d4ff,0xff4dc9ff,0xff4cc8ff,0xff70d3ff,0xff4cc8ff,0xff70d2ff,0xff4bc7ff,0xff4ac6ff,0xff6fd1ff,
+ 0xff4ac6ff,0xff6ed1ff,0xff48c5ff,0xff6dd1ff,0xff47c5ff,0xff47c5ff,0xff6bd0ff,0xff6bd0ff,0xff45c4ff,0xff6ad0ff,0xff44c2ff,0xff6acfff,0xff43c2ff,0xff43c2ff,
+ 0xff69cdff,0xff68ceff,0xff54c7ff,0xff67cdff,0xff40c0ff,0xff3fc0ff,0xff66ccff,0xff66ccff,0xff3ebfff,0xff64ccff,0xff3dbeff,0xff63cbff,0xff3cbdff,0xff3bbeff,
+ 0xff63caff,0xff3abdff,0xff62caff,0xff62caff,0xff39bcff,0xff38bcff,0xff60caff,0xff73cfff,0xff5fc8ff,0xff5fc9ff,0xff36baff,0xff5ec8ff,0xff34b9ff,0xff34b9ff,
+ 0xff5cc7ff,0xff34b9ff,0xff47bfff,0xff32b8ff,0xff5bc5ff,0xff32b7ff,0xff31b7ff,0xff30b7ff,0xff30b6ff,0xff2fb6ff,0xff2fb6ff,0xff2eb5ff,0xff2eb5ff,0xff2db4ff,
+ 0xff2db4ff,0xff57c3ff,0xff2cb4ff,0xff57c3ff,0xff2ab3ff,0xff2ab2ff,0xff54c1ff,0xff54c1ff,0xff29b1ff,0xff53c1ff,0xff53c1ff,0xff52c1ff,0xff52c1ff,0xff3cb9ff,
+ 0xff26b0ff,0xff51bfff,0xff26afff,0xff26b0ff,0xff26b0ff,0xff52c1ff,0xff27b1ff,0xff28b2ff,0xff54c1ff,0xff29b2ff
+};
+
+static const QRgb packageIcon_data[] = {
+ 0xffffff,0xd06e6e6e,0xf68e8f8f,0xf2898a8b,0xf288898b,0xf288898b,0xf288898a,0xf288888a,0xf287888a,0xf288898a,0xf288898a,0xf288888a,0xf288888a,0xf287888a,
+ 0xf2878889,0xf2878889,0xf2878889,0xf2868789,0xf2868789,0xf2868788,0xf2868788,0xf2868688,0xf2858688,0xf2858688,0xf2858687,0xf2858687,0xf2848687,0xf2848587,
+ 0xf3858688,0xf2838384,0xc56b6b6b,0xffffff,0xffffff,0xd76f6f6f,0xfff7faff,0xfff0f5ff,0xffedf3ff,0xffeef4ff,0xffebf2fe,0xffeaf1fe,0xffebf2fe,0xffdce8fb,
+ 0xffdbe7fb,0xffdae6fa,0xffd9e6fa,0xffd7e4f9,0xffd6e4f9,0xffd4e2f8,0xffd2e1f7,0xffd1e1f7,0xffd0dff6,0xffcedff6,0xffccddf5,0xffcbddf5,0xffcadcf5,0xffc8dbf4,
+ 0xffc7daf3,0xffc5d9f3,0xffc4d8f2,0xffc2d6f1,0xffc4d8f3,0xffeaeff4,0xcf686867,0xffffff,0xffffff,0xd76f6f6f,0xfff2f7ff,0xffbcd1fb,0xffbcd1f8,0xffc5d8f9,
+ 0xffbed3f7,0xffc4d6f7,0xffacc6f2,0xff729ee8,0xff6f9de6,0xff6b9ae5,0xff6597e4,0xff5f93e2,0xff5a90df,0xff548add,0xff4e86da,0xff4983d9,0xff427fd7,0xff3d7cd5,
+ 0xff3778d2,0xff3274d1,0xff2d72d0,0xff286ecd,0xff2269cb,0xff1c66c8,0xff1662c6,0xff0d5cc3,0xff1663c9,0xffe7ecf2,0xcf686867,0xffffff,0xffffff,0xd76f6f6f,
+ 0xfff3f7ff,0xffabc6f9,0xffa4c1f5,0xffbad0f8,0xffbfd4f7,0xffc5d7f7,0xffa3c0f2,0xff7aa4ea,0xff73a0e7,0xff6f9de6,0xff6a9ae5,0xff6496e3,0xff5f92e0,0xff598ede,
+ 0xff538adb,0xff4e87da,0xff4883d8,0xff4380d6,0xff3d7cd3,0xff3878d2,0xff3376d1,0xff2d72ce,0xff286dcc,0xff236ac9,0xff1d67c8,0xff1561c5,0xff1d68cb,0xffe8edf2,
+ 0xce696868,0xffffff,0xffffff,0xd76f6f6e,0xfffeffff,0xffe7efff,0xffe5edfd,0xffe4edfc,0xffe2ebfb,0xffe0eafb,0xffe2ebfb,0xffe1ebfa,0xffe0eafa,0xffdfe9fa,
+ 0xffdee9f9,0xffdce7f8,0xffdae5f7,0xffd9e6fa,0xffd8e6fb,0xffd5e2f4,0xffd3e0f2,0xffd2dff1,0xffcfdef1,0xffcedcef,0xffccdbef,0xffcadaee,0xffc9d8ed,0xffc6d7ec,
+ 0xffc5d5ea,0xffc2d3e9,0xffc8d9ee,0xfff2f3f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffdf3e4,0xfffae7ce,0xffffffff,0xfffffffc,0xfffffefa,0xfffffdfa,0xfffffcf9,
+ 0xfffefcf8,0xfffefbf8,0xfffdfaf7,0xfffcf9f6,0xfffbf9f5,0xfffbf9f5,0xfffffcf8,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffcf8f2,0xfff0d3a9,0xffebc37e,0xffe8c179,0xffe9cfab,
+ 0xfffbfeff,0xfff9fafa,0xfff7f7f7,0xfff7f7f7,0xfff6f6f6,0xfff6f6f6,0xfff5f5f5,0xfff3f3f3,0xfff3f3f3,0xfff2f2f2,0xfff3f3f3,0xfff5f5f5,0xce686868,0xffffff,
+ 0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffdfcfa,0xfff4dcbb,0xffecc480,
+ 0xfff4dea1,0xfffbf4cb,0xfffdf9d6,0xffe9cb8d,0xffe3c69e,0xfff9fbfc,0xfff8f9fa,0xfff6f6f6,0xfff6f6f6,0xfff5f5f5,0xfff4f4f4,0xfff4f4f4,0xfff3f3f3,0xfff1f1f1,
+ 0xfff1f1f1,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffefcf9,
+ 0xfff4dbb8,0xffecc482,0xfff2d797,0xfffdf9d2,0xffffffe8,0xfff8edc2,0xfffcf6cf,0xffffffe3,0xffe8ce95,0xffdbbb91,0xfff6f7f7,0xfff8fafc,0xfff5f5f5,0xfff5f5f5,
+ 0xfff4f4f4,0xfff3f3f3,0xfff2f2f2,0xffeeeeee,0xfff1f1f1,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xfffffefe,0xfff6e4c8,0xffedc784,0xfff4d794,0xfffef6c7,0xffffffdb,0xfffffdd5,0xfffffed8,0xfff3e0ab,0xfffbf1c4,0xfffffdd5,0xffffffd8,0xffe9d196,
+ 0xffd3b184,0xfff0ece9,0xfff8fbfd,0xfff4f4f4,0xfff3f3f3,0xfff3f3f3,0xfff1f1f1,0xffececec,0xfff2f2f2,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfffcf5eb,0xffedc687,0xffefc678,0xfff9e3a5,0xfffdecb6,0xfffbe6ab,0xfff9e1a3,0xfff9e0a3,0xfff8de9e,0xffecc984,
+ 0xfff8e1a5,0xfffff1bc,0xfffff5c2,0xfffffcca,0xffedd295,0xffc99f68,0xffe6dcd2,0xfff8fbff,0xfff3f3f3,0xfff2f2f2,0xffeeeeee,0xffececec,0xfff3f3f3,0xfff5f5f5,
+ 0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfff4ddba,0xfff2d087,0xfffff0b9,0xffffe4a4,0xfffee5a7,0xfffde5a6,
+ 0xfffde4a5,0xfffde4a4,0xfffee6a8,0xfff6d288,0xffe1a444,0xffdca855,0xffdeb46e,0xffe6c586,0xfff6dca2,0xfff0d594,0xffc7a066,0xffded2c6,0xfff5f7f9,0xfff0f0f0,
+ 0xffededed,0xffededed,0xfff3f3f3,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfff4debc,0xfff5d891,
+ 0xfffff7c3,0xffffe6a6,0xffffdd94,0xffffde97,0xffffde98,0xffffde98,0xffffe29c,0xfff2c573,0xffefc16e,0xffebbf70,0xffe1b368,0xffdaad66,0xffd6ac68,0xffdcb877,
+ 0xffe3c07d,0xffbe935a,0xffe6e1dc,0xfff0f1f3,0xffeeeeee,0xffeeeeee,0xfff4f4f4,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xfff4debd,0xfff4d389,0xfffff1b4,0xffffeeb1,0xffffe199,0xffffd481,0xffffd583,0xffffd585,0xfffed483,0xffefbe67,0xfffdd686,0xffffdb8b,
+ 0xffffda89,0xffffda89,0xffffda8a,0xffffd785,0xffffd87e,0xffd0a258,0xffdcd3cd,0xfff1f3f4,0xffefefef,0xffefefef,0xfff5f5f5,0xfff5f5f5,0xce686868,0xffffff,
+ 0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfff3ddbd,0xfff3d084,0xffffecaa,0xffffe8a3,0xffffe9a6,0xffffdf95,0xffffcd72,0xffffcd6f,
+ 0xfffbc86d,0xfff0bb61,0xffffce72,0xffffcc71,0xffffcf75,0xffffd076,0xffffce70,0xffffcd6e,0xffffd778,0xffcfa25c,0xffddd4cf,0xfff2f4f5,0xfff0f0f0,0xfff0f0f0,
+ 0xfff6f6f6,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xfff2dcbe,0xfff1cd7e,0xffffe9a1,0xffffe49a,
+ 0xffffe397,0xffffe49a,0xffffdc8e,0xffffc764,0xfff8ba54,0xfff6ba57,0xffffc763,0xffffc968,0xffffc866,0xffffc663,0xffffca69,0xffffcf73,0xffffdb7f,0xffcda25e,
+ 0xffdcd4cf,0xfff4f5f6,0xfff1f1f1,0xfff1f1f1,0xfff7f7f7,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xfff0dbbd,0xfff0ca78,0xffffe596,0xffffe090,0xffffe08e,0xffffde8b,0xffffe08e,0xffffda83,0xfff7be5b,0xfffcbf58,0xffffc35b,0xffffc158,0xffffc35d,0xffffca67,
+ 0xffffcf71,0xffffd279,0xffffde84,0xffcba261,0xffdcd4cf,0xfff5f6f7,0xfff2f2f2,0xfff2f2f2,0xfff8f8f8,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,
+ 0xffffffff,0xfff7f7f7,0xfffbfbfb,0xffffffff,0xffeedabe,0xffeec773,0xffffe18e,0xffffdd88,0xffffdc84,0xffffdb83,0xffffda80,0xffffdb82,0xfffed883,0xffffbb4e,
+ 0xffffbd4f,0xffffc25a,0xffffc864,0xffffcd6d,0xffffd176,0xffffd57e,0xffffe18a,0xffc9a264,0xffdcd4cf,0xfff5f6f7,0xfff2f2f2,0xfff2f2f2,0xfff8f8f8,0xfff5f5f5,
+ 0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xfff4f4f4,0xfff3f3f3,0xfff6f9fe,0xffe8d3b9,0xffeec570,0xffffde84,0xffffd97f,0xffffd97c,0xffffd87a,
+ 0xffffd677,0xffffd777,0xffffd172,0xffffbb4e,0xffffc056,0xffffc660,0xffffcb6a,0xffffd072,0xffffd47b,0xffffd883,0xffffe58f,0xffc7a265,0xffdcd4d0,0xfff7f8fa,
+ 0xfff4f4f4,0xfff4f4f4,0xfffafafa,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xfff6f6f6,0xfff4f4f4,0xfff6f9fd,0xffe5d3bb,0xffe5b75f,
+ 0xffffdc7b,0xffffd675,0xffffd572,0xffffd470,0xffffd36e,0xffffd36d,0xffffd06f,0xffffbe54,0xffffc35c,0xffffc966,0xffffce6f,0xffffd277,0xffffd780,0xffffdc88,
+ 0xffffe795,0xffc5a166,0xffdcd4d0,0xfff8f9fb,0xfff5f5f5,0xfff5f5f5,0xfffbfbfb,0xfff5f5f5,0xce686868,0xffffff,0xffffff,0xd76e6e6e,0xffffffff,0xfff6f6f6,
+ 0xfff5f5f5,0xfff5f6f7,0xfff4f3f2,0xffd9b88a,0xffe6b75c,0xffffd66e,0xffffd169,0xffffd067,0xffffcf64,0xffffcf63,0xffffcf6c,0xffffc25a,0xffffc661,0xffffcc6b,
+ 0xffffd174,0xffffd57d,0xffffda86,0xffffe08f,0xfffff09b,0xffbf9b60,0xffdad1cf,0xfff9fbfc,0xfff6f6f6,0xfff6f6f6,0xfffcfcfc,0xfff6f6f6,0xce686868,0xffffff,
+ 0xffffff,0xd76d6d6d,0xffffffff,0xfff7f7f7,0xfff6f6f6,0xfff6f6f6,0xfff7f8f9,0xfff7f8fb,0xffd5b894,0xffdfae55,0xffffd162,0xffffcd5e,0xffffcb5c,0xffffcb5a,
+ 0xffffce69,0xffffc560,0xffffc966,0xffffce70,0xffffd379,0xffffd983,0xffffe490,0xfffadc8b,0xffcdaa6a,0xffac8d6f,0xffebe8e7,0xfff8f9f9,0xfff6f6f6,0xfff6f6f6,
+ 0xfffcfcfc,0xfff6f6f6,0xcf676767,0xffffff,0xffffff,0xd76d6d6d,0xffffffff,0xfff8f8f8,0xfff7f7f7,0xfff7f7f7,0xfff7f7f7,0xfff8f9fa,0xfff9fbfe,0xffd5bda1,
+ 0xffd7a752,0xfffecc59,0xffffc952,0xffffc64f,0xffffce66,0xffffc967,0xffffcc6c,0xffffd276,0xffffde83,0xfff8d680,0xffc9a564,0xff7f766c,0xff827d7b,0xff8d8d8e,
+ 0xff8f8f8f,0xff8d8d8d,0xff8d8d8d,0xff8d8d8d,0xff909090,0xff878787,0xce666666,0xffffff,0xffffff,0xd76d6d6d,0xffffffff,0xfff9f9f9,0xfff8f8f8,0xfff8f8f8,
+ 0xfff8f8f8,0xfff8f8f8,0xfff8f9f9,0xfffafeff,0xffd5c1ac,0xffc39752,0xfff6c04d,0xffffc544,0xffffcc63,0xffffcc6d,0xffffd575,0xfffcd478,0xffd5ac62,0xffb3916b,
+ 0xffcbbcb4,0xff8c8c8d,0xfff4f6f8,0xfffafafa,0xfff7f7f7,0xfff7f7f7,0xfff7f7f7,0xffffffff,0xffe3e3e3,0xe5676767,0x1d000000,0xffffff,0xffffff,0xd76d6d6d,
+ 0xffffffff,0xfff9f9f9,0xfff8f8f8,0xfff8f8f8,0xfff8f8f8,0xfff8f8f8,0xfff8f8f8,0xfff9f9fa,0xfffcffff,0xffe3d8d2,0xffbf9861,0xfff0b841,0xffffd362,0xffffd172,
+ 0xffdfb15e,0xffb79161,0xffc6b4a7,0xfff2f1f2,0xfffeffff,0xff8e8f8f,0xfff2f2f2,0xfffbfbfb,0xfffcfcfc,0xfffdfdfd,0xffffffff,0xffebebeb,0xe5686868,0x1e000000,
+ 0x0,0xffffff,0xffffff,0xd76d6d6d,0xffffffff,0xfffafafa,0xfff9f9f9,0xfff9f9f9,0xfff9f9f9,0xfff9f9f9,0xfff9f9f9,0xfff9f9f9,0xfff9f9fa,0xfffeffff,
+ 0xffe9e3e1,0xffbc9868,0xffd7a750,0xffc0965f,0xffc2ab99,0xffece9e9,0xffffffff,0xfffbfcfd,0xfff9f9f9,0xff8d8d8d,0xffededed,0xfff4f4f4,0xfff4f4f4,0xffffffff,
+ 0xffe7e7e7,0xe5686868,0x1f000000,0x0,0x0,0xffffff,0xffffff,0xd76d6d6d,0xffffffff,0xfffbfbfb,0xfffafafa,0xfffafafa,0xfffafafa,0xfffafafa,
+ 0xfffafafa,0xfffafafa,0xfffafafa,0xfffafafa,0xffffffff,0xffede8e6,0xffc5b0a0,0xffe7e1df,0xffffffff,0xfffcfdfe,0xfffafafa,0xfffbfbfb,0xfffafafa,0xff8d8d8d,
+ 0xffe9e9e9,0xffefefef,0xfff9f9f9,0xffe1e1e1,0xe5686868,0x1f000000,0x0,0x0,0x0,0xffffff,0xffffff,0xd76d6d6d,0xffffffff,0xfffbfbfb,
+ 0xfffafafa,0xfffafafa,0xfffafafa,0xfffafafa,0xfffafafa,0xfffafafa,0xfffafafa,0xfffafafa,0xfffafafa,0xfffcfdfd,0xffffffff,0xfffdfefe,0xfffafafa,0xfffafafa,
+ 0xfffafafa,0xfffbfbfb,0xfffafafa,0xff8d8d8d,0xffe5e5e5,0xfff2f2f2,0xffdbdbdb,0xe4686868,0x1e000000,0x0,0x0,0x0,0x0,0xffffff,
+ 0xffffff,0xd76d6d6d,0xffffffff,0xfffcfcfc,0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,
+ 0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,0xfffbfbfb,0xfffcfcfc,0xfffbfbfb,0xff8d8d8d,0xffeaeaea,0xffd7d7d7,0xe5676767,0x1e000000,0x0,0x0,
+ 0x0,0x0,0x0,0xffffff,0xffffff,0xd76d6d6d,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
+ 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xff919191,0xffd1d1d1,0xe5676767,
+ 0x1f000000,0x0,0x0,0x0,0x0,0x0,0x0,0xffffff,0xffffff,0xd56b6b6b,0xff8d8d8d,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,
+ 0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,0xfc8a8a8a,
+ 0xfc8a8a8a,0xfd818181,0xe5676767,0x1f000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffffff,0xffffff,0x15000000,
+ 0x42030303,0x45000000,0x44000000,0x44000000,0x44000000,0x44000000,0x44000000,0x44000000,0x44000000,0x44000000,0x44000000,0x44000000,0x44000000,0x44000000,
+ 0x44000000,0x44000000,0x44000000,0x44000000,0x44000000,0x44030303,0x1d000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ 0x0,0xffffff
+};
+#include <qcstring.h>
+
+
+const QImage& qembed_findImage( const QString& name );
+#endif
diff --git a/src/arkollon/headerlistitem.cpp b/src/arkollon/headerlistitem.cpp
new file mode 100644
index 0000000..2d850ac
--- /dev/null
+++ b/src/arkollon/headerlistitem.cpp
@@ -0,0 +1,126 @@
+/***************************************************************************
+ * Copyright (C) 2004 by David Sansome *
+ * me@davidsansome.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "headerlistitem.h"
+
+#include <qfontmetrics.h>
+#include <qpainter.h>
+#include <qapplication.h>
+
+#include "uninstallwizard.h"
+#include "wizard.h"
+
+HeaderListItem::HeaderListItem(QListView* parent)
+ : QListViewItem(parent)
+{
+}
+
+int HeaderListItem::compare(QListViewItem* i, int , bool ) const
+{
+ switch (i->rtti())
+ {
+ case 1001: // Component
+ {
+ ComponentListItem* item = (ComponentListItem*) i;
+ if (section > item->section)
+ return 1;
+ return -1;
+ }
+
+ case 1003: // App
+ {
+ AppListItem* item = (AppListItem*) i;
+ if (section > item->section)
+ return 1;
+ return -1;
+ }
+
+ case 1002: // Header
+ {
+ HeaderListItem* item = (HeaderListItem*) i;
+ if (section > item->section)
+ return 1;
+ if (section < item->section)
+ return -1;
+ return 0;
+ }
+ }
+ return 0;
+}
+
+void HeaderListItem::paintCell(QPainter* p, const QColorGroup& cg, int , int width, int )
+{
+ p->fillRect(0, 0, width, height(), cg.base());
+
+ QFont boldFont = p->font();
+ boldFont.setBold(true);
+ p->setFont(boldFont);
+ p->drawText(listView()->itemMargin(), listView()->itemMargin(), width, QFontMetrics(boldFont).height(), Qt::AlignLeft, text(0));
+
+ int textWidth = QFontMetrics(boldFont).width(text(0));
+ p->fillRect(0, height() - 4 - listView()->itemMargin(), textWidth-10, 4, cg.highlight());
+
+ QColor ca = cg.highlight();
+ QColor cb = cg.base();
+ // Taken from KPixmapEffect::gradient
+ int rDiff, gDiff, bDiff;
+ int rca, gca, bca /*, rcb, gcb, bcb*/;
+
+// register int x, y;
+
+ rDiff = (/*rcb = */ cb.red()) - (rca = ca.red());
+ gDiff = (/*gcb = */ cb.green()) - (gca = ca.green());
+ bDiff = (/*bcb = */ cb.blue()) - (bca = ca.blue());
+
+ register int rl = rca << 16;
+ register int gl = gca << 16;
+ register int bl = bca << 16;
+
+ int rcdelta = ((1<<16) / 20) * rDiff;
+ int gcdelta = ((1<<16) / 20) * gDiff;
+ int bcdelta = ((1<<16) / 20) * bDiff;
+ for( int x = textWidth-10; x < textWidth+10; x++)
+ {
+ rl += rcdelta;
+ gl += gcdelta;
+ bl += bcdelta;
+
+ p->setPen(QColor(rl>>16, gl>>16, bl>>16));
+ p->drawLine(x, height() - 4 - listView()->itemMargin(), x, height() - listView()->itemMargin() - 1);
+ }
+}
+
+void HeaderListItem::paintFocus(QPainter* , const QColorGroup& , const QRect& )
+{
+}
+
+int HeaderListItem::width(const QFontMetrics& , const QListView* lv, int ) const
+{
+ QFont boldFont = qApp->font();
+ boldFont.setBold(true);
+ QFontMetrics metrics(boldFont);
+ return metrics.width(text(0)) + lv->itemMargin() + 10;
+}
+
+void HeaderListItem::setup()
+{
+ setHeight(qApp->fontMetrics().height() + listView()->itemMargin()*3 + 4);
+}
+
+
diff --git a/src/arkollon/headerlistitem.h b/src/arkollon/headerlistitem.h
new file mode 100644
index 0000000..5872220
--- /dev/null
+++ b/src/arkollon/headerlistitem.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2004 by David Sansome *
+ * me@davidsansome.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef HEADERLISTITEM_H
+#define HEADERLISTITEM_H
+
+#include <qlistview.h>
+
+class HeaderListItem : public QListViewItem
+{
+public:
+ HeaderListItem(QListView* parent);
+ int compare(QListViewItem* i, int col, bool ascending) const;
+ void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
+ void paintFocus(QPainter* p, const QColorGroup& cg, const QRect& r);
+ void setup();
+ int width(const QFontMetrics& fm, const QListView* lv, int c) const;
+ int rtti() const { return 1002; }
+
+ int section;
+};
+
+#endif
diff --git a/src/arkollon/logdialog.ui b/src/arkollon/logdialog.ui
new file mode 100644
index 0000000..9e2b24e
--- /dev/null
+++ b/src/arkollon/logdialog.ui
@@ -0,0 +1,91 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>LogDialog</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>LogDialog</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>572</width>
+ <height>350</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Installation log</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTextEdit">
+ <property name="name">
+ <cstring>logBox</cstring>
+ </property>
+ <property name="textFormat">
+ <enum>PlainText</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Horizontal Spacing2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>210</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonOk</cstring>
+ </property>
+ <property name="text">
+ <string>Close</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>LogDialog</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/arkollon/rcparser.cpp b/src/arkollon/rcparser.cpp
new file mode 100644
index 0000000..dc9442f
--- /dev/null
+++ b/src/arkollon/rcparser.cpp
@@ -0,0 +1,146 @@
+/***************************************************************************
+ * Copyright (C) 2004 by David Sansome *
+ * me@davidsansome.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "rcparser.h"
+
+#include <qregexp.h>
+#include <qfile.h>
+#include <qtextstream.h>
+
+RcParser::RcParser()
+{
+}
+
+
+RcParser::~RcParser()
+{
+}
+
+void RcParser::addSearchDir(QString dir)
+{
+ dirs.append(dir);
+}
+
+bool RcParser::openFile(QString name)
+{
+ // Check if it exists
+ fileName = "";
+ for ( QStringList::Iterator it = dirs.begin(); it != dirs.end(); ++it )
+ {
+ if (QFile::exists((*it) + "/" + name))
+ {
+ fileName = (*it) + "/" + name;
+ break;
+ }
+ }
+
+ if (fileName.isEmpty())
+ return false;
+
+ // Clear the current data
+ sections.clear();
+
+ // Read the file's contents
+ QFile file(fileName);
+ file.open(IO_ReadOnly);
+ QTextStream stream(&file);
+
+ QRegExp sectionRegExp("^\\[([^\\]]*)\\]$");
+ QRegExp pairRegExp("^([^=\\s]*)([=\\s]*)(.*)$");
+ currentSection = "RcParserDefaultSection";
+
+ while (!stream.atEnd())
+ {
+ QString line = stream.readLine();
+ if (line.left(1) == "#") // Comment
+ continue;
+
+ line = line.stripWhiteSpace();
+
+ if (sectionRegExp.search(line) != -1)
+ {
+ currentSection = sectionRegExp.cap(1);
+ //printf("Found section \"%s\"\n", currentSection.latin1());
+ continue;
+ }
+ if (pairRegExp.search(line) != -1)
+ {
+ QString key = pairRegExp.cap(1);
+ QString value = pairRegExp.cap(3);
+ sections[currentSection][key] = value;
+ //printf("Found pair \"%s\" = \"%s\"\n", key.latin1(), value.latin1());
+ continue;
+ }
+
+ // Parse error, ignore the line
+ }
+
+ currentSection = "RcParserDefaultSection";
+ return true;
+}
+
+void RcParser::setSection(QString section)
+{
+ currentSection = section;
+}
+
+QStringList RcParser::sectionList()
+{
+ return sections.keys();
+}
+
+QString RcParser::readString(QString key, QString def)
+{
+ QString ret = sections[currentSection][key];
+ if (ret.isEmpty())
+ return def;
+ return ret;
+}
+
+int RcParser::readInt(QString key, int def)
+{
+ bool ok;
+ int ret = sections[currentSection][key].toInt(&ok);
+ if (!ok)
+ return def;
+ return ret;
+}
+
+bool RcParser::readBool(QString key, bool def)
+{
+ bool ret = def;
+ if (sections[currentSection][key].lower() == "true")
+ ret = true;
+ if (sections[currentSection][key].lower() == "false")
+ ret = false;
+ if (sections[currentSection][key] == "1")
+ ret = true;
+ if (sections[currentSection][key] == "0")
+ ret = false;
+ return ret;
+}
+
+QStringList RcParser::readList(QString key)
+{
+ return QStringList::split(",", sections[currentSection][key]);
+}
+
+
+
+
diff --git a/src/arkollon/rcparser.h b/src/arkollon/rcparser.h
new file mode 100644
index 0000000..8739b0e
--- /dev/null
+++ b/src/arkollon/rcparser.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ * Copyright (C) 2004 by David Sansome *
+ * me@davidsansome.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef RCPARSER_H
+#define RCPARSER_H
+
+#include <qstringlist.h>
+#include <qmap.h>
+
+class RcParser
+{
+public:
+ RcParser();
+ ~RcParser();
+
+ void addSearchDir(QString dir);
+ bool openFile(QString name);
+
+ QStringList sectionList();
+ void setSection(QString section);
+
+ QString readString(QString key, QString def=QString::null);
+ int readInt(QString key, int def=0);
+ bool readBool(QString key, bool def=false);
+ QStringList readList(QString key);
+
+private:
+ QStringList dirs;
+ QString fileName;
+ QString currentSection;
+ QMap< QString, QMap< QString, QString> > sections;
+};
+
+#endif
diff --git a/src/arkollon/torkarkollon.1 b/src/arkollon/torkarkollon.1
new file mode 100644
index 0000000..b5e998c
--- /dev/null
+++ b/src/arkollon/torkarkollon.1
@@ -0,0 +1,18 @@
+.TH "TORKARKOLLON" "1"
+.SH "NAME"
+torkarkollon \- an installation helper for TorK.
+.SH "SYNOPSIS"
+\fBtorkarkollon\fR
+.SH "DESCRIPTION"
+This manual page documents briefly the
+\fBtorkarkollon\fR commandline
+parameters.
+\fBtorkarkollon\fR is a compilation and installation helper for TorK.
+It is a modified copy of Arkollon, distributed by the Apollon project.
+.TP
+.SH "AUTHOR"
+This manual page was written by Patrick Matth\[:a]i <patrick.matthaei@web.de>
+for webissues.
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU General Public License, Version 2 any
+later version published by the Free Software Foundation.
diff --git a/src/arkollon/torkarkollon.cpp b/src/arkollon/torkarkollon.cpp
new file mode 100644
index 0000000..8d24bd5
--- /dev/null
+++ b/src/arkollon/torkarkollon.cpp
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2004 by David Sansome *
+ * me@davidsansome.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <qapplication.h>
+#include "wizard.h"
+#include "uninstallwizard.h"
+
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ // Check if we're root
+ if (getuid() != 0)
+ {
+ QString command = "kdesu -t -i tork -n -c \"";
+ for (int i=0 ; i<app.argc() ; i++)
+ {
+ if (QString(app.argv()[i]).contains(" "))
+ command += "\\\"" + QString(app.argv()[i]) + "\\\" ";
+ else
+ command += QString(app.argv()[i]) + " ";
+ }
+ command += "\"";
+ return system(command.latin1());
+ }
+
+ WizardBase* wizard = NULL;
+
+ for ( int i = 1; i < app.argc(); i++ )
+ {
+ if (QString(app.argv()[i]) == "--help")
+ {
+ printf("Arkollon is a utility to aid installation and removal of packages from source.\n");
+ printf("Usage: arkollon DIRECTORY Installs a source package from DIRECTORY\n");
+ printf(" arkollon --uninstall Starts the uninstaller\n");
+ return 0;
+ }
+ if (QString(app.argv()[i]) == "--uninstall")
+ wizard = new UninstallWizard(NULL);
+ }
+
+ if (!wizard)
+ wizard = new Wizard(NULL);
+ app.setMainWidget(wizard);
+
+ return app.exec();
+}
diff --git a/src/arkollon/uninstallwizard.cpp b/src/arkollon/uninstallwizard.cpp
new file mode 100644
index 0000000..ac8f2f8
--- /dev/null
+++ b/src/arkollon/uninstallwizard.cpp
@@ -0,0 +1,322 @@
+/***************************************************************************
+ * Copyright (C) 2004 by David Sansome *
+ * me@davidsansome.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#include "uninstallwizard.h"
+#include "headerlistitem.h"
+#include "data.h"
+
+#include <qregexp.h>
+#include <qwidgetstack.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qheader.h>
+#include <qlistbox.h>
+#include <qmessagebox.h>
+#include <qpushbutton.h>
+#include <qlineedit.h>
+#include <qtextedit.h>
+#include <qlabel.h>
+
+AppListItem::AppListItem(QString nN, QString n, QListView* parent)
+ : QCheckListItem(parent, "", QCheckListItem::CheckBox)
+{
+ niceName = nN;
+ name = n;
+ section = 2;
+
+ setText(0, niceName);
+}
+
+int AppListItem::compare(QListViewItem* i, int col, bool ascending) const
+{
+ switch (i->rtti())
+ {
+ case 1003: // App
+ {
+ AppListItem* item = (AppListItem*) i;
+ if (section < item->section)
+ return -1;
+ if (section > item->section)
+ return 1;
+ return QListViewItem::compare(i, col, ascending);
+ }
+ break;
+
+ case 1002: // Header
+ {
+ HeaderListItem* item = (HeaderListItem*) i;
+ if (section < item->section)
+ return -1;
+ return 1;
+ }
+ break;
+ }
+ return 0;
+}
+
+
+UninstallWizard::UninstallWizard(QWidget* parent, const char* name, bool modal, WFlags fl)
+: WizardBase(parent,name, modal,fl)
+{
+ mainStack->raiseWidget(1);
+ setCaption("Uninstall Software");
+ titleLabel->setText("<b>Uninstall Software</b>");
+ componentInfo->setMaximumSize(32767,70);
+
+ logDialog = new LogDialog(this);
+ logDialog->hide();
+ appList->header()->hide();
+
+ globalHeader = NULL;
+
+ icon.convertFromImage(qembed_findImage("misc"));
+
+ externalProcess = new QProcess(this);
+ connect(externalProcess, SIGNAL(processExited()), SLOT(processExited()));
+ connect(externalProcess, SIGNAL(readyReadStdout()), SLOT(readyReadStdout()));
+ connect(externalProcess, SIGNAL(readyReadStderr()), SLOT(readyReadStderr()));
+
+ QFile uninstallScript("/tmp/arkollon-uninstall.sh");
+ if (uninstallScript.exists())
+ uninstallScript.remove();
+ uninstallScript.open(IO_WriteOnly);
+ QDataStream stream(&uninstallScript);
+ stream.writeRawBytes((const char*)uninstaller_sh_data, uninstaller_sh_len);
+ uninstallScript.close();
+
+ currentStage = ListingPackages;
+ externalProcess->addArgument("/bin/sh");
+ externalProcess->addArgument("/tmp/arkollon-uninstall.sh");
+ externalProcess->addArgument("--list");
+ externalProcess->start();
+}
+
+UninstallWizard::~UninstallWizard()
+{
+ QFile uninstallScript("/tmp/arkollon-uninstall.sh");
+ if (uninstallScript.exists())
+ uninstallScript.remove();
+}
+
+void UninstallWizard::logPressed()
+{
+ logDialog->show();
+}
+
+void UninstallWizard::cancelPressed()
+{
+ reject();
+}
+
+void UninstallWizard::previousPressed()
+{
+ int currentId = uninstallStack->id(uninstallStack->visibleWidget());
+ if (currentId == 0)
+ return;
+
+ uninstallStack->raiseWidget(--currentId);
+
+ if (currentId == 0)
+ previousButton->setEnabled(false);
+ nextButton->setEnabled(true);
+}
+
+void UninstallWizard::nextPressed()
+{
+ int currentId = uninstallStack->id(uninstallStack->visibleWidget());
+ if (currentId == 2)
+ {
+ accept();
+ return;
+ }
+
+ if (currentId == 0)
+ {
+ bool checked = false;
+ QStringList argList;
+ argList.append("/bin/sh");
+ argList.append("/tmp/arkollon-uninstall.sh");
+ for ( QListViewItem * myChild = appList->firstChild() ; myChild != NULL ; myChild = myChild->nextSibling())
+ {
+ if (myChild->rtti() != 1003)
+ continue;
+ AppListItem* app = (AppListItem*) myChild;
+ if (!app->isOn())
+ continue;
+ argList.append("--files");
+ argList.append(app->name);
+ checked = true;
+ }
+ if (!checked)
+ {
+ QMessageBox::warning(this, "Error", "You need to select at least one package to remove", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+ return;
+ }
+ fileList->clear();
+ currentStage = ListingFiles;
+ externalProcess->setArguments(argList);
+ externalProcess->start();
+ nextButton->setEnabled(false); // Set true again when the process is done
+ }
+
+ uninstallStack->raiseWidget(++currentId);
+
+ if (currentId == 2)
+ removeUserPackages();
+ else
+ previousButton->setEnabled(true);
+}
+
+void UninstallWizard::processExited()
+{
+ switch (currentStage)
+ {
+ case ListingPackages:
+ if (appList->childCount() <= 0)
+ {
+ QMessageBox::warning(NULL, "Warning", "There are no packages installed", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+ reject();
+ return;
+ }
+ show();
+ break;
+ case ListingFiles:
+ nextButton->setEnabled(true);
+ fileList->sort();
+ break;
+ case RemovingGlobal:
+ finished();
+ break;
+ }
+}
+
+void UninstallWizard::readyReadStdout()
+{
+ switch (currentStage)
+ {
+ case ListingPackages:
+ {
+ while (externalProcess->canReadLineStdout())
+ {
+ QString line = externalProcess->readLineStdout();
+ if (line.isEmpty())
+ continue;
+
+ // See if it already exists
+ bool exists = false;
+
+ for ( QListViewItem * myChild = appList->firstChild() ; myChild != NULL ; myChild = myChild->nextSibling())
+ {
+ if (myChild->rtti() != 1003)
+ continue;
+ AppListItem* app = (AppListItem*) myChild;
+ if (app->name.lower() == line.lower())
+ {
+ exists = true;
+ break;
+ }
+ }
+ if (exists)
+ continue;
+
+ QString niceName = line.left(line.findRev(':'));
+ niceName = niceName.left(1).upper() + niceName.right(niceName.length()-1);
+ new AppListItem(niceName, line, appList);
+
+ if (globalHeader == NULL)
+ {
+ globalHeader = new HeaderListItem(appList);
+ globalHeader->setText(0, "Applications available to all users");
+ globalHeader->section = 1;
+ }
+ }
+ break;
+ }
+ case ListingFiles:
+ {
+ while (externalProcess->canReadLineStdout())
+ {
+ QString line = externalProcess->readLineStdout();
+ if (line.isEmpty())
+ continue;
+ fileList->insertItem(icon, line.left(line.find(" ")));
+ }
+ break;
+ }
+ case RemovingGlobal:
+ while (externalProcess->canReadLineStdout())
+ {
+ QString line = externalProcess->readLineStdout();
+ if (line.isEmpty())
+ continue;
+ line.replace(QRegExp("\\033[^m]*m"), "");
+ logDialog->logBox->append(line);
+ }
+ break;
+ }
+}
+
+void UninstallWizard::readyReadStderr()
+{
+ while (externalProcess->canReadLineStdout())
+ {
+ QString line = externalProcess->readLineStdout();
+ if (line.isEmpty())
+ continue;
+ line.replace(QRegExp("\\033[^m]*m"), "");
+ logDialog->logBox->append(line);
+ }
+}
+
+void UninstallWizard::removeUserPackages()
+{
+ nextButton->setEnabled(false); // Set true again when the process is done
+ previousButton->setEnabled(false);
+
+ // Find out which packages belong to the user, and uninstall them
+ QStringList argList;
+ argList.append("/bin/sh");
+ argList.append("/tmp/arkollon-uninstall.sh");
+ for ( QListViewItem * myChild = appList->firstChild() ; myChild != NULL ; myChild = myChild->nextSibling())
+ {
+ if (myChild->rtti() != 1003)
+ continue;
+ AppListItem* app = (AppListItem*) myChild;
+ if (!app->isOn())
+ continue;
+
+ argList.append("--remove");
+ argList.append(app->name);
+ }
+ currentStage = RemovingGlobal;
+ externalProcess->setArguments(argList);
+ externalProcess->start();
+}
+
+void UninstallWizard::finished()
+{
+ pleaseWaitLabel2->setText("Removal of packages complete!");
+ nextButton->setText("Finish");
+ nextButton->setEnabled(true);
+}
+
+#include "uninstallwizard.moc"
+
diff --git a/src/arkollon/uninstallwizard.h b/src/arkollon/uninstallwizard.h
new file mode 100644
index 0000000..711e04f
--- /dev/null
+++ b/src/arkollon/uninstallwizard.h
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * Copyright (C) 2004 by David Sansome *
+ * me@davidsansome.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef UNINSTALLWIZARD_H
+#define UNINSTALLWIZARD_H
+
+#include "wizardbase.h"
+#include "logdialog.h"
+#include "headerlistitem.h"
+
+#include <qlistview.h>
+#include <qprocess.h>
+#include <qpixmap.h>
+
+class AppListItem : public QCheckListItem
+{
+public:
+
+ AppListItem(QString nN, QString n, QListView* lv);
+ int compare(QListViewItem* i, int col, bool ascending) const;
+ int rtti() const { return 1003; }
+
+ QString niceName;
+ QString name;
+ int section;
+};
+
+
+
+class UninstallWizard : public WizardBase
+{
+ Q_OBJECT
+
+public:
+ UninstallWizard(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
+ ~UninstallWizard();
+
+public slots:
+ virtual void logPressed();
+ virtual void cancelPressed();
+ virtual void previousPressed();
+ virtual void nextPressed();
+
+ void processExited();
+ void readyReadStdout();
+ void readyReadStderr();
+
+private:
+ void checkPassword();
+ void removeUserPackages();
+ void removeGlobalPackages();
+ void finished();
+
+private:
+ enum
+ {
+ ListingPackages,
+ ListingFiles,
+ RemovingGlobal
+ } currentStage;
+
+ LogDialog* logDialog;
+ QProcess* externalProcess;
+ HeaderListItem* globalHeader;
+
+ QPixmap icon;
+};
+
+#endif
+
diff --git a/src/arkollon/wizard.cpp b/src/arkollon/wizard.cpp
new file mode 100644
index 0000000..8e92ebf
--- /dev/null
+++ b/src/arkollon/wizard.cpp
@@ -0,0 +1,950 @@
+/***************************************************************************
+ * Copyright (C) 2004 by David Sansome *
+ * me@davidsansome.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "wizard.h"
+
+#include <qfiledialog.h>
+#include <qwidgetstack.h>
+#include <qpushbutton.h>
+#include <qpainter.h>
+#include <qheader.h>
+#include <qapplication.h>
+#include <qmessagebox.h>
+#include <qprogressbar.h>
+#include <qradiobutton.h>
+#include <qtextedit.h>
+#include <qlineedit.h>
+#include <qpopupmenu.h>
+#include <qhbox.h>
+#include <qfileinfo.h>
+#include <qlabel.h>
+#include <qfontmetrics.h>
+#include <qcheckbox.h>
+
+#include "data.h"
+
+#include "rcparser.h"
+#include "headerlistitem.h"
+
+typedef QValueVector<CompileError> CompileErrorVector;
+CompileErrorVector errs( 5 ); // vector of 3 Employees
+
+
+ComponentListItem::ComponentListItem(struct Component c, QListView* parent)
+ : QCheckListItem(parent, "", QCheckListItem::CheckBox)
+{
+ component = c;
+ setText(0, c.niceName);
+ setOn(true);
+
+ if (c.gnomeOnly)
+ section=2;
+ else if (c.kdeOnly)
+ section=3;
+ else if (c.optional)
+ section=1;
+ else
+ section=0;
+
+
+}
+
+int ComponentListItem::compare(QListViewItem* i, int col, bool ascending) const
+{
+ switch (i->rtti())
+ {
+ case 1001: // Component
+ {
+ ComponentListItem* item = (ComponentListItem*) i;
+ if (section < item->section)
+ return -1;
+ if (section > item->section)
+ return 1;
+ return QListViewItem::compare(i, col, ascending);
+ }
+ break;
+
+ case 1002: // Header
+ {
+ HeaderListItem* item = (HeaderListItem*) i;
+ if (section < item->section)
+ return -1;
+ return 1;
+ }
+ break;
+ }
+ return 0;
+}
+
+
+
+Wizard::Wizard(QWidget *parent, const char *name)
+ : WizardBase(parent, name, false, WDestructiveClose)
+{
+ componentInfo->setMaximumSize(32767,70);
+ componentList->header()->hide();
+ //progressLabel2->setMaximumSize(32767, progressLabel2->fontMetrics().height()*2);
+ externalProcess = new QProcess(this);
+ connect(externalProcess, SIGNAL(processExited()), SLOT(processExited()));
+ connect(externalProcess, SIGNAL(readyReadStdout()), SLOT(readyReadStdout()));
+ connect(externalProcess, SIGNAL(readyReadStderr()), SLOT(readyReadStderr()));
+
+ logDialog = new LogDialog(this);
+ logDialog->hide();
+ previousButton->hide();
+
+ createActionFormats();
+
+ kdeDirProcess = new QProcess(this);
+ connect(kdeDirProcess, SIGNAL(readyReadStdout()), SLOT(kdeDirReady()));
+ connect(kdeDirProcess, SIGNAL(processExited()), SLOT(getInstalledComponents()));
+ kdeDirProcess->addArgument("kde-config");
+ kdeDirProcess->addArgument("--prefix");
+ if (!kdeDirProcess->start())
+ getInstalledComponents();
+
+ errs[0] = CompileError( "libevent", "The installation process finished with an error because it needs a "
+ " component missing on your system. To correct this, "
+ "do the following: <br> 1. Download and install the package for your distribution with the word 'libevent' in its title. <br> 2. Retry installation." );
+ errs[1] = CompileError( "X includes", "The installation process finished with an error because it needs a "
+ " component missing on your system. To correct this, "
+ "do the following: <br> 1. Download and install any packages for your distribution with (i) 'X' and "
+ " either 'devel' or 'lib' in their name. <br> 2. Retry installation. " );
+ errs[2] = CompileError( "There is no user 'privoxy' on this system", "The installation reported an"
+ "error because you need to create the 'privoxy' user. To correct this, "
+ "do the following: <br> 1. As root, enter the following command: useradd privoxy. <br> 2. Retry installation. " );
+ errs[3] = CompileError( "installing config files as root", "The installation reported an"
+ "error because I attempted to install the privoxy config files as root. <b> There is no "
+ "need to take any action on your part. Privoxy has been installed and you can now use it with TorK. " );
+ errs[4] = CompileError( "Qt (>= ", "The installation process finished with an error because it needs a "
+ " component missing on your system. To correct this, "
+ "do the following: <br> 1. Download and install any packages for your distribution with (i) 'qt' and "
+ " either 'devel' or 'lib' in their name. <br> 2. Retry installation. " );
+
+
+
+
+}
+
+void Wizard::createActionFormats()
+{
+ // Taken from KDevelop
+ actionFormats.clear();
+ actionFormats.append(ActionFormat( tr("compiling"), "g++", "g\\+\\+\\S* (?:\\S* )*-c (?:\\S* )*`[^`]*`(?:[^/\\s;]*/)*([^/\\s;]+)", 1 ));
+ actionFormats.append(ActionFormat( tr("compiling"), "g++", "g\\+\\+\\S* (?:\\S* )*-c (?:\\S* )*(?:[^/]*/)*([^/\\s;]*)", 1 ));
+ actionFormats.append(ActionFormat( tr("compiling"), "gcc", "gcc\\S* (?:\\S* )*-c (?:\\S* )*`[^`]*`(?:[^/\\s;]*/)*([^/\\s;]+)", 1 ));
+ actionFormats.append(ActionFormat( tr("compiling"), "gcc", "gcc\\S* (?:\\S* )*-c (?:\\S* )*(?:[^/]*/)*([^/\\s;]*)", 1 ));
+ actionFormats.append(ActionFormat( tr("compiling"), "distcc", "distcc (?:\\S* )*-c (?:\\S* )*`[^`]*`(?:[^/\\s;]*/)*([^/\\s;]+)", 1 ));
+ actionFormats.append(ActionFormat( tr("compiling"), "distcc", "distcc (?:\\S* )*-c (?:\\S* )*(?:[^/]*/)*([^/\\s;]*)", 1 ));
+ actionFormats.append(ActionFormat( tr("compiling"), "unknown", "^compiling (.*)", 1 ));
+ actionFormats.append(ActionFormat( tr("generating"), "moc", "/moc\\b.*\\s-o\\s([^\\s;]+)", 1 ));
+ actionFormats.append(ActionFormat( tr("generating"), "uic", "/uic\\b.*\\s-o\\s([^\\s;]+)", 1 ));
+ actionFormats.append(ActionFormat( tr("linking"), "libtool", "/+bin/+sh\\s.*libtool.*--mode=link\\s.*\\s-o\\s([^\\s;]+)", 1 ));
+ actionFormats.append(ActionFormat( tr("linking"), "g++", "g\\+\\+\\S* (?:\\S* )*-o ([^\\s;]+)", 1 ));
+ actionFormats.append(ActionFormat( tr("linking"), "gcc", "gcc\\S* (?:\\S* )*-o ([^\\s;]+)", 1 ));
+ actionFormats.append(ActionFormat( tr("creating"), "", "/(?:bin/+sh\\s.*mkinstalldirs).*\\s([^\\s;]+)", 1 ));
+ actionFormats.append(ActionFormat( tr("installing"), "", "/(?:usr/+bin/+install|bin/+sh\\s.*mkinstalldirs|bin/+sh\\s.*libtool.*--mode=install).*\\s\\'?([^\\s;\\']+)\\'?", 1 ));
+ actionFormats.append(ActionFormat( tr("generating"), "dcopidl", "dcopidl .* > ([^\\s;]+)", 1 ));
+ actionFormats.append(ActionFormat( tr("compiling"), "dcopidl2cpp", "dcopidl2cpp (?:\\S* )*([^\\s;]+)", 1 ));
+}
+
+void Wizard::kdeDirReady()
+{
+ while (kdeDirProcess->canReadLineStdout())
+ {
+ QString line = kdeDirProcess->readLineStdout();
+ if (!line.isEmpty())
+ kdeDir = line;
+ }
+}
+
+void Wizard::getInstalledComponents()
+{
+ QFile uninstallScript("/tmp/arkollon-uninstall.sh");
+ if (uninstallScript.exists())
+ uninstallScript.remove();
+ uninstallScript.open(IO_WriteOnly);
+ QDataStream stream(&uninstallScript);
+ stream.writeRawBytes((const char*)uninstaller_sh_data, uninstaller_sh_len);
+ uninstallScript.close();
+
+ installedComponentsProcess = new QProcess(this);
+ connect(installedComponentsProcess, SIGNAL(readyReadStdout()), SLOT(installedComponentsReady()));
+ connect(installedComponentsProcess, SIGNAL(processExited()), SLOT(setup()));
+ installedComponentsProcess->addArgument("/bin/sh");
+ installedComponentsProcess->addArgument("/tmp/arkollon-uninstall.sh");
+ installedComponentsProcess->addArgument("--list");
+ if (!installedComponentsProcess->start())
+ setup();
+}
+
+void Wizard::installedComponentsReady()
+{
+ while (installedComponentsProcess->canReadLineStdout())
+ {
+ QString line = installedComponentsProcess->readLineStdout();
+ if (line.isEmpty())
+ continue;
+
+ // See if it already exists
+ if (installedComponents.find(line.lower()) != installedComponents.end())
+ continue;
+
+ installedComponents.append(line.lower());
+ //printf("Found installed component %s\n", parser.cap(3).latin1());
+ }
+}
+
+void Wizard::setup()
+{
+ QFile uninstallScript("/tmp/arkollon-uninstall.sh");
+ if (uninstallScript.exists())
+ uninstallScript.remove();
+
+ if (kdeDir.isEmpty())
+ kdeDir = "/usr";
+
+ // Firstly check if there's an arkollonrc file in the current directory
+ // If there is, use it.
+ dir = QDir::currentDirPath();
+ if (qApp->argc() > 1)
+ {
+ // The directory specified on the command line overrides the current dir.
+ QDir d(qApp->argv()[1]);
+ dir = d.absPath();
+ }
+ if (QFile::exists(dir + "/arkollonrc"))
+ {
+ setupFromRc();
+ }
+ else
+ {
+ if (!setupFromDir())
+ {
+ QMessageBox::critical(NULL, "Error", "This directory does not contain any recognised buildsystem", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+ reject();
+ return;
+ }
+ }
+ show();
+}
+
+void Wizard::setupFromRc()
+{
+ RcParser parser;
+ parser.addSearchDir(dir);
+ if (!parser.openFile("arkollonrc"))
+ {
+ QMessageBox::critical(NULL, "Error", "The \"arkollonrc\" file in this directory could not be read", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+ reject();
+ return;
+ }
+
+ parser.setSection("Arkollon");
+ QString appName = parser.readString("AppName");
+ if (appName.isEmpty())
+ {
+ QMessageBox::critical(NULL, "Error", "The \"arkollonrc\" file in this directory contains no application name!", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+ reject();
+ return;
+ }
+ setAppName(appName);
+
+ QString icon32Path = parser.readString("Icon32");
+ QString icon16Path = parser.readString("Icon16");
+ if ((!icon32Path.isEmpty()) && (QFile::exists(dir + "/" + icon32Path)))
+ {
+ QPixmap icon32(dir + "/" + icon32Path);
+ appIcon->setPixmap(icon32);
+ }
+ if ((!icon16Path.isEmpty()) && (QFile::exists(dir + "/" + icon16Path)))
+ {
+ QPixmap icon16(dir + "/" + icon16Path);
+ setIcon(icon16);
+ }
+
+ buildOrder = parser.readList("BuildOrder");
+ QStringList compNames = parser.readList("Components");
+ QStringList::Iterator it = compNames.begin();
+ while( it != compNames.end() )
+ {
+ parser.setSection(*it);
+
+ struct Component c;
+ c.name = *it;
+ c.niceName = parser.readString("NiceName");
+ c.subDir = parser.readString("SubDir");
+ c.forceDir = sub(parser.readString("ForceDir"));
+ c.optional = parser.readBool("Optional", false);
+ c.kdeOnly = parser.readBool("KDEOnly", false);
+ c.gnomeOnly = parser.readBool("GnomeOnly", false);
+ c.description = sub(parser.readString("Description"));
+ c.confOptions = parser.readString("ConfigureOptions");
+ c.alreadyInstalled = false;
+
+ // Load the buildtimes data
+ if (QFile::exists(dir + "/" + c.subDir + "/buildtimes"))
+ {
+ QRegExp re("([^,]*,[^,]*),(\\d*)");
+ QFile file(dir + "/" + c.subDir + "/buildtimes");
+ file.open(IO_ReadOnly);
+ QTextStream stream(&file);
+ for (;;)
+ {
+ QString line = stream.readLine();
+ if (line.isNull())
+ break;
+ if (re.search(line) == -1)
+ continue;
+ c.buildTimes.insert(re.cap(1), re.cap(2).toInt());
+ }
+ }
+
+ // Add the header for this component
+ ComponentListItem* item = new ComponentListItem(c, componentList);
+ if (!headers.contains(item->section))
+ {
+ headers[item->section] = new HeaderListItem(componentList);
+ ((HeaderListItem*)headers[item->section])->section = item->section;
+
+ switch(item->section)
+ {
+ case 0: headers[item->section]->setText(0, "Required components"); break;
+ case 1: headers[item->section]->setText(0, "Optional components"); break;
+ case 2: headers[item->section]->setText(0, "Gnome specific components"); break;
+ case 3: headers[item->section]->setText(0, "KDE specific components"); break;
+ }
+ }
+
+ // Check if it's already installed
+ QStringList::Iterator it2 = installedComponents.begin();
+ while( it2 != installedComponents.end() )
+ {
+ int dashPos = c.subDir.findRev('-');
+ if (dashPos < 0)
+ dashPos = c.subDir.length();
+ QString version = c.subDir.left(dashPos) + ":" + c.subDir.right(c.subDir.length() - dashPos - 1);
+ if (*it2 == version.lower())
+ {
+ item->setOn(false);
+ item->component.alreadyInstalled = true;
+ }
+ ++it2;
+ }
+
+ ++it;
+ }
+ parser.setSection("Arkollon");
+ exec = sub(parser.readString("Exec"));
+ desktop = sub(parser.readString("Desktop"));
+}
+
+bool Wizard::setupFromDir()
+{
+ if ((!QFile::exists(dir + "/configure")) &&
+ (!QFile::exists(dir + "/autogen.sh")) &&
+ (!QFile::exists(dir + "/auto-gen.sh")))
+ {
+ QDir myDir(dir + "/" + selectedComponents[currentComponent].subDir);
+ if (myDir.entryList("*.pro", QDir::Files).count() <= 0)
+ return false;
+ }
+
+ // Use the directory name as the appname
+ QDir myDir2(dir);
+ QString dirName = myDir2.dirName();
+ setAppName(makeDirNice(dirName));
+
+ buildOrder.append(dirName);
+ struct Component c;
+ c.name = dirName;
+ c.niceName = makeDirNice(dirName);
+ c.optional = false;
+ c.subDir = "";
+ c.gnomeOnly = false;
+ c.kdeOnly = false;
+ c.description = "<i>No description is associated with this component.</i>";
+ c.alreadyInstalled = false;
+ ComponentListItem* item = new ComponentListItem(c, componentList);
+ HeaderListItem* header = new HeaderListItem(componentList);
+ header->setText(0, "Required components");
+ header->section = 0;
+
+ QStringList::Iterator it2 = installedComponents.begin();
+ while( it2 != installedComponents.end() )
+ {
+ int dashPos = dirName.findRev('-');
+ if (dashPos < 0)
+ dashPos = dirName.length();
+ QString version = dirName.left(dashPos) + ":" + dirName.right(dirName.length() - dashPos - 1);
+ if (*it2 == version.lower())
+ item->component.alreadyInstalled = true;
+ ++it2;
+ }
+
+ return true;
+}
+
+
+Wizard::~Wizard()
+{
+}
+
+
+void Wizard::componentSelected(QListViewItem* item)
+{
+ if (item->rtti() != 1001)
+ return;
+
+ ComponentListItem* i = (ComponentListItem*) item;
+ QString text = "<p><b>" + item->text(0) + "</b>";
+ if (i->component.alreadyInstalled)
+ text += " <i>(Already installed)</i>";
+ text += "</p><p>";
+ text += i->component.description;
+ text += "</p>";
+
+ componentInfo->setText(text);
+}
+
+
+QString Wizard::makeDirNice(QString name)
+{
+ int dashPos = name.findRev('-');
+ if (dashPos < 0)
+ dashPos = name.length();
+
+ QString ret = name.left(dashPos);
+ ret = ret.left(1).upper() + ret.right(ret.length()-1);
+
+ return ret;
+}
+
+
+void Wizard::cancelPressed()
+{
+ if (externalProcess->isRunning())
+ externalProcess->tryTerminate();
+
+ reject();
+}
+
+void Wizard::nextPressed()
+{
+ int currentId = installStack->id(installStack->visibleWidget());
+ if (currentId == 3)
+ {
+ QDir d(kdeDir);
+ d.mkdir("share/apps/kdesktop/Desktop");
+ if (shortcutBox->isChecked())
+ {
+ QFile source(dir + "/" + desktop);
+ QString destDir = kdeDir + "/share/apps/kdesktop/Desktop";
+ int slashPos = desktop.findRev('/');
+ if (slashPos < 0)
+ slashPos = 0;
+ QFile dest(destDir + "/" + desktop.right(desktop.length() - slashPos));
+ source.open(IO_ReadOnly);
+ dest.open(IO_WriteOnly | IO_Truncate);
+ QDataStream destStream(&dest);
+ QByteArray data = source.readAll();
+ destStream.writeRawBytes(data.data(), data.size());
+ source.close();
+ dest.close();
+ }
+ if (uninstallBox->isChecked())
+ {
+ QFile source(dir + "/Uninstall TorK.desktop");
+ QFile dest(kdeDir + "/share/apps/kdesktop/Desktop/Uinstall TorK.desktop");
+ source.open(IO_ReadOnly);
+ dest.open(IO_WriteOnly | IO_Truncate);
+ QDataStream destStream(&dest);
+ QByteArray data = source.readAll();
+ destStream.writeRawBytes(data.data(), data.size());
+ source.close();
+ dest.close();
+ }
+ accept();
+ return;
+ }
+ if ((currentId == 2) && (exec.isEmpty()))
+ {
+ accept();
+ return;
+ }
+
+ if (currentId == 1)
+ {
+ bool itemsSelected = false;
+
+ QListViewItemIterator it( componentList );
+ while ( it.current() )
+ {
+ if (it.current()->rtti() != 1001)
+ {
+ ++it;
+ continue;
+ }
+ ComponentListItem* item = (ComponentListItem*) it.current();
+ if (item->isOn())
+ itemsSelected = true;
+ ++it;
+ }
+ if (!itemsSelected)
+ {
+ QMessageBox::warning(this, "Warning", "You need to select at least one component", QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+ return;
+ }
+ }
+
+ installStack->raiseWidget(++currentId);
+
+ if (currentId == 2)
+ {
+ pleaseWaitLabel->setText("Please wait while the software is compiled and installed");
+ timeRemaining->setText("Estimated time remaining: <b>Calculating...</b>");
+ startProcess();
+ nextButton->setEnabled(false);
+ previousButton->setEnabled(false);
+ }
+ else if (currentId == 3)
+ {
+ nextButton->setText("Finish");
+ }
+ else
+ previousButton->setEnabled(true);
+}
+
+void Wizard::previousPressed()
+{
+ int currentId = installStack->id(installStack->visibleWidget());
+ if (currentId == 0)
+ return;
+
+ installStack->raiseWidget(--currentId);
+
+ if (currentId == 0)
+ previousButton->setEnabled(false);
+ nextButton->setEnabled(true);
+}
+
+
+void Wizard::startProcess()
+{
+ selectedComponents.clear();
+
+ totalBTime = 0;
+ elapsedTime = 0;
+ elapsedBTime = 0;
+ for ( QStringList::Iterator it = buildOrder.begin(); it != buildOrder.end(); ++it )
+ {
+ QListViewItemIterator it2( componentList );
+ while ( it2.current() )
+ {
+ if (it2.current()->rtti() != 1001)
+ {
+ ++it2;
+ continue;
+ }
+ ComponentListItem* item = (ComponentListItem*) it2.current();
+ if (item->component.name == *it)
+ {
+ if (item->isOn())
+ {
+ selectedComponents.append(item->component);
+ QMap<QString, uint>::iterator it3;
+ for ( it3 = item->component.buildTimes.begin(); it3 != item->component.buildTimes.end(); ++it3 )
+ totalBTime += it3.data();
+ }
+ }
+ ++it2;
+ }
+ }
+
+ progressBar->setProgress(0);
+ progressBar->setTotalSteps(totalBTime);
+
+ currentComponent = 0;
+ currentStage = None;
+ currentIsQMake = false;
+
+ nextStep();
+}
+
+void Wizard::nextStep()
+{
+ externalProcess->clearArguments();
+
+ switch (currentStage)
+ {
+ case None:
+ {
+ logLine(selectedComponents[currentComponent].niceName);
+ progressLabel1->setText("<b>Running autogen for " + selectedComponents[currentComponent].niceName + "</b>");
+ setProgress2Text("");
+ //progressLabel2->setCursorPosition(0);
+ currentStage = Autogen;
+ QDir myDir(dir + "/" + selectedComponents[currentComponent].subDir);
+ if (myDir.entryList("*.pro", QDir::Files).count() > 0)
+ {
+ currentIsQMake = true;
+ nextStep();
+ return;
+ }
+
+ if (QFile::exists(dir + "/" + selectedComponents[currentComponent].subDir + "/configure"))
+ {
+ nextStep();
+ return;
+ }
+
+ QString autogenName;
+ if (QFile::exists(dir + "/" + selectedComponents[currentComponent].subDir + "/autogen.sh"))
+ autogenName = "autogen.sh";
+ else if (QFile::exists(dir + "/" + selectedComponents[currentComponent].subDir + "/auto-gen.sh"))
+ autogenName = "auto-gen.sh";
+ else
+ {
+ logLine("No configure, autogen, or qmake scripts found");
+ errorOccured();
+ return;
+ }
+
+ externalProcess->addArgument(dir + "/" + selectedComponents[currentComponent].subDir + autogenName);
+ externalProcess->setWorkingDirectory(dir + "/" + selectedComponents[currentComponent].subDir);
+ logLine("Running autogen...");
+ externalProcess->start();
+ break;
+ }
+ case Autogen:
+ {
+ //progressBar->setProgress(progressBar->progress() + 1);
+ currentStage = Configure;
+ if (currentIsQMake)
+ {
+ progressLabel1->setText("<b>Running qmake for " + selectedComponents[currentComponent].niceName + "</b>");
+ setProgress2Text("");
+ //progressLabel2->setCursorPosition(0);
+ externalProcess->addArgument("qmake");
+ externalProcess->setWorkingDirectory(dir + "/" + selectedComponents[currentComponent].subDir);
+ if (!externalProcess->start())
+ {
+ logLine("Error: qmake was not found. Try installing the Qt-devel libraries.");
+ errorOccured();
+ return;
+ }
+ logLine("Running qmake...");
+ break;
+ }
+
+ if (!selectedComponents[currentComponent].forceDir.isEmpty())
+ prefix = selectedComponents[currentComponent].forceDir;
+ else
+ prefix = "/usr/local";
+
+ externalProcess->addArgument("./configure");
+ //externalProcess->addArgument("--prefix=" + prefix);
+ if (!selectedComponents[currentComponent].confOptions.isEmpty())
+ {
+ QStringList extraArgs = QStringList::split(" ", sub(selectedComponents[currentComponent].confOptions));
+ for ( QStringList::Iterator it = extraArgs.begin(); it != extraArgs.end(); ++it )
+ externalProcess->addArgument(*it);
+ }
+ externalProcess->setWorkingDirectory(dir + "/" + selectedComponents[currentComponent].subDir);
+ logLine("Running configure (" + externalProcess->arguments().join(" ") + ")...");
+ progressLabel1->setText("<b>Configuring " + selectedComponents[currentComponent].niceName + "</b>");
+ setProgress2Text("");
+ timer.start();
+ externalProcess->start();
+ break;
+ }
+ case Configure:
+ {
+ updateTime("configure,");
+
+ currentStage = Compile;
+
+ externalProcess->addArgument("make");
+ externalProcess->setWorkingDirectory(dir + "/" + selectedComponents[currentComponent].subDir);
+ logLine("Running make...");
+ progressLabel1->setText("<b>Compiling " + selectedComponents[currentComponent].niceName + "</b>");
+ setProgress2Text("");
+ timer.setHMS(0, 0, 0);
+ externalProcess->start();
+ break;
+ }
+ case Compile:
+ {
+ currentStage = Install;
+
+ logLine("Installing...");
+ progressLabel1->setText("<b>Installing " + selectedComponents[currentComponent].niceName + "</b>");
+ setProgress2Text("");
+
+ installedFiles.clear();
+
+ externalProcess->addArgument("make");
+ externalProcess->addArgument("install");
+ externalProcess->setWorkingDirectory(dir + "/" + selectedComponents[currentComponent].subDir);
+ externalProcess->start();
+
+ break;
+ }
+ case Install:
+ {
+ currentStage = WriteUninstallInfo;
+ logLine("Writing uninstall information...");
+ progressLabel1->setText("<b>Writing uninstall information for " + selectedComponents[currentComponent].niceName + "</b>");
+ setProgress2Text("");
+
+ QFile postInstallScript("/tmp/arkollon-postinstall.sh");
+ if (postInstallScript.exists())
+ postInstallScript.remove();
+ postInstallScript.open(IO_WriteOnly);
+ QDataStream stream(&postInstallScript);
+ stream.writeRawBytes((const char*)postinstall_sh_data, postinstall_sh_len);
+ postInstallScript.close();
+
+ QFile fileList("/tmp/arkollon-filelist");
+ if (fileList.exists())
+ fileList.remove();
+ fileList.open(IO_WriteOnly);
+ QTextStream fileStream(&fileList);
+ QStringList doneFiles;
+ for ( QStringList::Iterator it = installedFiles.begin(); it != installedFiles.end(); ++it )
+ {
+ if (doneFiles.find(*it) != doneFiles.end())
+ continue;
+ QFileInfo fileInfo(*it);
+ if (fileInfo.isDir())
+ continue;
+ fileStream << (*it) << '\n';
+ doneFiles.append(*it);
+ }
+ fileList.close();
+
+ struct Component c = selectedComponents[currentComponent];
+ int dashPos = c.subDir.findRev('-');
+ if (dashPos < 0)
+ dashPos = c.subDir.length();
+ QString appname = c.subDir.left(dashPos);
+ QString version = c.subDir.right(c.subDir.length() - dashPos - 1);
+
+ externalProcess->addArgument("/bin/sh");
+ externalProcess->addArgument("/tmp/arkollon-postinstall.sh");
+ externalProcess->addArgument("--appname");
+ externalProcess->addArgument(appname);
+ externalProcess->addArgument("--version");
+ externalProcess->addArgument(version);
+ externalProcess->addArgument("--filelist");
+ externalProcess->addArgument("/tmp/arkollon-filelist");
+ externalProcess->start();
+ break;
+ }
+ case WriteUninstallInfo:
+ {
+ currentStage = None;
+ currentComponent++;
+ currentIsQMake = false;
+ if (currentComponent >= selectedComponents.count())
+ {
+ progressLabel1->setText("<b>Installation completed!</b>");
+ pleaseWaitLabel->setText("Installation complete");
+ timeRemaining->setText("");
+ progressBar->setProgress(totalBTime);
+ nextButton->setEnabled(true);
+ if (exec.isEmpty())
+ {
+ nextButton->setText("Finish");
+ setProgress2Text("");
+ }
+ else
+ {
+ setProgress2Text("Click \"next\" to continue");
+ }
+
+ return;
+ }
+ nextStep();
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void Wizard::processExited()
+{
+ if (currentStage == WriteUninstallInfo)
+ {
+ // Remove temp files from the last stage
+ QFile postInstallScript("/tmp/arkollon-postinstall.sh");
+ if (postInstallScript.exists())
+ postInstallScript.remove();
+
+ QFile fileList("/tmp/arkollon-filelist");
+ if (fileList.exists())
+ fileList.remove();
+ }
+ if (!externalProcess->normalExit())
+ {
+ logLine("Process was killed");
+ errorOccured();
+ return;
+ }
+ if (externalProcess->exitStatus() != 0)
+ {
+ logLine("Return value " + QString::number(externalProcess->exitStatus()));
+ errorOccured();
+ return;
+ }
+ if (currentStage == Compile)
+ updateTime(lastTimeLine);
+ nextStep();
+}
+
+void Wizard::readyReadStderr()
+{
+ while (externalProcess->canReadLineStderr())
+ {
+ QString line = externalProcess->readLineStderr().latin1();
+ CompileErrorVector::iterator it;
+ for( it = errs.begin(); it != errs.end(); ++it ){
+ if (line.contains((*it).type()))
+ QMessageBox::information( this, (*it).type(), (*it).message() );
+ }
+ logDialog->logBox->append(" * "+line);
+ }
+}
+
+void Wizard::readyReadStdout()
+{
+ while (externalProcess->canReadLineStdout())
+ {
+ QString line = externalProcess->readLineStdout().latin1();
+ logDialog->logBox->append(line);
+
+ if (currentStage == Configure)
+ {
+ setProgress2Text(line);
+ continue;
+ }
+ commandLine += line;
+ if (line.right(1) == "\\")
+ continue;
+ commandLine = commandLine.left(commandLine.find(';'));
+ for ( QValueList<ActionFormat>::Iterator it = actionFormats.begin(); it != actionFormats.end(); ++it )
+ {
+ if ((*it).regExp.search(commandLine) == -1)
+ continue;
+ setProgress2Text((*it).action + " <b>" + (*it).regExp.cap(1) + "</b> (" + (*it).tool + ")");
+ if ((currentStage == Install) && ((*it).action == "installing"))
+ installedFiles.append((*it).regExp.cap(1));
+ else
+ updateTime(lastTimeLine);
+ lastTimeLine = (*it).tool + "," + (*it).regExp.cap(1);
+ }
+ commandLine = "";
+ }
+}
+
+void Wizard::updateTime(QString key)
+{
+ if (!timer.isNull())
+ {
+ elapsedBTime += selectedComponents[currentComponent].buildTimes[key];
+ elapsedTime += timer.elapsed();
+ float ratio = (float)elapsedTime / (float)elapsedBTime;
+ int remainingTime = (int)((float)(totalBTime - elapsedBTime) * ratio) / 60000;
+ if (remainingTime < 0)
+ remainingTime = 0;
+ QString text = QString::number(remainingTime + 1) + " minutes";
+ if (remainingTime == 0)
+ text = "1 minute";
+ timeRemaining->setText("Estimated time remaining: <b>" + text + "</b>");
+ progressBar->setProgress(elapsedBTime);
+ }
+ timer.start();
+}
+
+void Wizard::logLine(QString line)
+{
+ QString tmp = line;
+ QStringList lines = QStringList::split("\n", tmp);
+ for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ logDialog->logBox->append("***** "+*it);
+ }
+}
+
+void Wizard::setProgress2Text(QString text)
+{
+ QString croppedText = text;
+ int i = croppedText.length();
+
+ QFont boldFont = progressLabel2->font();
+ boldFont.setBold(true);
+ QFontMetrics boldFontMetrics(boldFont);
+ while (boldFontMetrics.width(croppedText) > progressLabel2->width())
+ {
+ croppedText = croppedText.left(--i);
+ }
+
+ progressLabel2->setText(croppedText);
+}
+
+void Wizard::errorOccured()
+{
+ //logFrame->show();
+ pleaseWaitLabel->setText("An error occured");
+ progressLabel1->setText("<b>An error occured</b>");
+ setProgress2Text("See the log file for more information");
+ previousButton->setEnabled(true);
+}
+
+QString Wizard::sub(QString s)
+{
+ QString tmp = s;
+ tmp.replace(QRegExp("\\$KDEDIR"), kdeDir);
+ tmp.replace(QRegExp("\\$HOMEDIR"), QDir::homeDirPath());
+ tmp.replace(QRegExp("~"), QDir::homeDirPath());
+ tmp.replace(QRegExp("\\$PREFIX"), "/usr/local");
+
+ return tmp;
+}
+
+void Wizard::runPressed()
+{
+ QProcess* proc = new QProcess(this);
+ proc->addArgument(exec);
+ if (!proc->start())
+ {
+ QMessageBox::warning(this, "Warning", "The application could not be started<br>"+exec, QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton);
+ }
+}
+
+void Wizard::logPressed()
+{
+ logDialog->show();
+}
+
+#include "wizard.moc"
+
diff --git a/src/arkollon/wizard.h b/src/arkollon/wizard.h
new file mode 100644
index 0000000..cf32d9d
--- /dev/null
+++ b/src/arkollon/wizard.h
@@ -0,0 +1,183 @@
+/***************************************************************************
+ * Copyright (C) 2004 by David Sansome *
+ * me@davidsansome.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef WIZARD_H
+#define WIZARD_H
+
+#include <wizardbase.h>
+#include <qlistview.h>
+#include <qprocess.h>
+#include <qsettings.h>
+#include <qiconview.h>
+#include <qregexp.h>
+#include <qvaluevector.h>
+#include <qstring.h>
+#include <stdio.h>
+
+#include "logdialog.h"
+class HeaderListItem;
+
+struct Component
+{
+ QString name;
+ QString niceName;
+ QString subDir;
+ QString forceDir;
+ bool optional;
+ bool kdeOnly;
+ bool gnomeOnly;
+ QString description;
+ QString confOptions;
+
+ QMap<QString, uint> buildTimes;
+
+ bool alreadyInstalled;
+};
+
+class ComponentListItem : public QCheckListItem
+{
+public:
+ ComponentListItem(struct Component c, QListView* parent);
+ int compare(QListViewItem* i, int col, bool ascending) const;
+ int rtti() const { return 1001; }
+
+ struct Component component;
+ int section;
+};
+
+class ActionFormat
+{
+public:
+ ActionFormat() {}
+ ActionFormat(QString a, QString t, QString r, int) { action=a; tool=t; regExp=r; }
+ ~ActionFormat() {}
+
+ QString action;
+ QString tool;
+ QRegExp regExp;
+};
+
+
+class CompileError
+{
+public:
+ CompileError() {}
+ CompileError( const QString& type, const QString& message )
+ : t( type ), m( message )
+ { }
+
+ QString type() const { return t; }
+ QString message() const { return m; }
+private:
+ QString t;
+ QString m;
+};
+
+
+
+class Wizard : public WizardBase
+{
+ Q_OBJECT
+
+public:
+ Wizard(QWidget *parent = 0, const char *name = 0);
+
+ ~Wizard();
+
+
+private:
+ void createActionFormats();
+ void startProcess();
+ void nextStep();
+ void checkPassword();
+
+ void updateTime(QString key);
+ QString lastTimeLine;
+
+ void logLine(QString line);
+ void errorOccured();
+ QString makeDirNice(QString name);
+
+ QString sub(QString s);
+
+ QString rootPassword;
+
+private slots:
+ void processExited();
+ void readyReadStdout();
+ void readyReadStderr();
+ void kdeDirReady();
+ void getInstalledComponents();
+ void installedComponentsReady();
+
+ void cancelPressed();
+ void nextPressed();
+ void previousPressed();
+ void runPressed();
+ void logPressed();
+ void componentSelected(QListViewItem* item);
+ void setProgress2Text(QString text);
+
+ void setup();
+ void setupFromRc();
+ bool setupFromDir();
+
+private:
+ enum Stage
+ {
+ None,
+ Autogen,
+ Configure,
+ Compile,
+ Install,
+ WriteUninstallInfo
+ };
+
+ QString dir;
+ QStringList buildOrder;
+ QValueList<struct Component> selectedComponents;
+ uint totalBTime;
+ uint elapsedBTime;
+ uint elapsedTime;
+ QTime timer;
+ QProcess* externalProcess;
+ QProcess* kdeDirProcess;
+ QProcess* installedComponentsProcess;
+ QString commandLine;
+ bool currentIsQMake;
+ uint currentComponent;
+ enum Stage currentStage;
+ bool needRoot;
+ QString prefix;
+
+ QStringList installedComponents;
+ QString exec;
+ QString desktop;
+
+ QString kdeDir;
+
+ LogDialog* logDialog;
+
+ QMap<int, HeaderListItem*> headers;
+ QValueList<ActionFormat> actionFormats;
+ QStringList installedFiles;
+
+};
+
+#endif
diff --git a/src/arkollon/wizardbase.ui b/src/arkollon/wizardbase.ui
new file mode 100644
index 0000000..6fc9d12
--- /dev/null
+++ b/src/arkollon/wizardbase.ui
@@ -0,0 +1,921 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>WizardBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>WizardBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>587</width>
+ <height>384</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>530</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="caption">
+ <string>[AppName] installation</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="resizeMode">
+ <enum>Fixed</enum>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>splash</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>titleLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;[AppName] installation&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QWidgetStack">
+ <property name="name">
+ <cstring>mainStack</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>0</number>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QWidgetStack">
+ <property name="name">
+ <cstring>installStack</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Introduction</cstring>
+ </property>
+ <attribute name="id">
+ <number>0</number>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;This wizard will guide you through the installation of:</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout12</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>30</width>
+ <height>10</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>appIcon</cstring>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>appNameLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;[AppName]&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>10</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Please click "Next" to continue</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>71</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Components</cstring>
+ </property>
+ <attribute name="id">
+ <number>1</number>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Select the components to install</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Component name</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>componentList</cstring>
+ </property>
+ </widget>
+ <widget class="QTextEdit">
+ <property name="name">
+ <cstring>componentInfo</cstring>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Select a component from the list above to see a brief description of it.&lt;/i&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <enum>WidgetWidth</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>2</number>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pleaseWaitLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Please wait while the software is compiled and installed</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer14_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Minimum</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>progressLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Progress Label 1</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>progressLabel2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Progress Label 2</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignTop|AlignLeft</set>
+ </property>
+ </widget>
+ <widget class="QProgressBar">
+ <property name="name">
+ <cstring>progressBar</cstring>
+ </property>
+ <property name="progress">
+ <number>0</number>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>timeRemaining</cstring>
+ </property>
+ <property name="text">
+ <string>Estimated time remaining: &lt;b&gt;Calculating...&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer15</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>logFrame</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>logSpacer_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>224</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>logButton</cstring>
+ </property>
+ <property name="text">
+ <string>View log file...</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>3</number>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;The installation is complete.&lt;/p&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="0" column="0" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>spacer16</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>30</width>
+ <height>50</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="2" column="1">
+ <property name="name">
+ <cstring>uninstallBox</cstring>
+ </property>
+ <property name="text">
+ <string>Place a shortcut to the uninstaller on the desktop</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="1">
+ <property name="name">
+ <cstring>shortcutBox</cstring>
+ </property>
+ <property name="text">
+ <string>Place a shortcut to [AppName] on the desktop</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>90</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>1</number>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QWidgetStack">
+ <property name="name">
+ <cstring>uninstallStack</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>0</number>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Please select from the list below the applications you wish to uninstall.</string>
+ </property>
+ </widget>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Application Name</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>appList</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>1</number>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_3</cstring>
+ </property>
+ <property name="text">
+ <string>The following files will be removed.&lt;br&gt;
+Please check this list, and click &lt;b&gt;next&lt;/b&gt; to continue.</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ </widget>
+ <widget class="QListBox">
+ <property name="name">
+ <cstring>fileList</cstring>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WStackPage</cstring>
+ </property>
+ <attribute name="id">
+ <number>2</number>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer14</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pleaseWaitLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Please wait while the selected packages are removed...</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer15_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>41</width>
+ <height>156</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>logFrame_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>logSpacer_2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>224</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>logButton2</cstring>
+ </property>
+ <property name="text">
+ <string>View log file...</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </widget>
+ </vbox>
+ </widget>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>61</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>previousButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&lt; Previous</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>nextButton</cstring>
+ </property>
+ <property name="text">
+ <string>Next &gt;</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>cancelButton</cstring>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>nextButton</sender>
+ <signal>clicked()</signal>
+ <receiver>WizardBase</receiver>
+ <slot>nextPressed()</slot>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>WizardBase</receiver>
+ <slot>cancelPressed()</slot>
+ </connection>
+ <connection>
+ <sender>componentList</sender>
+ <signal>selectionChanged(QListViewItem*)</signal>
+ <receiver>WizardBase</receiver>
+ <slot>componentSelected(QListViewItem*)</slot>
+ </connection>
+ <connection>
+ <sender>logButton</sender>
+ <signal>clicked()</signal>
+ <receiver>WizardBase</receiver>
+ <slot>logPressed()</slot>
+ </connection>
+ <connection>
+ <sender>logButton2</sender>
+ <signal>clicked()</signal>
+ <receiver>WizardBase</receiver>
+ <slot>logPressed()</slot>
+ </connection>
+ <connection>
+ <sender>previousButton</sender>
+ <signal>clicked()</signal>
+ <receiver>WizardBase</receiver>
+ <slot>previousPressed()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>componentList</tabstop>
+ <tabstop>componentInfo</tabstop>
+ <tabstop>logButton</tabstop>
+ <tabstop>previousButton</tabstop>
+ <tabstop>nextButton</tabstop>
+ <tabstop>cancelButton</tabstop>
+</tabstops>
+<includes>
+ <include location="local" impldecl="in implementation">wizardbase.ui.h</include>
+ <include location="global" impldecl="in implementation">qwidgetstack.h</include>
+</includes>
+<slots>
+ <slot>setAppName( QString n )</slot>
+ <slot>nextPressed()</slot>
+ <slot>previousPressed()</slot>
+ <slot>cancelPressed()</slot>
+ <slot>browsePressed()</slot>
+ <slot>runPressed()</slot>
+ <slot>logPressed()</slot>
+ <slot>componentSelected( QListViewItem * item )</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/arkollon/wizardbase.ui.h b/src/arkollon/wizardbase.ui.h
new file mode 100644
index 0000000..2fd5bce
--- /dev/null
+++ b/src/arkollon/wizardbase.ui.h
@@ -0,0 +1,58 @@
+#include "data.h"
+
+void WizardBase::setAppName( QString n )
+{
+ QPixmap tmp;
+ tmp.convertFromImage(qembed_findImage("packageIcon"));
+ appIcon->setPixmap(tmp);
+ tmp.convertFromImage(qembed_findImage("splash"));
+ splash->setPixmap(tmp);
+
+ setCaption("Installing "+n);
+ titleLabel->setText("<b>Installing "+n+"</b>");
+ appNameLabel->setText("<b>"+n+"</b>");
+ shortcutBox->setText("Place a shortcut to "+n+" on the desktop");
+}
+
+
+void WizardBase::nextPressed()
+{
+
+}
+
+
+void WizardBase::previousPressed()
+{
+
+}
+
+
+void WizardBase::cancelPressed()
+{
+
+}
+
+
+void WizardBase::browsePressed()
+{
+
+}
+
+
+void WizardBase::runPressed()
+{
+
+}
+
+
+void WizardBase::logPressed()
+{
+
+}
+
+
+
+void WizardBase::componentSelected( QListViewItem * )
+{
+
+}
diff --git a/src/chart.cpp b/src/chart.cpp
new file mode 100644
index 0000000..fd90368
--- /dev/null
+++ b/src/chart.cpp
@@ -0,0 +1,123 @@
+/***************************************************************************
+** $Id: chart.cpp,v 1.8 2008/07/31 19:56:25 hoganrobert Exp $
+* Copyright (C) 2006 - 2008 Robert Hogan *
+* robert@roberthogan.net *
+* *
+* Copyright (C) 2005 by Hugo Parente Lima *
+* hugo_pl@users.sourceforge.net *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+***************************************************************************/
+
+#include "chart.h"
+#include "functions.h"
+#include <qpainter.h>
+#include <qbrush.h>
+#include <kdebug.h>
+
+using namespace tk;
+
+Chart::Chart(QWidget* parent, const double* uploadBuffer, const double* downloadBuffer, int bufferSize, const int* ptr, const double* maxspeed, const double* sys_uploadBuffer, const double* sys_downloadBuffer, int sys_bufferSize, const int* sys_ptr, const double* sys_maxspeed, bool gotEth0) : QWidget(parent), mUplBuffer(uploadBuffer), mDldBuffer(downloadBuffer), mBufferSize(bufferSize), mPtr(ptr), mMaxSpeed(maxspeed),sys_mUplBuffer(sys_uploadBuffer), sys_mDldBuffer(sys_downloadBuffer), sys_mBufferSize(sys_bufferSize), sys_mPtr(sys_ptr), sys_mMaxSpeed(sys_maxspeed),mGotEth0(gotEth0) {
+ setWFlags(Qt::WNoAutoErase);
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
+}
+
+void Chart::paintEvent(QPaintEvent*) {
+ QPainter paint(this);
+ paint.setBackgroundColor(Qt::black);
+ paint.setBackgroundMode(Qt::OpaqueMode);
+ QBrush brush(QColor(0x33, 0x33, 0x33), CrossPattern);
+ paint.fillRect(0, 0, width(), height(), brush);
+
+
+ const double step = width()/double(mBufferSize);
+ const int HEIGHT = height() - 1;
+ int x;
+ int lastX = x = width();
+ int lastRxY = HEIGHT - int(HEIGHT * (mDldBuffer[*mPtr]/(*mMaxSpeed)));
+ int lastTxY = HEIGHT - int(HEIGHT * (mUplBuffer[*mPtr]/(*mMaxSpeed)));
+ int count = 0;
+ for (int i = *mPtr; count < mBufferSize; i--) {
+ if (i < 0)
+ i = mBufferSize-1;
+ int rxY = HEIGHT - int(HEIGHT * (mDldBuffer[i]/(*mMaxSpeed)));
+ int txY = HEIGHT - int(HEIGHT * (mUplBuffer[i]/(*mMaxSpeed)));
+ paint.setPen(Qt::green);
+ paint.drawLine(lastX, lastRxY, x, rxY);
+ paint.setPen(Qt::red);
+ paint.drawLine(lastX, lastTxY, x, txY);
+ //qDebug("%d => %d", i, int(mSpeedHistoryRx[i]));
+ lastX = x;
+ lastRxY = rxY;
+ lastTxY = txY;
+
+ count++;
+ x = width() - int(step*(count+1));
+
+ }
+
+ paint.setFont(QFont("Helvetica", 8));
+ paint.setPen( Qt::red );
+ paint.drawText( rect(), Qt::AlignTop, QString("Tor Tx: %1 ").arg(BytesPerSecToString(mUplBuffer[*mPtr])));
+ paint.setPen( Qt::green );
+ paint.drawText( rect(), Qt::AlignBottom, QString("Tor Rx: %1 ").arg(BytesPerSecToString(mDldBuffer[*mPtr])));
+
+ if (mGotEth0){
+ lastX = x = width();
+ lastRxY = HEIGHT - int(HEIGHT * (sys_mDldBuffer[*sys_mPtr]/(*sys_mMaxSpeed)));
+ lastTxY = HEIGHT - int(HEIGHT * (sys_mUplBuffer[*sys_mPtr]/(*sys_mMaxSpeed)));
+ count = 0;
+ for (int i = *sys_mPtr; count < sys_mBufferSize; i--) {
+ if (i < 0)
+ i = sys_mBufferSize-1;
+ int rxY = HEIGHT - int(HEIGHT * (sys_mDldBuffer[i]/(*sys_mMaxSpeed)));
+ int txY = HEIGHT - int(HEIGHT * (sys_mUplBuffer[i]/(*sys_mMaxSpeed)));
+ paint.setPen(Qt::darkGreen);
+ paint.drawLine(lastX, lastRxY, x, rxY);
+ paint.setPen(Qt::darkRed);
+ paint.drawLine(lastX, lastTxY, x, txY);
+ //qDebug("%d => %d", i, int(mSpeedHistoryRx[i]));
+ lastX = x;
+ lastRxY = rxY;
+ lastTxY = txY;
+
+ count++;
+ x = width() - int(step*(count+1));
+
+ }
+
+ QString TorTX = QString("Tor Tx: %1 ").arg(BytesPerSecToString(mUplBuffer[*mPtr]));
+ QString SysTX = QString("Sys Tx: %1 ").arg(BytesPerSecToString(sys_mUplBuffer[*sys_mPtr]));
+ QString TorRX = QString("Tor Rx: %1 ").arg(BytesPerSecToString(mDldBuffer[*mPtr]));
+ QString SysRX = QString("Sys Rx: %1 ").arg(BytesPerSecToString(sys_mDldBuffer[*sys_mPtr]));
+ //Paint Text Representation
+ QRect first = paint.boundingRect( rect(), Qt::AlignTop, TorTX);
+ first.moveLeft(first.width());
+ first.setWidth(paint.boundingRect( rect(), Qt::AlignTop, SysTX).width());
+ paint.setPen( Qt::red );
+ paint.drawText( first, Qt::AlignTop, SysTX);
+
+ first = paint.boundingRect( rect(), Qt::AlignBottom, TorRX);
+ first.moveLeft(first.width());
+ first.setWidth(paint.boundingRect( rect(), Qt::AlignTop, SysRX).width());
+ paint.setPen( Qt::green );
+ paint.drawText( first, Qt::AlignTop, SysRX);
+
+ }
+
+
+}
+
diff --git a/src/chart.h b/src/chart.h
new file mode 100644
index 0000000..8757261
--- /dev/null
+++ b/src/chart.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+* Copyright (C) 2006 - 2008 Robert Hogan *
+* robert@roberthogan.net *
+* Copyright (C) 2005 by Hugo Parente Lima *
+* hugo_pl@users.sourceforge.net *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the *
+* Free Software Foundation, Inc., *
+* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+***************************************************************************/
+
+#ifndef CHART_H
+#define CHART_H
+
+#include <qwidget.h>
+
+class QPaintEvent;
+
+class Chart : public QWidget {
+public:
+ Chart(QWidget* parent, const double* uploadBuffer, const double* downloadBuffer, int bufferSize, const int* ptr, const double* maxspeed, const double* sys_uploadBuffer, const double* sys_downloadBuffer, int sys_bufferSize, const int* sys_ptr, const double* sys_maxspeed, bool gotEth0);
+ QSize sizeHint() { return QSize(600, 25); }
+protected:
+ void paintEvent( QPaintEvent* ev );
+
+private:
+ const double* mUplBuffer;
+ const double* mDldBuffer;
+ const int mBufferSize;
+ const int* mPtr;
+ const double* mMaxSpeed;
+
+ const double* sys_mUplBuffer;
+ const double* sys_mDldBuffer;
+ const int sys_mBufferSize;
+ const int* sys_mPtr;
+ const double* sys_mMaxSpeed;
+ bool mGotEth0;
+};
+
+#endif
diff --git a/src/configdialog.cpp b/src/configdialog.cpp
new file mode 100644
index 0000000..55af9ab
--- /dev/null
+++ b/src/configdialog.cpp
@@ -0,0 +1,515 @@
+/***************************************************************************
+** $Id: configdialog.cpp,v 1.51 2008/07/31 19:56:25 hoganrobert Exp $
+* Copyright (C) 2006 - 2008 Robert Hogan *
+* robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+//Adapted from configdialog.cpp in amaroK:
+/***************************************************************************
+begin : 2004/02/07
+copyright : (C) Mark Kretschmann
+email : markey@web.de
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "configdialog.h"
+#include "konqueror.h"
+#include "firewallsproxies.h"
+#include "paranoia.h"
+#include "maxmin.h"
+#include "running.h"
+#include "torservers.h"
+#include "usability.h"
+#include "torkconfig.h"
+#include "server.h"
+#include "quickconfig.h"
+#include "hiddensrvs.h"
+#include "portsandnames.h"
+#include "tork.h"
+#include "crypto.h"
+#include "../config.h"
+
+#include <qcombobox.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qmessagebox.h>
+#include <qobjectlist.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qspinbox.h>
+#include <qtextcodec.h>
+#include <qtooltip.h>
+#include <qvbox.h>
+#include <qlistview.h>
+#include <qcheckbox.h>
+
+#include <kapplication.h> //kapp
+#include <kcombobox.h>
+#include <kiconloader.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <dcopref.h>
+#include <kconfig.h>
+#include <kmessagebox.h>
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// PUBLIC
+//////////////////////////////////////////////////////////////////////////////////////////
+
+TorkConfigDialog::TorkConfigDialog( QWidget *parent, const char* name, KConfigSkeleton *config )
+ : KConfigDialog( parent, name, config ),m_parent(parent)
+{
+ setWFlags( WDestructiveClose );
+
+ // IMPORTANT Don't simply change the page names, they are used as identifiers in other parts of the app.
+ m_firewallsproxies = new FirewallsProxies( 0, "Firewall/Censor Evasion" );
+ m_usability = new Usability( 0, "Usability" );
+ m_torservers = new TorServers( 0, "My Network View" );
+ m_maxmin = new MaxMin( 0, "My Server Bandwidth" );
+ m_running = new Running( 0, "My Tor Client" );
+ m_myserver = new MyServer( this, "My Tor Server" );
+ m_myhidden = new MyHidden( 0, "My Hidden" );
+ m_quickconfig = new QuickConfig( 0, "Quick Configure" );
+ m_konq = new Konq( 0, "Konqueror" );
+ m_filtertable = new FilterTable( 0, "FailSafe" );
+
+ // add pages
+ addPage( m_quickconfig, i18n( "Quick Configure" ), "cache", i18n( "Quick Configuration" ) );
+#ifndef LIVECD
+ addPage( m_konq, i18n( "Konqueror" ), "tork_konqueror_play", i18n( "Konqueror and Privacy Proxy" ) );
+#endif
+
+#ifndef LIVECD
+ addPage( m_running, i18n( "My Tor Client" ), "launch", i18n( "Configure My Client" ) );
+#endif
+ addPage( m_firewallsproxies, i18n( "Firewall/Censor Evasion" ), "proxy", i18n( "Configure Firewalls Proxies" ) );
+
+ if (TorkConfig::advancedMode()){
+#ifndef LIVECD
+#ifdef USE_FAILSAFE
+ addPage( m_filtertable, i18n( "FailSafe" ), "gv", i18n( "Configure FailSafe Settings" ) );
+#endif
+#endif
+ addPage( m_usability, i18n( "Usability" ), "idea", i18n( "Configure Usability" ) );
+ }
+ if ((!TorkConfig::excludeNodes().isEmpty()) ||
+ (!TorkConfig::exitNodes().isEmpty())){
+ addPage( m_torservers, i18n( "My Network View" ), "network",
+ i18n( "Configure My Network View" ) );
+ }
+ if (!TorkConfig::clientOnly()){
+ addPage( m_myserver, i18n( "My Tor Server" ), "system", i18n( "Configure My Server" ) );
+ addPage( m_maxmin, i18n( "My Server Bandwidth" ), "filter", i18n( "Configure My Bandwidth" ) );
+ }
+ if (!TorkConfig::hiddenServices().isEmpty())
+ addPage( m_myhidden, i18n( "My Hidden Services" ), "tork_agent",
+ i18n( "Configure My Hidden Services" ) );
+
+
+ QObjectList *list = queryList( "QLabel", "infoPixmap" );
+ for( QObject *label = list->first(); label; label = list->next() )
+ static_cast<QLabel*>(label)->setPixmap( QMessageBox::standardIcon( QMessageBox::Information ) );
+ delete list;
+
+ //stop KFont Requesters getting stupidly large
+ list = queryList( "QLabel", "m_sampleLabel" );
+ for( QObject *label = list->first(); label; label = list->next() )
+ static_cast<QLabel*>(label)->setMaximumWidth( 250 );
+ delete list;
+
+ connect( m_usability->LongLivedPorts, SIGNAL( selectionChanged() ), this, SLOT( enableApply() ) );
+ connect( m_torservers->ExitNodes, SIGNAL( selectionChanged() ), this, SLOT( enableApply() ) );
+ connect( m_torservers->ExcludeNodes, SIGNAL( selectionChanged() ), this, SLOT( enableApply() ) );
+ connect( m_torservers->MapAddress, SIGNAL( selectionChanged() ), this, SLOT( enableApply() ) );
+ connect( m_torservers->AllowUnverifiedNodes, SIGNAL( selectionChanged() ), this, SLOT( enableApply() ) );
+ connect( m_firewallsproxies->ReachableAddresses, SIGNAL( selectionChanged() ), this, SLOT( enableApply() ) );
+ connect( m_filtertable->FilterRules, SIGNAL( selectionChanged() ), this, SLOT( enableApply() ) );
+ connect( m_running->SOCKSPolicy, SIGNAL( selectionChanged() ), this, SLOT( enableApply() ) );
+ connect( m_running->SOCKSBindAddressMany, SIGNAL( selectionChanged() ), this, SLOT( enableApply() ) );
+ connect( m_running->PushAdd, SIGNAL( clicked() ), this, SLOT( enableApply() ) );
+ connect( m_running->PushAdd2, SIGNAL( clicked() ), this, SLOT( enableApply() ) );
+ connect( m_myserver->kcfg_ClientOnly, SIGNAL( toggled(bool) ), this, SLOT( showServerOpts(bool) ) );
+ connect( m_usability->TrackHostExits, SIGNAL( selectionChanged() ), this, SLOT( enableApply() ) );
+ connect( m_usability->PushAdd, SIGNAL( clicked() ), this, SLOT( enableApply() ) );
+
+ connect( m_quickconfig, SIGNAL( configChanged(const int &) ), this, SLOT( showHidePages(const int &) ) );
+ //connect( m_usability, SIGNAL(settingsChanged()), SLOT(updateButtons()) );
+
+ // Always apply settings when OK or Apply is pressed.
+ //connect( this, SIGNAL(settingsChanged()), this,
+ // SLOT(updateCustomSettings()) );
+ connect( this, SIGNAL(okClicked()), this,
+ SLOT(updateCustomSettings()) );
+ connect( this, SIGNAL(applyClicked()), this,
+ SLOT(updateCustomSettings()) );
+ connect( this, SIGNAL(updateServerButton( )), parent,
+ SLOT(updateServerButton( )) );
+
+ connect( m_firewallsproxies, SIGNAL(uncensorSelected( bool )), parent,
+ SLOT(toggleServerButton( bool )) );
+
+ if (TorkConfig::currentTorVersion().left(3) == "0.1"){
+ m_filtertable->setEnabled(false);
+ }
+ showHidePages(m_quickconfig->QuickConfigure->currentItem());
+
+}
+
+void TorkConfigDialog::showHidePages( const int &type )
+{
+ switch (type) {
+ case 0 : //Tor client and server with default settings
+ case 1 : //Tor client and relay server with default settings
+ case 2 : //Tor client and relay server with default settings
+ case 3 : //Tor client and relay server with default settings
+ case 4 : //Tor client and relay server with default settings
+ m_running->setEnabled(false);
+ m_usability->setEnabled(false);
+ m_torservers->setEnabled(false);
+ m_maxmin->setEnabled(false);
+ m_firewallsproxies->setEnabled(true);
+ m_myserver->setEnabled(false);
+ break;
+ case 5 : //Use custom settings
+ case 6 : //Use custom settings
+ case 7 : //Use custom settings
+ m_running->setEnabled(true);
+ m_usability->setEnabled(true);
+ m_torservers->setEnabled(true);
+ m_maxmin->setEnabled(true);
+ m_firewallsproxies->setEnabled(true);
+ m_myserver->ServerInfo->setEnabled(!TorkConfig::clientOnly());
+ break;
+
+ }
+
+ show();
+
+}
+
+TorkConfigDialog::~TorkConfigDialog()
+{
+ emit updateServerButton( );
+}
+
+void TorkConfigDialog::showServerOpts( bool state)
+{
+ m_myserver->ServerInfo->setEnabled(!state);
+}
+
+
+/** Show page by object name */
+void TorkConfigDialog::showPage( const QCString& page )
+{
+ for( uint index = 0; index < m_pageList.count(); index++ ) {
+ if ( m_pageList[index]->name() == page ) {
+ KConfigDialog::showPage( index );
+ return;
+ }
+ }
+}
+
+/** Reimplemented from KConfigDialog */
+void TorkConfigDialog::addPage( QWidget *page, const QString &itemName, const QString &pixmapName, const QString &header, bool manage )
+{
+ // Add the widget pointer to our list, for later reference
+ m_pageList << page;
+
+ KConfigDialog::addPage( page, itemName, pixmapName, header, manage );
+}
+
+
+void TorkConfigDialog::enableApply()
+{
+ enableButtonApply(true);
+}
+
+void TorkConfigDialog::updateCustomSettings()
+{
+
+ kdDebug() << "applied config" << endl;
+
+ //When settings are changed in the config dialog, this is called
+ //to update all possibly changed values and apply them to Tor.
+
+ //QListViews need to be handled outside of kconfigxt
+ TorkConfig::setQuickConfigure( m_quickconfig->QuickConfigure->currentItem() );
+
+ TorkConfig::setAccountingStart(m_myserver->AccountingStart->currentText());
+// TorkConfig::setStatusFetchPeriodUnit(m_torservers->StatusFetchPeriodUnit->currentText());
+// TorkConfig::setDirFetchPeriodUnit(m_torservers->DirFetchPeriodUnit->currentText());
+
+ //Unverified Servers
+ if ( m_torservers->AllowUnverifiedNodes->childCount() > 0 ) {
+ QStringList v_allowUnverifiedNodes;
+ QListViewItemIterator it( m_torservers->AllowUnverifiedNodes, QListViewItemIterator::Selected );
+ while ( it.current() ) {
+ v_allowUnverifiedNodes.append(it.current()->text(0));
+ ++it;
+ }
+ TorkConfig::setAllowUnverifiedNodes( v_allowUnverifiedNodes );
+ }
+
+ //Friendly Servers
+ if ( m_torservers->MapAddress->childCount() > 0 ) {
+ QStringList v_mapAddress;
+ QListViewItemIterator it( m_torservers->MapAddress );
+ while ( it.current() ) {
+ QString s_mapAddress = it.current()->text(0) + " " + it.current()->text(0) + "." +
+ it.current()->text(1) + "." + it.current()->text(2);
+ v_mapAddress.append(s_mapAddress);
+ ++it;
+ }
+ TorkConfig::setMapAddress( v_mapAddress );
+ }else
+ TorkConfig::setMapAddress( "" );
+
+ //Exclude Countries
+ QStringList cclist;
+ for (unsigned int index = 0; index != m_torservers->CountryList->count(); ++index){
+ cclist.append(m_torservers->ccode(m_torservers->CountryList->item(index)->text()));
+ }
+ TorkConfig::setExcludeCountries(cclist);
+
+// Preferred Countries
+// cclist.clear();
+// for (unsigned int index = 0; index != m_torservers->PreferredCountryList->count(); ++index){
+// cclist.append(m_torservers->ccode(m_torservers->PreferredCountryList->item(index)->text()));
+// }
+// TorkConfig::setPreferredCountries(cclist);
+
+ //Enemy Servers
+ if ( m_torservers->ExcludeNodes->childCount() > 0 ) {
+ QStringList v_excludeNodes;
+ QStringList v_excludeServersHistory;
+ QListViewItemIterator it( m_torservers->ExcludeNodes );
+ while ( it.current() ) {
+ v_excludeNodes.append("$"+getFPFromFPDigest(it.current()->text(2)));
+ v_excludeServersHistory.append(it.current()->text(1) + "-" +
+ it.current()->text(2) + "-" + it.current()->text(3));
+ ++it;
+ }
+ TorkConfig::setExcludeNodes( v_excludeNodes );
+ TorkConfig::setExcludeServersHistory( v_excludeServersHistory );
+ }else{
+ TorkConfig::setExcludeNodes( QStringList() );
+ TorkConfig::setExcludeServersHistory( QStringList() );
+ }
+
+ //Exit Servers
+ if ( m_torservers->ExitNodes->childCount() > 0 ) {
+ QStringList v_exitNodes;
+ QStringList v_includeServersHistory;
+ QListViewItemIterator it( m_torservers->ExitNodes );
+ while ( it.current() ) {
+ v_exitNodes.append("$"+getFPFromFPDigest(it.current()->text(2)));
+ v_includeServersHistory.append(it.current()->text(1) + "-" +
+ it.current()->text(2) + "-" + it.current()->text(3));
+
+ ++it;
+ }
+ TorkConfig::setExitNodes( v_exitNodes );
+ TorkConfig::setIncludeServersHistory( v_includeServersHistory );
+ }else{
+ TorkConfig::setExitNodes( QStringList() );
+ TorkConfig::setIncludeServersHistory( QStringList() );
+ }
+
+ //Family Servers
+ if ( m_myserver->MyFamily->childCount() > 0 ) {
+ QStringList v_myFamily;
+ QListViewItemIterator it( m_myserver->MyFamily, QListViewItemIterator::Selected );
+ while ( it.current() ) {
+ v_myFamily.append(it.current()->text(1) + "-" +
+ it.current()->text(2) + "-" + it.current()->text(3));
+ ++it;
+ }
+ TorkConfig::setMyFamily( v_myFamily );
+ }else{
+ TorkConfig::setMyFamily( QStringList() );
+ }
+
+ //Track Host Exits
+ if ( m_usability->TrackHostExits->childCount() > 0 ) {
+ QStringList v_trackHostExits;
+ QListViewItemIterator it( m_usability->TrackHostExits );
+ while ( it.current() ) {
+ v_trackHostExits.append(it.current()->text(0));
+ ++it;
+ }
+ TorkConfig::setTrackHostExits( v_trackHostExits );
+ }else
+ TorkConfig::setTrackHostExits( "" );
+
+ //Long Lived Ports
+ if ( m_usability->LongLivedPorts->childCount() > 0 ) {
+ QStringList v_longLivedPorts;
+ QListViewItemIterator it( m_usability->LongLivedPorts, QListViewItemIterator::Selected );
+ while ( it.current() ) {
+ int i;
+ for (i = 0; _port_name[i].port; ++i) {
+ portsandnames_t *pics = &_port_name[i];
+ if (it.current()->text(0) == pics->name){
+ v_longLivedPorts.append(pics->port);
+ }
+ }
+
+ ++it;
+ }
+ TorkConfig::setLongLivedPorts( v_longLivedPorts );
+ }
+
+ //Socks Bind Addresses
+ if ( m_running->SOCKSBindAddressMany->childCount() > 0 ) {
+ QStringList v_sOCKSBindAddressMany;
+ QListViewItemIterator it( m_running->SOCKSBindAddressMany );
+ while ( it.current() ) {
+ QString s_sOCKSBindAddressMany = it.current()->text(0) + ":" + it.current()->text(1);
+ v_sOCKSBindAddressMany.append(s_sOCKSBindAddressMany);
+ ++it;
+ }
+ TorkConfig::setSOCKSBindAddressMany( v_sOCKSBindAddressMany );
+ }else
+ TorkConfig::setSOCKSBindAddressMany( "" );
+
+ //Exit Policy
+ if ( m_myserver->ExitPolicy->childCount() > 0 ) {
+ QStringList v_exitPolicy;
+ QListViewItemIterator it( m_myserver->ExitPolicy );
+ while ( it.current() ) {
+ QString s_exitPolicy = it.current()->text(0) + " " + it.current()->text(1) + ":" + it.current()->text(2);
+ v_exitPolicy.append(s_exitPolicy);
+ ++it;
+ }
+ TorkConfig::setExitPolicy( v_exitPolicy );
+ }else
+ TorkConfig::setExitPolicy( "" );
+
+ //Socks Policy
+ if ( m_running->SOCKSPolicy->childCount() > 0 ) {
+ QStringList v_sOCKSPolicy;
+ QListViewItemIterator it( m_running->SOCKSPolicy );
+ while ( it.current() ) {
+ QString s_sOCKSPolicy = it.current()->text(0) + " " + it.current()->text(1) + ":" + it.current()->text(2);
+ v_sOCKSPolicy.append(s_sOCKSPolicy);
+ ++it;
+ }
+ TorkConfig::setSOCKSPolicy( v_sOCKSPolicy );
+ }else
+ TorkConfig::setSOCKSPolicy( "" );
+
+ //Filter Rules
+ if ( m_filtertable->FilterRules->childCount() > 0 ) {
+ QStringList v_filterRules;
+ QListViewItemIterator it( m_filtertable->FilterRules );
+ while ( it.current() ) {
+ QString s_filterRules = it.current()->text(0) + "%:%" + it.current()->text(1)+ "%:%" + it.current()->text(2);
+ v_filterRules.append(s_filterRules);
+ ++it;
+ }
+ TorkConfig::setFilterRules( v_filterRules );
+ }else
+ TorkConfig::setFilterRules( "" );
+
+ //Reachable Address
+ if ( m_firewallsproxies->ReachableAddresses->childCount() > 0 ) {
+ QStringList v_reachableAddresses;
+ QListViewItemIterator it( m_firewallsproxies->ReachableAddresses );
+ while ( it.current() ) {
+ QString s_reachableAddresses = "*:" + it.current()->text(0);
+ v_reachableAddresses.append(s_reachableAddresses);
+ ++it;
+ }
+ TorkConfig::setReachableAddresses( v_reachableAddresses );
+ }else
+ TorkConfig::setReachableAddresses( "" );
+
+ //Bridge Addresses
+ if ( m_firewallsproxies->Bridge->childCount() > 0 ) {
+ QStringList v_bridges;
+ QListViewItemIterator it( m_firewallsproxies->Bridge );
+ while ( it.current() ) {
+ QString s_bridges = it.current()->text(0) + ":" + it.current()->text(1)
+ + " " + it.current()->text(2);
+ v_bridges.append(s_bridges);
+ ++it;
+ }
+ TorkConfig::setBridge( v_bridges );
+ }else
+ TorkConfig::setBridge( QStringList() );
+
+ //Hidden Services
+// if ( m_myhidden->servicesList->childCount() > 0 ) {
+// QStringList v_hiddenServices;
+// QListViewItemIterator it( m_myhidden->servicesList );
+// while ( it.current() ) {
+// QString s_hiddenServices = it.current()->text(0) + "\n" + it.current()->text(1)
+// + "\n" + it.current()->text(2) + "\n" + it.current()->text(3)
+// + "\n" + it.current()->text(4)+ "\n" + it.current()->text(5);
+// v_hiddenServices.append(s_hiddenServices);
+// ++it;
+// }
+// TorkConfig::setHiddenServices( v_hiddenServices );
+// }else
+// TorkConfig::setHiddenServices( "" );
+
+ //Bandwidth Slots
+ if ( m_maxmin->timedBandwidthList->childCount() > 0 ) {
+ QStringList v_bandwidthSlots;
+ QListViewItemIterator it( m_maxmin->timedBandwidthList );
+ while ( it.current() ) {
+ QString s_bandwidthSlots = it.current()->text(0) + "\n" + it.current()->text(1)
+ + "\n" + it.current()->text(2) + "\n" + it.current()->text(3)
+ + "\n" + it.current()->text(4);
+ v_bandwidthSlots.append(s_bandwidthSlots);
+ ++it;
+ }
+ TorkConfig::setBandwidthSlots( v_bandwidthSlots );
+ }else
+ TorkConfig::setBandwidthSlots( "" );
+
+ // If we are to use bridges then TunnelDirConns must be set as well.
+ if (m_firewallsproxies->kcfg_UseBridges->isChecked())
+ TorkConfig::setTunnelDirConns(true);
+ else
+ TorkConfig::setTunnelDirConns(false);
+
+ TorkConfig::writeConfig();
+
+
+ //If you're going to disable this again, explain why here. You have a crap
+ //memory.
+ //emit settingsChanged();
+ static_cast<tork*>(m_parent)->applySettingsToRunningTor();
+}
+
+
+
+
+#include "configdialog.moc"
diff --git a/src/configdialog.h b/src/configdialog.h
new file mode 100644
index 0000000..7bb145e
--- /dev/null
+++ b/src/configdialog.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+* Copyright (C) 2006 - 2008 Robert Hogan *
+* robert@roberthogan.net *
+begin : 2004/02/07
+copyright : (C) Mark Kretschmann
+email : markey@web.de
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef TORKCONFIGDIALOG_H
+#define TORKCONFIGDIALOG_H
+
+
+#include <qmap.h>
+#include <qvaluelist.h>
+#include <kconfigdialog.h>
+
+class QComboBox;
+class QGroupBox;
+class QVBox;
+
+class TorkConfigDialog : public KConfigDialog
+{
+ Q_OBJECT
+
+ public:
+ TorkConfigDialog( QWidget *parent, const char* name, KConfigSkeleton *config );
+ ~TorkConfigDialog();
+
+ void addPage( QWidget *page, const QString &itemName, const QString &pixmapName,
+ const QString &header=QString::null, bool manage=true);
+
+ void showPage( const QCString& page );
+ class QuickConfig *m_quickconfig;
+ public slots:
+ void showServerOpts(bool state);
+ signals:
+ void updateServerButton( );
+ private slots:
+ void updateCustomSettings();
+ void enableApply();
+ void showHidePages( const int &);
+ private:
+ class FirewallsProxies *m_firewallsproxies;
+ class FilterTable *m_filtertable;
+ class MaxMin *m_maxmin;
+ class Usability *m_usability;
+ class TorServers *m_torservers;
+ class Running *m_running;
+ class MyServer *m_myserver;
+ class MyHidden *m_myhidden;
+ class Konq *m_konq;
+
+ QValueList<QWidget*> m_pageList;
+ QMap<QString, QString> m_pluginName;
+ QMap<QString, QString> m_pluginTorkName;
+
+ QWidget* m_parent;
+};
+
+
+#endif // TORKCONFIGDIALOG_H
diff --git a/src/constants.h b/src/constants.h
new file mode 100644
index 0000000..8f633b2
--- /dev/null
+++ b/src/constants.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef BTCONSTANTS_H
+#define BTCONSTANTS_H
+
+namespace bt
+{
+ typedef unsigned long long Uint64;
+ typedef unsigned long Uint32;
+ typedef unsigned short Uint16;
+ typedef unsigned char Uint8;
+
+ typedef long long Int64;
+ typedef long Int32;
+ typedef short Int16;
+ typedef char Int8;
+
+ const Uint32 MAX_MSGLEN = 9 + 131072;
+ const Uint16 MIN_PORT = 6881;
+ const Uint16 MAX_PORT = 6889;
+ const Uint32 MAX_PIECE_LEN = 16384;
+
+ const Uint8 CHOKE = 0;
+ const Uint8 UNCHOKE = 1;
+ const Uint8 INTERESTED = 2;
+ const Uint8 NOT_INTERESTED = 3;
+ const Uint8 HAVE = 4;
+ const Uint8 BITFIELD = 5;
+ const Uint8 REQUEST = 6;
+ const Uint8 PIECE = 7;
+ const Uint8 CANCEL = 8;
+}
+
+
+#endif
diff --git a/src/crashhandler.cpp b/src/crashhandler.cpp
new file mode 100644
index 0000000..5e072e6
--- /dev/null
+++ b/src/crashhandler.cpp
@@ -0,0 +1,293 @@
+/***************************************************************************
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * Copyright (C) 2005 Max Howell <max.howell@methylblue.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "tork.h"
+#include "torkconfig.h"
+#include "crashhandler.h"
+
+#include <kapplication.h> //invokeMailer()
+#include <kdebug.h> //kdBacktrace()
+#include <kdeversion.h>
+#include <klocale.h>
+#include <ktempfile.h>
+
+#include <qfile.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+#include <qglobal.h> //qVersion()
+
+#include <cstdio> //popen, fread
+#include <iostream>
+#include <sys/types.h> //pid_t
+#include <sys/wait.h> //waitpid
+#include <unistd.h> //write, getpid
+
+
+
+
+
+namespace torK
+{
+ #if 0
+ class CrashHandlerWidget : public KDialog {
+ public:
+ CrashHandlerWidget();
+ };
+ #endif
+
+ static QString
+ runCommand( const QCString &command )
+ {
+ static const uint SIZE = 40960; //40 KiB
+ static char stdoutBuf[ SIZE ] = {0};
+
+ std::cout << "Running: " << command << std::endl;
+
+ FILE *process = ::popen( command, "r" );
+ if ( process )
+ {
+ stdoutBuf[ std::fread( static_cast<void*>( stdoutBuf ), sizeof(char), SIZE-1, process ) ] = '\0';
+ ::pclose( process );
+ }
+ return QString::fromLocal8Bit( stdoutBuf );
+ }
+
+ void
+ Crash::crashHandler( int /*signal*/ )
+ {
+ // we need to fork to be able to get a
+ // semi-decent bt - I dunno why
+ const pid_t pid = ::fork();
+
+ if( pid < 0 )
+ {
+ std::cout << "forking crash reporter failed\n";
+ // continuing now can't do no good
+ _exit( 1 );
+ }
+ else if ( pid == 0 )
+ {
+ // we are the child process (the result of the fork)
+ std::cout << "TorK is crashing...\n";
+
+ QString subject = TORK_VERSION " ";
+ QString body = i18n(
+ "TorK has crashed! We are terribly sorry about this :(\n\n"
+ "But, all is not lost! You could potentially help us fix the crash. "
+ "Information describing the crash is below, so just click send, "
+ "or if you have time, write a brief description of how the crash happened first.\n\n"
+ "Many thanks.\n\n" );
+ body += i18n( "\n\n\n\n\n\n"
+ "The information below is to help the developers identify the problem, "
+ "please do not modify it.\n\n\n\n" );
+
+
+ body += "======== DEBUG INFORMATION =======\n"
+ "Version: " TORK_VERSION "\n"
+ "Build date: " __DATE__ "\n"
+ "CC version: " __VERSION__ "\n" //assuming we're using GCC
+ "KDElibs: " KDE_VERSION_STRING "\n"
+ "Qt: %2\n"
+ "CPU count: %6\n";
+
+ QString cpucount = "unknown";
+#ifdef __linux__
+ QString line;
+ uint cpuCount = 0;
+ QFile cpuinfo( "/proc/cpuinfo" );
+ if ( cpuinfo.open( IO_ReadOnly ) ) {
+ while ( cpuinfo.readLine( line, 20000 ) != -1 ) {
+ if ( line.startsWith( "processor" ) ) {
+ ++cpuCount;
+ }
+ }
+ }
+ cpucount = QString::number( cpuCount );
+#endif
+
+
+ body = body.arg( qVersion() )
+ .arg( cpucount );
+
+ #ifdef NDEBUG
+ body += "NDEBUG: true";
+ #endif
+ body += "\n";
+
+ /// obtain the backtrace with gdb
+
+ KTempFile temp;
+ temp.setAutoDelete( true );
+
+ const int handle = temp.handle();
+
+// QCString gdb_command_string =
+// "file tork\n"
+// "attach " + QCString().setNum( ::getppid() ) + "\n"
+// "bt\n" "echo \\n\n"
+// "thread apply all bt\n";
+
+ const QCString gdb_batch =
+ "bt\n"
+ "echo \\n\\n\n"
+ "bt full\n"
+ "echo \\n\\n\n"
+ "echo ==== (gdb) thread apply all bt ====\\n\n"
+ "thread apply all bt\n";
+
+ ::write( handle, gdb_batch, gdb_batch.length() );
+ ::fsync( handle );
+
+ // so we can read stderr too
+ ::dup2( fileno( stdout ), fileno( stderr ) );
+
+
+ QCString gdb;
+ gdb = "gdb --nw -n --batch -x ";
+ gdb += temp.name().latin1();
+ gdb += " tork ";
+ gdb += QCString().setNum( ::getppid() );
+
+ QString bt = runCommand( gdb );
+
+ /// clean up
+ bt.remove( "(no debugging symbols found)..." );
+ bt.remove( "(no debugging symbols found)\n" );
+ bt.replace( QRegExp("\n{2,}"), "\n" ); //clean up multiple \n characters
+ bt.stripWhiteSpace();
+
+ /// analyze usefulness
+ bool useful = true;
+ const QString fileCommandOutput = runCommand( "file `which tork`" );
+
+ if( fileCommandOutput.find( "not stripped", false ) == -1 )
+ subject += "[___stripped]"; //same length as below
+ else
+ subject += "[NOTstripped]";
+
+ if( !bt.isEmpty() ) {
+ const int invalidFrames = bt.contains( QRegExp("\n#[0-9]+\\s+0x[0-9A-Fa-f]+ in \\?\\?") );
+ const int validFrames = bt.contains( QRegExp("\n#[0-9]+\\s+0x[0-9A-Fa-f]+ in [^?]") );
+ const int totalFrames = invalidFrames + validFrames;
+
+ if( totalFrames > 0 ) {
+ const double validity = double(validFrames) / totalFrames;
+ subject += QString("[validity: %1]").arg( validity, 0, 'f', 2 );
+ if( validity <= 0.5 ) useful = false;
+ }
+ subject += QString("[frames: %1]").arg( totalFrames, 3 /*padding*/ );
+
+ if( bt.find( QRegExp(" at \\w*\\.cpp:\\d+\n") ) >= 0 )
+ subject += "[line numbers]";
+ }
+ else
+ useful = false;
+
+
+ std::cout << subject.latin1() << std::endl;
+
+
+ //TODO -fomit-frame-pointer buggers up the backtrace, so detect it
+ //TODO -O optimization can rearrange execution and stuff so show a warning for the developer
+ //TODO pass the CXXFLAGS used with the email
+
+ if( useful ) {
+ body += "==== file `which tork` =======\n";
+ body += fileCommandOutput + "\n\n";
+ body += "==== (gdb) bt =====================\n";
+ body += bt + "\n\n";
+ body += "==== kdBacktrace() ================\n";
+ body += kdBacktrace();
+
+ //TODO startup notification
+ kapp->invokeMailer(
+ /*to*/ "tork-backtraces@lists.sf.net",
+ /*cc*/ QString(),
+ /*bcc*/ QString(),
+ /*subject*/ subject,
+ /*body*/ body,
+ /*messageFile*/ QString(),
+ /*attachURLs*/ QStringList(),
+ /*startup_id*/ "" );
+ }
+ else {
+ std::cout << i18n( "\nTorK has crashed! We are terribly sorry about this :(\n\n"
+ "But, all is not lost! Perhaps an upgrade is already available "
+ "which fixes the problem. Please check your distribution's software repository.\n" ).local8Bit();
+ }
+
+ //_exit() exits immediately, otherwise this
+ //function is called repeatedly ad finitum
+ ::_exit( 255 );
+ }
+
+ else {
+ // we are the process that crashed
+
+ ::alarm( 0 );
+
+ // wait for child to exit
+ ::waitpid( pid, NULL, 0 );
+ ::_exit( 253 );
+ }
+ }
+}
+
+
+#if 0
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qvbox.h>
+#include <kdialog.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+#include <kstandarddirs.h>
+
+torK::CrashHandlerWidget::CrashHandlerWidget()
+{
+ QBoxLayout *layout = new QHBoxLayout( this, 18, 12 );
+
+ {
+ QBoxLayout *lay = new QVBoxLayout( layout );
+ QLabel *label = new QLabel( this );
+ label->setPixmap( locate( "data", "drkonqi/pics/konqi.png" ) );
+ label->setFrameStyle( QFrame::Plain | QFrame::Box );
+ lay->add( label );
+ lay->addItem( new QSpacerItem( 3, 3, QSizePolicy::Minimum, QSizePolicy::Expanding ) );
+ }
+
+ layout = new QVBoxLayout( layout, 6 );
+
+ layout->add( new QLabel( /*i18n*/(
+ "<p>" "TorK has crashed! We are terribly sorry about this :("
+ "<p>" "However you now have an opportunity to help us fix this crash so that it doesn't "
+ "happen again! Click <b>Send Email</b> and TorK will prepare an email that you "
+ "can send to us that contains information about the crash, and we'll try to fix it "
+ "as soon as possible."
+ "<p>" "Thanks for choosing TorK.<br>" ), this ) );
+
+ layout = new QHBoxLayout( layout, 6 );
+
+ layout->addItem( new QSpacerItem( 6, 6, QSizePolicy::Expanding ) );
+ layout->add( new KPushButton( KGuiItem( i18n("Send Email"), "mail_send" ), this, "email" ) );
+ layout->add( new KPushButton( KStdGuiItem::close(), this, "close" ) );
+
+ static_cast<QPushButton*>(child("email"))->setDefault( true );
+
+ connect( child( "email" ), SIGNAL(clicked()), SLOT(accept()) );
+ connect( child( "close" ), SIGNAL(clicked()), SLOT(reject()) );
+
+ setCaption( i18n("Crash Handler") );
+ setFixedSize( sizeHint() );
+}
+#endif
diff --git a/src/crashhandler.h b/src/crashhandler.h
new file mode 100644
index 0000000..34c2c68
--- /dev/null
+++ b/src/crashhandler.h
@@ -0,0 +1,34 @@
+/***************************************************************************
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * Copyright (C) 2005 Max Howell <max.howell@methylblue.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef CRASH_H
+#define CRASH_H
+
+#include <kcrash.h> //for main.cpp
+
+namespace torK
+{
+ /**
+ * @author Max Howell
+ * @short The Amarok crash-handler
+ *
+ * I'm not entirely sure why this had to be inside a class, but it
+ * wouldn't work otherwise *shrug*
+ */
+ class Crash
+ {
+ public:
+ static void crashHandler( int signal );
+ };
+}
+
+#endif
diff --git a/src/crypto.cpp b/src/crypto.cpp
new file mode 100644
index 0000000..a47e19d
--- /dev/null
+++ b/src/crypto.cpp
@@ -0,0 +1,816 @@
+/***************************************************************************
+** $Id: crypto.cpp,v 1.11 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ *
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ ***************************************************************************/
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. */
+/* See Tor LICENSE for licensing information */
+/* $Id: crypto.cpp,v 1.11 2008/07/31 19:56:26 hoganrobert Exp $ */
+#include <string.h>
+#include <kdebug.h>
+#include "crypto.h"
+#include "../config.h"
+
+#ifndef USE_OPENSSL
+#include <gnutls/gnutls.h>
+#include <gcrypt.h>
+#else
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/opensslv.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/rsa.h>
+#include <openssl/dh.h>
+#include <openssl/conf.h>
+#endif
+
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <limits.h>
+
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdint.h>
+
+/* random numbers */
+
+/* This is how much entropy OpenSSL likes to add right now, so maybe it will
+ * work for us too. */
+#define ADD_ENTROPY 32
+
+
+typedef QMap<QString, QString> servermap;
+servermap serverTofp_identity;
+servermap fp_identityToServer;
+
+/** Intermediate information about the digest of a stream of data. */
+struct crypto_digest_env_t {
+#ifndef USE_OPENSSL
+ gcry_md_hd_t d;
+#else
+ SHA_CTX d;
+#endif
+};
+
+
+void clearServers()
+{
+ serverTofp_identity.clear();
+ fp_identityToServer.clear();
+}
+
+QString fp_identity(const QString &server)
+{
+
+ return serverTofp_identity[server];
+}
+
+QString server(const QString &fp_identity)
+{
+
+ return fp_identityToServer[fp_identity];
+}
+
+void storeServer(const QString &server,const QString &fp_identity)
+{
+
+ serverTofp_identity[server] = fp_identity;
+ fp_identityToServer[fp_identity] = server;
+
+}
+
+
+
+QString getFPDigestFromFP(const QString &fp)
+{
+ char identity64[BASE64_DIGEST_LEN+1];
+ char digest[DIGEST_LEN];
+ QString FP = fp;
+ FP.replace("$","");
+
+ base16_decode(digest, DIGEST_LEN, FP, strlen(FP));
+ digest_to_base64(identity64, digest);
+ return identity64;
+}
+
+QString getNickNameFromFPDigest(const QString &fpdigest)
+{
+
+ return fp_identityToServer[fpdigest];
+
+}
+
+QString getNickNameFromFP(const QString &fp)
+{
+ QString fpdigest = getFPDigestFromFP(fp);
+
+ return fp_identityToServer[fpdigest];
+}
+
+
+
+QString getFPFromNickName(const QString &nickname)
+{
+ char buf[256];
+ char hexdigest[HEX_DIGEST_LEN+1];
+
+ QString fp = serverTofp_identity[nickname];
+
+ if (fp.isEmpty())
+ return QString();
+ if (!digest_from_base64(buf, fp))
+ base16_encode(hexdigest, HEX_DIGEST_LEN+1, buf, DIGEST_LEN);
+
+ return hexdigest;
+}
+
+QString getFPFromFPDigest(const QString &fp)
+{
+ char buf[256];
+ char hexdigest[HEX_DIGEST_LEN+1];
+
+ digest_from_base64(buf, fp);
+ base16_encode(hexdigest, HEX_DIGEST_LEN+1, buf, DIGEST_LEN);
+
+ return hexdigest;
+}
+
+
+/** Seed OpenSSL's random number generator with bytes from the
+ * operating system. Return 0 on success, -1 on failure.
+ */
+int
+crypto_seed_rng(void)
+{
+ char buf[ADD_ENTROPY];
+ int rand_poll_status;
+
+ /* local variables */
+ static const char *filenames[] = {
+ "/dev/srandom", "/dev/urandom", "/dev/random", NULL
+ };
+ int fd;
+ int i, n;
+
+ rand_poll_status = 0;
+
+ for (i = 0; filenames[i]; ++i) {
+ fd = open(filenames[i], O_RDONLY, 0);
+ if (fd<0) continue;
+ n = read_all(fd, buf, sizeof(buf), 0);
+ close(fd);
+ if (n != sizeof(buf)) {
+ return -1;
+ }
+#ifndef USE_OPENSSL
+ gcry_create_nonce(buf, sizeof(buf));
+#else
+ RAND_seed(buf, sizeof(buf));
+#endif
+ return 0;
+ }
+
+ return rand_poll_status ? 0 : -1;
+}
+
+/** Write n bytes of strong random data to <b>to</b>. Return 0 on
+ * success, -1 on failure.
+ */
+int
+crypto_rand(char *to, size_t n)
+{
+ assert(to);
+#ifndef USE_OPENSSL
+ gcry_randomize((unsigned char*)to,n,GCRY_STRONG_RANDOM);
+ return 0;
+#else
+ int r;
+ r = RAND_bytes((unsigned char*)to, n);
+ return (r == 1) ? 0 : -1;
+#endif
+}
+
+/** Return a pseudorandom integer, chosen uniformly from the values
+ * between 0 and max-1. */
+int
+crypto_rand_int(unsigned int max)
+{
+ unsigned int val;
+ unsigned int cutoff;
+ assert(max < UINT_MAX);
+ assert(max > 0); /* don't div by 0 */
+
+ /* We ignore any values that are >= 'cutoff,' to avoid biasing the
+ * distribution with clipping at the upper end of unsigned int's
+ * range.
+ */
+ cutoff = UINT_MAX - (UINT_MAX%max);
+ while (1) {
+ crypto_rand((char*)&val, sizeof(val));
+ if (val < cutoff)
+ return val % max;
+ }
+}
+
+/** Generates a pseudorandom string of length <b>len</b> containing printable
+ * ASCII characters from the range '!' (0x21) to '~' (0x7e). */
+QString
+crypto_rand_string(int len)
+{
+ QString str;
+ Q_ASSERT(len >= 0);
+
+ for (int i = 0; i < len; i++)
+ str += QChar('!' + crypto_rand_int('~'-'!'+1));
+ return str;
+}
+
+/** Read from <b>fd</b> to <b>buf</b>, until we get <b>count</b> bytes
+ * or reach the end of the file. <b>isSocket</b> must be 1 if fd
+ * was returned by socket() or accept(), and 0 if fd was returned by
+ * open(). Return the number of bytes read, or -1 on error. Only use
+ * if fd is a blocking fd. */
+int
+read_all(int fd, char *buf, size_t count, int isSocket)
+{
+ size_t numread = 0;
+ int result;
+
+ if (count > SIZE_T_CEILING)
+ return -1;
+
+ while (numread != count) {
+ if (isSocket)
+ result = recv(fd, buf+numread, count-numread, 0);
+ else
+ result = read(fd, buf+numread, count-numread);
+ if (result<0)
+ return -1;
+ else if (result == 0)
+ break;
+ numread += result;
+ }
+ return numread;
+}
+
+
+int
+digest_from_base64(char *digest, const char *d64)
+{
+
+ char buf_in[BASE64_DIGEST_LEN+3];
+ char buf[256];
+ if (strlen(d64) != BASE64_DIGEST_LEN)
+ return -1;
+ memcpy(buf_in, d64, BASE64_DIGEST_LEN);
+#ifndef USE_OPENSSL
+ memcpy(buf_in+BASE64_DIGEST_LEN, "=\0", 2);
+ if (base64_decode(buf, sizeof(buf), buf_in, strlen(buf_in)) != DIGEST_LEN)
+ return -1;
+#else
+ memcpy(buf_in+BASE64_DIGEST_LEN, "=\n\0", 3);
+ if (base64_decode(buf, sizeof(buf), buf_in, strlen(buf_in)) != DIGEST_LEN)
+ return -1;
+
+#endif
+
+
+ memcpy(digest, buf, DIGEST_LEN);
+ return 0;
+}
+
+int
+base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
+{
+
+#ifndef USE_OPENSSL
+// gnutls_datum_t data_in;
+ base64_decodestate state;
+#else
+ EVP_ENCODE_CTX ctx;
+ int len;
+#endif
+ int ret;
+
+ /* 64 bytes of input -> *up to* 48 bytes of output.
+ Plus one more byte, in case I'm wrong.
+ */
+ if (destlen < ((srclen/64)+1)*49)
+ return -1;
+ if (destlen > SIZE_T_CEILING)
+ return -1;
+
+#ifndef USE_OPENSSL
+/* data_in.data = (unsigned char*)src;
+ data_in.size = srclen;*/
+ base64_init_decodestate(&state);
+#endif
+
+#ifndef USE_OPENSSL
+// if (gnutls_srp_base64_decode(&data_in, dest, &destlen)
+// == GNUTLS_E_SHORT_MEMORY_BUFFER)
+// kdDebug() << "error decoding " << endl;
+// kdDebug() << "decoded " << dest << "len" << destlen << endl;
+
+ ret = base64_decode_block(src, srclen, dest, &state);
+ return ret;
+#else
+ EVP_DecodeInit(&ctx);
+ EVP_DecodeUpdate(&ctx, (unsigned char*)dest, &len,
+ (unsigned char*)src, srclen);
+ EVP_DecodeFinal(&ctx, (unsigned char*)dest, &ret);
+ ret += len;
+ return ret;
+#endif
+
+}
+
+int
+digest_to_base64(char *d64, const char *digest)
+{
+ char buf[256];
+ base64_encode(buf, sizeof(buf), digest, DIGEST_LEN);
+ buf[BASE64_DIGEST_LEN] = '\0';
+ memcpy(d64, buf, BASE64_DIGEST_LEN+1);
+ return 0;
+}
+
+int
+base64_encode(char *dest, size_t destlen, const char *src, size_t srclen)
+{
+#ifndef USE_OPENSSL
+// gnutls_datum_t data_in;
+ base64_encodestate state;
+#else
+ EVP_ENCODE_CTX ctx;
+ int len;
+#endif
+ int ret;
+
+
+ /* 48 bytes of input -> 64 bytes of output plus newline.
+ Plus one more byte, in case I'm wrong.
+ */
+ if (destlen < ((srclen/48)+1)*66)
+ return -1;
+ if (destlen > SIZE_T_CEILING)
+ return -1;
+
+#ifndef USE_OPENSSL
+/* data_in.data = (unsigned char*)src;
+ data_in.size = srclen;*/
+ base64_init_encodestate(&state);
+#endif
+
+#ifndef USE_OPENSSL
+// gnutls_srp_base64_encode(&data_in, dest, &destlen);
+// kdDebug() << "encoded " << dest << "len" << destlen << endl;
+// return destlen;
+ ret = base64_encode_block(src, srclen, dest, &state);
+ ret += base64_encode_blockend(dest+ret, &state);
+
+ return ret;
+#else
+ EVP_EncodeInit(&ctx);
+ EVP_EncodeUpdate(&ctx, (unsigned char*)dest, &len,
+ (unsigned char*)src, srclen);
+ EVP_EncodeFinal(&ctx, (unsigned char*)(dest+len), &ret);
+ ret += len;
+ return ret;
+#endif
+
+}
+
+static const char HEX_DIGITS[] = "0123456789ABCDEFabcdef";
+
+static int hex_decode_digit(char c)
+{
+ const char *cp;
+ int n;
+ cp = strchr(HEX_DIGITS, c);
+ if (!cp)
+ return -1;
+ n = cp-HEX_DIGITS;
+ if (n<=15)
+ return n; /* digit or uppercase */
+ else
+ return n-6; /* lowercase */
+}
+
+
+void
+base16_encode(char *dest, size_t destlen, const char *src, size_t srclen)
+{
+ const char *end;
+ char *cp;
+
+ assert(destlen >= srclen*2+1);
+ assert(destlen < SIZE_T_CEILING);
+
+ cp = dest;
+ end = src+srclen;
+ while (src<end) {
+ sprintf(cp,"%02X",*(const uint8_t*)src);
+ ++src;
+ cp += 2;
+ }
+ *cp = '\0';
+}
+
+
+int
+base16_decode(char *dest, size_t destlen, const char *src, size_t srclen)
+{
+ const char *end;
+ int v1,v2;
+ if ((srclen % 2) != 0)
+ return -1;
+ if (destlen < srclen/2 || destlen > SIZE_T_CEILING)
+ return -1;
+ end = src+srclen;
+ while (src<end) {
+ v1 = hex_decode_digit(*src);
+ v2 = hex_decode_digit(*(src+1));
+ if (v1<0||v2<0)
+ return -1;
+ *(uint8_t*)dest = (v1<<4)|v2;
+ ++dest;
+ src+=2;
+ }
+ return 0;
+}
+
+
+/** Deallocate a digest object.
+ */
+void
+crypto_free_digest_env(crypto_digest_env_t *digest)
+{
+ free(digest);
+}
+
+/** Allocate and return a new digest object.
+ */
+ crypto_digest_env_t *
+crypto_new_digest_env(void)
+{
+ crypto_digest_env_t *r;
+ r = (crypto_digest_env_t *)malloc(sizeof(crypto_digest_env_t));
+
+#ifndef USE_OPENSSL
+ gcry_md_open(&r->d,GCRY_MD_SHA1, 0);
+#else
+ SHA1_Init(&r->d);
+#endif
+ return r;
+}
+
+/** Compute the hash of the data that has been passed to the digest
+ * object; write the first out_len bytes of the result to <b>out</b>.
+ * <b>out_len</b> must be \<= DIGEST_LEN.
+ */
+void
+crypto_digest_get_digest(crypto_digest_env_t *digest,
+ char *out, size_t out_len)
+{
+
+#ifdef USE_OPENSSL
+ static unsigned char r[DIGEST_LEN];
+#else
+ unsigned char* r;
+#endif
+ assert(digest);
+ assert(out);
+ assert(out_len <= DIGEST_LEN);
+#ifdef USE_OPENSSL
+ SHA_CTX tmpctx;
+#endif
+
+#ifndef USE_OPENSSL
+ r = gcry_md_read(digest->d, GCRY_MD_SHA1);
+ memcpy(out, r, out_len);
+ gcry_md_close(digest->d);
+#else
+ /* memcpy into a temporary ctx, since SHA1_Final clears the context */
+ memcpy(&tmpctx, &digest->d, sizeof(SHA_CTX));
+ SHA1_Final(r, &tmpctx);
+ memcpy(out, r, out_len);
+#endif
+
+}
+
+/** Add <b>len</b> bytes from <b>data</b> to the digest object.
+ */
+void
+crypto_digest_add_bytes(crypto_digest_env_t *digest, const char *data,
+ size_t len)
+{
+ assert(digest);
+ assert(data);
+ /* Using the SHA1_*() calls directly means we don't support doing
+ * sha1 in hardware. But so far the delay of getting the question
+ * to the hardware, and hearing the answer, is likely higher than
+ * just doing it ourselves. Hashes are fast.
+ */
+#ifndef USE_OPENSSL
+ gcry_md_write(digest->d, data, len);
+#else
+ SHA1_Update(&digest->d, (void*)data, len);
+#endif
+
+}
+
+/** Implement RFC2440-style iterated-salted S2K conversion: convert the
+ * <b>secret_len</b>-byte <b>secret</b> into a <b>key_out_len</b> byte
+ * <b>key_out</b>. As in RFC2440, the first 8 bytes of s2k_specifier
+ * are a salt; the 9th byte describes how much iteration to do.
+ * Does not support <b>key_out_len</b> &gt; DIGEST_LEN.
+ */
+void
+secret_to_key(char *key_out, size_t key_out_len, const char *secret,
+ size_t secret_len, const char *s2k_specifier)
+{
+ crypto_digest_env_t *d;
+ uint8_t c;
+ size_t count;
+ char *tmp;
+ assert(key_out_len < SIZE_T_CEILING);
+
+#define EXPBIAS 6
+ c = s2k_specifier[8];
+ count = ((uint32_t)16 + (c & 15)) << ((c >> 4) + EXPBIAS);
+#undef EXPBIAS
+
+ assert(key_out_len <= DIGEST_LEN);
+
+ d = crypto_new_digest_env();
+ tmp = (char *)malloc(8+secret_len);
+ memcpy(tmp,s2k_specifier,8);
+ memcpy(tmp+8,secret,secret_len);
+ secret_len += 8;
+ while (count) {
+ if (count >= secret_len) {
+ crypto_digest_add_bytes(d, tmp, secret_len);
+ count -= secret_len;
+ } else {
+ crypto_digest_add_bytes(d, tmp, count);
+ count = 0;
+ }
+ }
+ crypto_digest_get_digest(d, key_out, key_out_len);
+ free(tmp);
+ crypto_free_digest_env(d);
+}
+
+
+/** Entry point for password hashing: take the desired password from
+ * the command line, and print its salted hash to stdout. **/
+QString hashPassword(const char* secret)
+{
+
+ char output[256];
+ char key[S2K_SPECIFIER_LEN+DIGEST_LEN];
+
+ crypto_rand(key, S2K_SPECIFIER_LEN-1);
+ key[S2K_SPECIFIER_LEN-1] = (uint8_t)96; /* Hash 64 K of data. */
+ secret_to_key(key+S2K_SPECIFIER_LEN, DIGEST_LEN,
+ secret, strlen(secret),
+ key);
+ base16_encode(output, sizeof(output), key, sizeof(key));
+ kdDebug() << output << endl;
+ return output;
+}
+
+/*
+cdecoder.c - c source to a base64 decoding algorithm implementation
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+int base64_decode_value(char value_in)
+{
+ static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
+ static const char decoding_size = sizeof(decoding);
+ value_in -= 43;
+ if (value_in < 0 || value_in > decoding_size) return -1;
+ return decoding[(int)value_in];
+}
+
+void base64_init_decodestate(base64_decodestate* state_in)
+{
+ state_in->step = step_a;
+ state_in->plainchar = 0;
+}
+
+int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in)
+{
+ const char* codechar = code_in;
+ char* plainchar = plaintext_out;
+ char fragment;
+
+ *plainchar = state_in->plainchar;
+
+ switch (state_in->step)
+ {
+ while (1)
+ {
+ case step_a:
+ do {
+ if (codechar == code_in+length_in)
+ {
+ state_in->step = step_a;
+ state_in->plainchar = *plainchar;
+ return plainchar - plaintext_out;
+ }
+ fragment = (char)base64_decode_value(*codechar++);
+ } while (fragment < 0);
+ *plainchar = (fragment & 0x03f) << 2;
+ case step_b:
+ do {
+ if (codechar == code_in+length_in)
+ {
+ state_in->step = step_b;
+ state_in->plainchar = *plainchar;
+ return plainchar - plaintext_out;
+ }
+ fragment = (char)base64_decode_value(*codechar++);
+ } while (fragment < 0);
+ *plainchar++ |= (fragment & 0x030) >> 4;
+ *plainchar = (fragment & 0x00f) << 4;
+ case step_c:
+ do {
+ if (codechar == code_in+length_in)
+ {
+ state_in->step = step_c;
+ state_in->plainchar = *plainchar;
+ return plainchar - plaintext_out;
+ }
+ fragment = (char)base64_decode_value(*codechar++);
+ } while (fragment < 0);
+ *plainchar++ |= (fragment & 0x03c) >> 2;
+ *plainchar = (fragment & 0x003) << 6;
+ case step_d:
+ do {
+ if (codechar == code_in+length_in)
+ {
+ state_in->step = step_d;
+ state_in->plainchar = *plainchar;
+ return plainchar - plaintext_out;
+ }
+ fragment = (char)base64_decode_value(*codechar++);
+ } while (fragment < 0);
+ *plainchar++ |= (fragment & 0x03f);
+ }
+ }
+ /* control should not reach here */
+ return plainchar - plaintext_out;
+}
+
+/*
+cencoder.c - c source to a base64 encoding algorithm implementation
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+
+const int CHARS_PER_LINE = 72;
+
+void base64_init_encodestate(base64_encodestate* state_in)
+{
+ state_in->step = step_A;
+ state_in->result = 0;
+ state_in->stepcount = 0;
+}
+
+char base64_encode_value(char value_in)
+{
+ static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ if (value_in > 63) return '=';
+ return encoding[(int)value_in];
+}
+
+int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
+{
+ const char* plainchar = plaintext_in;
+ const char* const plaintextend = plaintext_in + length_in;
+ char* codechar = code_out;
+ char result;
+ char fragment;
+
+ result = state_in->result;
+
+ switch (state_in->step)
+ {
+ while (1)
+ {
+ case step_A:
+ if (plainchar == plaintextend)
+ {
+ state_in->result = result;
+ state_in->step = step_A;
+ return codechar - code_out;
+ }
+ fragment = *plainchar++;
+ result = (fragment & 0x0fc) >> 2;
+ *codechar++ = base64_encode_value(result);
+ result = (fragment & 0x003) << 4;
+ case step_B:
+ if (plainchar == plaintextend)
+ {
+ state_in->result = result;
+ state_in->step = step_B;
+ return codechar - code_out;
+ }
+ fragment = *plainchar++;
+ result |= (fragment & 0x0f0) >> 4;
+ *codechar++ = base64_encode_value(result);
+ result = (fragment & 0x00f) << 2;
+ case step_C:
+ if (plainchar == plaintextend)
+ {
+ state_in->result = result;
+ state_in->step = step_C;
+ return codechar - code_out;
+ }
+ fragment = *plainchar++;
+ result |= (fragment & 0x0c0) >> 6;
+ *codechar++ = base64_encode_value(result);
+ result = (fragment & 0x03f) >> 0;
+ *codechar++ = base64_encode_value(result);
+
+ ++(state_in->stepcount);
+ if (state_in->stepcount == CHARS_PER_LINE/4)
+ {
+ *codechar++ = '\n';
+ state_in->stepcount = 0;
+ }
+ }
+ }
+ /* control should not reach here */
+ return codechar - code_out;
+}
+
+int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
+{
+ char* codechar = code_out;
+
+ switch (state_in->step)
+ {
+ case step_B:
+ *codechar++ = base64_encode_value(state_in->result);
+/* *codechar++ = '=';
+ *codechar++ = '=';*/
+ break;
+ case step_C:
+ *codechar++ = base64_encode_value(state_in->result);
+/* *codechar++ = '=';*/
+ break;
+ case step_A:
+ break;
+ }
+/* *codechar++ = '\n';*/
+
+ return codechar - code_out;
+}
diff --git a/src/crypto.h b/src/crypto.h
new file mode 100644
index 0000000..92c6094
--- /dev/null
+++ b/src/crypto.h
@@ -0,0 +1,183 @@
+/* $Id: crypto.h,v 1.9 2008/07/31 19:56:26 hoganrobert Exp $ */
+/* Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ *
+ * Most of this file is derived from Tor and Vidalia.
+ *
+ * The licences for both follow:
+ *
+ * Vidalia is distributed under the following license:
+ *
+ * Copyright (C) 2007, Matt Edman, Justin Hipple
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * * * *
+ *
+ * Pseudorandom number generation support in this file is derived from
+ * Tor's crypto.[ch]. Tor is distributed under this license.
+ *
+ * Copyright (c) 2001-2004, Roger Dingledine
+ * Copyright (c) 2004-2007, Roger Dingledine, Nick Mathewson
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the names of the copyright owners nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ****************************************************************/
+
+
+/**
+ * \file crypto.h
+ *
+ * \brief Headers for crypto.c
+ **/
+
+#define BASE64_DIGEST_LEN 27
+#define DIGEST_LEN 20
+#define HEX_DIGEST_LEN 40
+#define SIZE_T_CEILING (sizeof(char)<<(sizeof(size_t)*8 - 1))
+
+#define S2K_SPECIFIER_LEN 9
+
+#include <qmap.h>
+#include <qstring.h>
+
+typedef struct crypto_digest_env_t crypto_digest_env_t;
+
+
+int read_all(int fd, char *buf, size_t count, int isSocket);
+int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen);
+int digest_from_base64(char *digest, const char *d64);
+void base16_encode(char *dest, size_t destlen, const char *src, size_t srclen);
+int digest_to_base64(char *d64, const char *digest);
+int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen);
+int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
+
+QString getFPDigestFromFP(const QString &fp);
+QString getNickNameFromFPDigest(const QString &fpdigest);
+QString getNickNameFromFP(const QString &fp);
+QString getFPFromNickName(const QString &nickname);
+QString getFPFromFPDigest(const QString &fp);
+void storeServer(const QString &server,const QString &fp_identity);
+void clearServers();
+QString fp_identity(const QString &server);
+QString server(const QString &fp_identity);
+QString hashPassword(const char* secret);
+
+QString crypto_rand_string(int len);
+
+/* random numbers */
+int crypto_seed_rng(void);
+int crypto_rand(char *to, size_t n);
+int crypto_rand_int(unsigned int max);
+
+
+
+/*
+cdecode.h - c header for a base64 decoding algorithm
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+
+typedef enum
+{
+ step_a, step_b, step_c, step_d
+} base64_decodestep;
+
+typedef struct
+{
+ base64_decodestep step;
+ char plainchar;
+} base64_decodestate;
+
+void base64_init_decodestate(base64_decodestate* state_in);
+
+int base64_decode_value(char value_in);
+
+int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in);
+
+
+/*
+cencode.h - c header for a base64 encoding algorithm
+
+This is part of the libb64 project, and has been placed in the public domain.
+For details, see http://sourceforge.net/projects/libb64
+*/
+
+
+typedef enum
+{
+ step_A, step_B, step_C
+} base64_encodestep;
+
+typedef struct
+{
+ base64_encodestep step;
+ char result;
+ int stepcount;
+} base64_encodestate;
+
+void base64_init_encodestate(base64_encodestate* state_in);
+
+char base64_encode_value(char value_in);
+
+int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
+
+int base64_encode_blockend(char* code_out, base64_encodestate* state_in);
+
+
+
diff --git a/src/dcoptork.h b/src/dcoptork.h
new file mode 100644
index 0000000..4f4c6d6
--- /dev/null
+++ b/src/dcoptork.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ ** $Id: dcoptork.h,v 1.5 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef DCOPTORK_H
+#define DCOPTORK_H
+
+#include <dcopobject.h>
+
+class DCOPTork : virtual public DCOPObject
+{
+ K_DCOP
+ k_dcop:
+
+
+ virtual void startEverything() = 0;
+ virtual void stopTor() = 0;
+ virtual void toggleKDESetting() = 0;
+ virtual bool getKDESetting() = 0;
+ virtual void anonymousEmail() = 0;
+ virtual void anonymousFirefox() = 0;
+ virtual void anonymizedFirefox(const QString & url) = 0;
+ virtual void anonymizedOpera(const QString & url) = 0;
+ virtual void anonymousOpera() = 0;
+ virtual void anonymousKonversation() = 0;
+ virtual void anonymousGaim() = 0;
+ virtual void anonymousPidgin() = 0;
+ virtual void anonymousKonsole() = 0;
+ virtual void anonymousKopete() = 0;
+
+};
+
+#endif // DCOPDEMOIFACE_H
diff --git a/src/dndlistview.cpp b/src/dndlistview.cpp
new file mode 100644
index 0000000..5ddfaf7
--- /dev/null
+++ b/src/dndlistview.cpp
@@ -0,0 +1,346 @@
+/***************************************************************************
+* Copyright (C) 2006 - 2008 Robert Hogan *
+* robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "dndlistview.h"
+#include "torkconfig.h"
+#include "kdebug.h"
+#include <qapplication.h>
+#include <qheader.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include <qsimplerichtext.h>
+#include <qpainter.h>
+
+DndListView::DndListView( QWidget * parent, const char * name, WFlags f ) :
+ QListView( parent, name, f ), oldCurrent( 0 ),
+ dropItem( 0 ), mousePressed( FALSE ),m_recentDrop( FALSE)
+{
+
+ setAllColumnsShowFocus( TRUE );
+ //setResizeMode( QListView::AllColumns );
+ setSelectionMode( QListView::Extended );
+
+ setAcceptDrops( TRUE );
+ viewport()->setAcceptDrops( TRUE );
+
+}
+
+
+//static const int autoopenTime = 750;
+
+
+void DndListView::contentsDragEnterEvent( QDragEnterEvent *e )
+{
+
+ setSelectionMode( QListView::Single );
+
+ if ( !QTextDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+
+ oldCurrent = currentItem();
+
+ QListViewItem *i = itemAt( contentsToViewport(e->pos()) );
+ if ( i ) {
+ dropItem = i;
+/* autoopen_timer->start( autoopenTime );*/
+ }
+}
+
+
+void DndListView::contentsDragMoveEvent( QDragMoveEvent *e )
+{
+ if ( !QTextDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+ QPoint vp = contentsToViewport( ( (QDragMoveEvent*)e )->pos() );
+ QListViewItem *i = itemAt( vp );
+
+ //!(e->source() == this) &&
+
+ if ((QString(this->name()).contains("circuitList")) &&
+ (QString(e->source()->name()).contains("serverList"))) {
+
+ if ( i ){
+ setSelected( i, TRUE );
+ if ( i != dropItem ) {
+ dropItem = i;
+ }
+ }
+ e->accept();
+ }else if ((QString(this->name()).contains("circuitList")) &&
+ (QString(e->source()->name()).contains("circuitList"))) {
+ if ( i ){
+ setSelected( i, TRUE );
+ if ( i != dropItem ) {
+ dropItem = i;
+ }
+ }
+ e->accept();
+ }else if ((QString(this->name()).contains("circuitList")) &&
+ (QString(e->source()->name()).contains("ORList"))) {
+ if ( i ){
+ setSelected( i, TRUE );
+ if ( i != dropItem ) {
+ dropItem = i;
+ }
+ }
+ e->accept();
+ }else if ((QString(this->name()).contains("circuitList")) &&
+ (QString(e->source()->name()).contains("streamList"))) {
+ if ( i ){
+ setSelected( i, TRUE );
+ if ( i != dropItem ) {
+ dropItem = i;
+ }
+ }
+ e->accept();
+
+ }else {
+ e->ignore();
+ dropItem = 0;
+ }
+}
+
+void DndListView::contentsDragLeaveEvent( QDragLeaveEvent * )
+{
+/* autoopen_timer->stop();*/
+
+ dropItem = 0;
+
+ setCurrentItem( oldCurrent );
+ setSelected( oldCurrent, TRUE );
+
+ setSelectionMode( QListView::Extended );
+
+}
+
+void DndListView::contentsDropEvent( QDropEvent *e )
+{
+// autoopen_timer->stop();
+ m_recentDrop = true;
+ dropTimer = startTimer( 3000 );
+
+ setSelectionMode( QListView::Extended );
+
+ QString text;
+ if ( !QTextDrag::decode( e, text ) ) {
+ e->ignore();
+ return;
+ }
+
+ m_mousepos = e->pos() ;
+
+ QListViewItem *item = itemAt( contentsToViewport(e->pos()) );
+ if (QString(this->name()).contains("circuitList")){
+ e->accept();
+ if ( item ) {
+ if (QString(e->source()->name()).contains("serverList"))
+ emit extendCircuit(item->text(0),text,true);
+ else if (QString(e->source()->name()).contains("circuitList"))
+ emit extendCircuit(item->text(0),text, true);
+ else if (QString(e->source()->name()).contains("ORList"))
+ emit extendCircuit(item->text(0),text, false);
+ else if (QString(e->source()->name()).contains("streamList"))
+ emit attach(item->text(0),text);
+ } else{
+ if (QString(e->source()->name()).contains("serverList"))
+ emit createCircuit(text,true);
+ else if (QString(e->source()->name()).contains("ORList"))
+ emit createCircuit(text,false);
+ }
+ }else
+ e->ignore();
+
+}
+
+
+
+void DndListView::contentsMousePressEvent( QMouseEvent* e )
+{
+ QPoint p( contentsToViewport( e->pos() ) );
+ //QListViewItem *i = itemAt( p );
+/* if ( i ) {
+ // if the user clicked into the root decoration of the item, don't try to start a drag!
+ if ( p.x() > header()->cellPos( header()->mapToActual( 0 ) ) +
+ treeStepSize() * ( i->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ||
+ p.x() < header()->cellPos( header()->mapToActual( 0 ) ) ) {
+ presspos = e->pos();
+ mousePressed = TRUE;
+ }
+ }*/
+
+ if (e->button() == Qt::LeftButton){
+ presspos = e->pos();
+ mousePressed = TRUE;
+ }
+ QListView::contentsMousePressEvent( e );
+}
+
+void DndListView::contentsMouseMoveEvent( QMouseEvent* e )
+{
+ if ( mousePressed ) {
+ kdDebug() << "in mouse move drag" << endl;
+
+ mousePressed = FALSE;
+ //QListViewItem *item = itemAt( contentsToViewport(presspos) );
+
+ int column;
+ if (QString(this->name()).contains("circuitList"))
+ column = 2;
+ else if (QString(this->name()).contains("ORList"))
+ column = 1;
+ else if (QString(this->name()).contains("streamList"))
+ column = 0;
+ else
+ column = 2;
+
+ QString selectedItems;
+ QListViewItemIterator it(this, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (this->isSelected( it.current()))
+ selectedItems.append(it.current()->text(column)+" ");
+ ++it;
+ }
+ if (!selectedItems.isEmpty()){
+ selectedItems = selectedItems.stripWhiteSpace();
+ QDragObject *d = new QTextDrag( selectedItems, this );
+ d->dragCopy(); // do NOT delete d.
+ }
+
+ }else
+ QListView::contentsMouseMoveEvent( e );
+}
+
+void DndListView::contentsMouseReleaseEvent( QMouseEvent* e)
+{
+/* kdDebug() << "mouse released" << endl;*/
+ mousePressed = FALSE;
+ QListView::contentsMouseReleaseEvent(e);
+
+}
+
+void DndListView::mouseReleaseEvent( QMouseEvent* e)
+{
+/* kdDebug() << "mouse released" << endl;*/
+ mousePressed = FALSE;
+ QListView::mouseReleaseEvent(e);
+
+}
+
+QPoint DndListView::getMousePos()
+{
+ return m_mousepos;
+}
+
+void DndListView::timerEvent( QTimerEvent * )
+{
+ //if ( e->timerId() == dropTimer ) // stop showing date
+ m_recentDrop = false;
+ killTimer( dropTimer );
+ dropTimer = -1;
+}
+
+
+
+void
+DndListView::viewportPaintEvent( QPaintEvent *e )
+{
+ QListView::viewportPaintEvent( e );
+
+ if (!TorkConfig::displayBubble())
+ return;
+ // Superimpose bubble help
+ // Taken from mediabrowser.cpp in Amarok
+
+ if (( childCount() == 0 ) && (QString(this->name()).contains("streamList")))
+ {
+ QPainter p( viewport() );
+
+ QSimpleRichText t( i18n(
+ "<div align=center>"
+ "<h4>Almost Everything Is Clickable.</h4>"
+ "You can drag servers to create circuits. You can drag connections onto circuits "
+ " if you right-click here first. "
+ "You can right-click on servers to include/exclude them or their country from your "
+ "connections. Remember though: <b> messing with stuff is fun, but generally bad for "
+ "anonymity.</b>"
+ "</div>" ), QApplication::font() );
+
+ t.setWidth( width() - 50 );
+
+ const uint w = t.width() + 20;
+ const uint h = t.height() + 20;
+
+ p.setBrush( colorGroup().background() );
+ p.drawRoundRect( 15, 15, w, h, (8*200)/w, (8*200)/h );
+ t.draw( &p, 20, 20, QRect(), colorGroup() );
+ }
+}
+
+
+// QDragObject *DndListView::dragObject()
+// {
+// kdDebug() << "dragging item" << endl;
+// return new QTextDrag( currentItem()->text(0), this );
+// }
+
+
+// void DndListView::dragEnterEvent( QDragEnterEvent *evt )
+// {
+// kdDebug() << "drag enter event" << endl;
+// if ( QTextDrag::canDecode( evt ) )
+// evt->accept();
+// }
+//
+//
+// void DndListView::dropEvent( QDropEvent *evt )
+// {
+// QString text;
+//
+// if ( QTextDrag::decode( evt, text ) )
+// kdDebug() << text << endl;
+// }
+//
+//
+// void DndListView::contentsMousePressEvent( QMouseEvent *evt )
+// {
+// dragging = TRUE;
+// kdDebug() << "draggng mouse" << endl;
+// QListView::mousePressEvent( evt );
+//
+// }
+//
+//
+// void DndListView::contentsMouseMoveEvent( QMouseEvent * )
+// {
+// if ( dragging ) {
+// kdDebug() << "dragging" << endl;
+// QDragObject *d = new QTextDrag( currentItem()->text(0), this );
+// d->dragCopy(); // do NOT delete d.
+// dragging = FALSE;
+// }
+// }
+
+#include "dndlistview.moc"
diff --git a/src/dndlistview.h b/src/dndlistview.h
new file mode 100644
index 0000000..5e7c441
--- /dev/null
+++ b/src/dndlistview.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+* Copyright (C) 2006 - 2008 Robert Hogan *
+* robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#ifndef _DNDLISTVIEW_H_
+#define _DNDLISTVIEW_H_
+
+#include <qlistview.h>
+#include <qdragobject.h>
+
+class QDragEnterEvent;
+class QDragDropEvent;
+
+
+class DndListView : public QListView
+{
+Q_OBJECT
+
+public:
+ DndListView( QWidget * parent = 0, const char * name = 0, WFlags f = 0 );
+ QPoint m_mousepos;
+ QPoint getMousePos();
+ bool recentDropEvent() { return m_recentDrop; };
+ void contentsMouseReleaseEvent( QMouseEvent *e );
+
+protected:
+ void contentsDragEnterEvent( QDragEnterEvent *e );
+ void contentsDragMoveEvent( QDragMoveEvent *e );
+ void contentsDragLeaveEvent( QDragLeaveEvent *e );
+ void contentsDropEvent( QDropEvent *e );
+ void contentsMouseMoveEvent( QMouseEvent *e );
+ void contentsMousePressEvent( QMouseEvent *e );
+ void mouseReleaseEvent( QMouseEvent *e );
+ void timerEvent( QTimerEvent * );
+ void viewportPaintEvent( QPaintEvent *e );
+
+
+private:
+ QListViewItem *oldCurrent;
+ QListViewItem *dropItem;
+/* QTimer* autoopen_timer;*/
+ QPoint presspos;
+ bool mousePressed;
+ int dropTimer;
+ bool m_recentDrop;
+signals:
+
+ void attach(const QString &, const QString &);
+ void extendCircuit(const QString &, const QString &, bool);
+ void createCircuit(const QString &, bool);
+ void itemAdded(QListViewItem *);
+
+
+
+
+
+/* void dragEnterEvent( QDragEnterEvent *evt );
+ void dropEvent( QDropEvent *evt );
+ void contentsMousePressEvent( QMouseEvent *evt );
+ void contentsMouseMoveEvent( QMouseEvent * );*/
+// QDragObject *dragObject();
+// private:
+// bool dragging;
+
+
+};
+#endif // _TORKVIEW_H_
diff --git a/src/eventsrc b/src/eventsrc
new file mode 100644
index 0000000..a9a7bdb
--- /dev/null
+++ b/src/eventsrc
@@ -0,0 +1,11 @@
+[!Global!]
+IconName=tork
+Comment=Anonymity Notice
+
+[TorDisabled]
+Name=TorDisabled
+Comment=Anonymous Use of KDE/Konqueror Disabled
+#default_sound=k3b_success1.wav
+default_presentation=16
+# None = 0, Sound = 1, Messagebox = 2, Logfile = 4, Stderr = 8, PassivePopup = 16, Execute = 32
+
diff --git a/src/firewallsproxies.ui b/src/firewallsproxies.ui
new file mode 100644
index 0000000..f43bb31
--- /dev/null
+++ b/src/firewallsproxies.ui
@@ -0,0 +1,666 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>FirewallsProxies</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>FirewallsProxies</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>582</width>
+ <height>539</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>MyDialog1</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Evade Censorship</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kcfg_UseBridges</cstring>
+ </property>
+ <property name="text">
+ <string>My State or Service Provider Censors the Use of Tor</string>
+ </property>
+ </widget>
+ <spacer row="4" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>80</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton" row="2" column="1">
+ <property name="name">
+ <cstring>pushButton3</cstring>
+ </property>
+ <property name="text">
+ <string>Fetch Listings</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>You can fetch a list of servers from http://bridges.torproject.org</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>You can also fetch listings by emailing bridges@torproject.org from a gmail or yahoo account.</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>BridgePanel</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Restrictive Firewall Avoidance</string>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>pushBridgeAdd</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>462</x>
+ <y>191</y>
+ <width>72</width>
+ <height>23</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&amp;Add</string>
+ </property>
+ <property name="accel">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>BridgePort</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>296</x>
+ <y>192</y>
+ <width>57</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>FirewallLabel_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>31</y>
+ <width>177</width>
+ <height>150</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;Tor will only use the servers in the box to the right to communicate with the rest of the Tor network.&lt;/p&gt;
+&lt;p&gt;The servers are known as 'bridges'.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>BridgeAddress</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>194</x>
+ <y>192</y>
+ <width>95</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>BridgeKey</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>360</x>
+ <y>192</y>
+ <width>95</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Address</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Port</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Key (Optional)</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>Bridge</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>194</x>
+ <y>20</y>
+ <width>340</width>
+ <height>165</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget8</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Evade your firewall</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>kcfg_FascistFirewall</cstring>
+ </property>
+ <property name="text">
+ <string>My Firewall Only Lets Certain Ports Out</string>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="3" column="0">
+ <property name="name">
+ <cstring>Proxies</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>Proxies</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_HttpProxyAuthenticatorUserName</cstring>
+ </property>
+ <property name="inputMask">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="4" column="3">
+ <property name="name">
+ <cstring>kcfg_HttpsProxyAuthenticatorPassword</cstring>
+ </property>
+ <property name="inputMask">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel2_4_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>User Name:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="3" column="3">
+ <property name="name">
+ <cstring>kcfg_HttpsProxyPort</cstring>
+ </property>
+ <property name="maxValue">
+ <number>99999</number>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="3" column="1">
+ <property name="name">
+ <cstring>kcfg_HttpsProxyHost</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="3">
+ <property name="name">
+ <cstring>kcfg_HttpProxyAuthenticatorPassword</cstring>
+ </property>
+ <property name="inputMask">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;HTTPS Proxy&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="2">
+ <property name="name">
+ <cstring>textLabel2_4_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="2">
+ <property name="name">
+ <cstring>textLabel3_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="4" column="1">
+ <property name="name">
+ <cstring>kcfg_HttpsProxyAuthenticatorUserName</cstring>
+ </property>
+ <property name="inputMask">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel2_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Address:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>textLabel2_4_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_HttpProxyHost</cstring>
+ </property>
+ <property name="inputMask">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="3">
+ <property name="name">
+ <cstring>kcfg_HttpProxyPort</cstring>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Address:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel2_4_4</cstring>
+ </property>
+ <property name="text">
+ <string>User Name:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>kcfg_UseProxy</cstring>
+ </property>
+ <property name="text">
+ <string>I Use a Proxy to Access the Internet</string>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>Firewall</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Restrictive Firewall Avoidance</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>FirewallLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Prevent firewall time-outs by sending something every</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="0" column="1">
+ <column>
+ <property name="text">
+ <string>Port</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>ReachableAddresses</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>kcfg_KeepalivePeriod</cstring>
+ </property>
+ <property name="suffix">
+ <string> minutes</string>
+ </property>
+ <property name="specialValueText">
+ <string></string>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="2">
+ <property name="name">
+ <cstring>pushAdd</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add</string>
+ </property>
+ <property name="accel">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>Port</cstring>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>FirewallLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;Tor will only use the ports in the box to the right to communicate with the rest of the Tor network.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>pushAdd</sender>
+ <signal>clicked()</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>pushAdd_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>ReachableAddresses</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>ReachableAddresses_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_FascistFirewall</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>kcfg_FascistFirewall_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_UseProxy</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>kcfg_UseProxy_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_HttpProxyHost</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>kcfg_HttpProxyHost_textChanged(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_HttpProxyAuthenticatorUserName</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>kcfg_HttpProxyAuthenticatorUserName_textChanged(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_HttpProxyAuthenticatorPassword</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>kcfg_HttpProxyAuthenticatorPassword_textChanged(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_HttpProxyPort</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>kcfg_HttpProxyPort_valueChanged(int)</slot>
+ </connection>
+ <connection>
+ <sender>pushBridgeAdd</sender>
+ <signal>clicked()</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>pushBridgeAdd_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_UseBridges</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>kcfg_UseBridges_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>Bridge</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>Bridge_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>pushButton3</sender>
+ <signal>clicked()</signal>
+ <receiver>FirewallsProxies</receiver>
+ <slot>slotGetBridges()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">firewallsproxies.ui.h</include>
+</includes>
+<signals>
+ <signal>uncensorSelected( bool )</signal>
+</signals>
+<slots>
+ <slot>pushAdd_clicked()</slot>
+ <slot>ReachableAddresses_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotDeleteEntry()</slot>
+ <slot>kcfg_FascistFirewall_toggled( bool on )</slot>
+ <slot>kcfg_UseProxy_toggled( bool on )</slot>
+ <slot>kcfg_HttpProxyHost_textChanged( const QString &amp; text )</slot>
+ <slot>kcfg_HttpProxyPort_valueChanged( int text )</slot>
+ <slot>kcfg_HttpProxyAuthenticatorUserName_textChanged( const QString &amp; text )</slot>
+ <slot>kcfg_HttpProxyAuthenticatorPassword_textChanged( const QString &amp; text )</slot>
+ <slot>pushBridgeAdd_clicked()</slot>
+ <slot>kcfg_UseBridges_toggled( bool on )</slot>
+ <slot>Bridge_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotDeleteBridgesEntry()</slot>
+ <slot>slotGetBridges()</slot>
+ <slot>parseBridges()</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/firewallsproxies.ui.h b/src/firewallsproxies.ui.h
new file mode 100644
index 0000000..751b54c
--- /dev/null
+++ b/src/firewallsproxies.ui.h
@@ -0,0 +1,229 @@
+/***************************************************************************
+* Copyright (C) 2006 - 2008 Robert Hogan *
+* robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "torkconfig.h"
+#include <klocale.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <kdebug.h>
+#include <khtml_part.h>
+#include <dom/html_misc.h>
+#include <kmessagebox.h>
+
+KHTMLPart *filelist;
+
+void FirewallsProxies::init()
+{
+
+ filelist = new KHTMLPart();
+
+ QStringList existingMaps = TorkConfig::reachableAddresses();
+ QListViewItem *tm;
+ for ( QStringList::Iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString entry = (*it).section(":",0,0);
+ QString port = (*it).section(":",1,1);
+
+ tm = new QListViewItem(ReachableAddresses,port);
+ }
+
+ existingMaps = TorkConfig::bridge();
+ for ( QStringList::Iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString entry = (*it).section(":",0,0);
+ QString port = (*it).section(" ",0,0).section(":",1,1);
+ QString key = (*it).section(" ",1);
+
+ tm = new QListViewItem(Bridge,entry,port,key);
+ }
+
+ if (TorkConfig::currentTorVersion().left(3) == "0.1"){
+ tabWidget->removePage(tabWidget->page(0));
+ }
+
+}
+void FirewallsProxies::pushAdd_clicked()
+{
+ new QListViewItem(ReachableAddresses,Port->text());
+
+}
+
+
+
+void FirewallsProxies::ReachableAddresses_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( ReachableAddresses );
+
+ menu->clear();
+ menu->insertItem( "Delete Entry", this,SLOT(slotDeleteEntry()) );
+ menu->popup( point );
+
+}
+
+void FirewallsProxies::slotDeleteEntry( )
+{
+
+ QValueList<QListViewItem*> itemsToDelete;
+ QListViewItemIterator it(ReachableAddresses, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ itemsToDelete << it.current();
+ ++it;
+ }
+
+ for ( QValueList<QListViewItem*>::Iterator itt = itemsToDelete.begin();
+ itt != itemsToDelete.end(); ++itt ){
+ delete (*itt);
+ }
+
+}
+
+void FirewallsProxies::kcfg_FascistFirewall_toggled( bool on )
+{
+ Firewall->setEnabled(on);
+}
+
+void FirewallsProxies::kcfg_UseProxy_toggled( bool on)
+{
+ Proxies->setEnabled(on);
+}
+
+void FirewallsProxies::kcfg_HttpProxyHost_textChanged( const QString & text)
+{
+ kcfg_HttpsProxyHost->setText(text);
+}
+
+
+void FirewallsProxies::kcfg_HttpProxyPort_valueChanged( int text)
+{
+ kcfg_HttpsProxyPort->setValue(text);
+}
+
+
+void FirewallsProxies::kcfg_HttpProxyAuthenticatorUserName_textChanged( const QString & text)
+{
+ kcfg_HttpsProxyAuthenticatorUserName->setText(text);
+}
+
+
+void FirewallsProxies::kcfg_HttpProxyAuthenticatorPassword_textChanged( const QString & text)
+{
+ kcfg_HttpsProxyAuthenticatorPassword->setText(text);
+}
+
+
+
+
+void FirewallsProxies::pushBridgeAdd_clicked()
+{
+ new QListViewItem(Bridge,BridgeAddress->text(),BridgePort->text(),BridgeKey->text());
+
+}
+
+
+void FirewallsProxies::kcfg_UseBridges_toggled( bool on)
+{
+ BridgePanel->setEnabled(on);
+ emit uncensorSelected(on);
+}
+
+
+void FirewallsProxies::Bridge_contextMenuRequested( QListViewItem *, const QPoint & point, int )
+{
+ QPopupMenu *menu = new QPopupMenu( Bridge );
+
+ menu->clear();
+ menu->insertItem( "Delete Entry", this,SLOT(slotDeleteBridgesEntry()) );
+ menu->popup( point );
+
+}
+
+void FirewallsProxies::slotDeleteBridgesEntry( )
+{
+
+ QValueList<QListViewItem*> itemsToDelete;
+ QListViewItemIterator it(Bridge, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ itemsToDelete << it.current();
+ ++it;
+ }
+
+ for ( QValueList<QListViewItem*>::Iterator itt = itemsToDelete.begin();
+ itt != itemsToDelete.end(); ++itt ){
+ delete (*itt);
+ }
+
+}
+
+
+void FirewallsProxies::slotGetBridges( )
+{
+
+ connect( filelist, SIGNAL( completed() ), this,
+ SLOT( parseBridges() ) );
+
+ filelist->openURL("https://bridges.torproject.org");
+}
+
+void FirewallsProxies::parseBridges()
+{
+
+ disconnect( filelist, SIGNAL( completed() ), this,
+ SLOT( parseBridges() ) );
+
+ const DOM::HTMLCollection links = filelist->htmlDocument().all();
+ if (links.length() == 0){
+ KMessageBox::information (this,i18n( "Could not contact update server!" ));
+ return;
+ }
+
+
+ for (unsigned int j=0; j != links.length(); j++ ){
+ const DOM::Node linkNode = links.item( j );
+ if ( linkNode.isNull() || linkNode.nodeType() != DOM::Node::ELEMENT_NODE )
+ continue;
+
+ DOM::HTMLElement elem = static_cast<DOM::HTMLElement>( linkNode );
+ if (elem.getAttribute("id") == "bridges"){
+ QStringList bridges = QStringList::split("bridge ",elem.innerText().string());
+
+ for ( QStringList::Iterator it = bridges.begin(); it != bridges.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString entry = (*it).section(":",0,0);
+ QString port = (*it).section(" ",0,0).section(":",1,1);
+ QString key = (*it).section(" ",1);
+ if (((QListViewItem*) Bridge->findItem(key,2)) == 0)
+ new QListViewItem(Bridge,entry,port,key);
+ else
+ KMessageBox::information (this,i18n( "Already have server :%1" ).arg((*it)));
+ }
+
+
+ }
+ }
+}
+
+
diff --git a/src/functions.cpp b/src/functions.cpp
new file mode 100644
index 0000000..828222e
--- /dev/null
+++ b/src/functions.cpp
@@ -0,0 +1,202 @@
+/***************************************************************************
+ ** $Id: functions.cpp,v 1.14 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <qdatetime.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kdebug.h>
+#include <sys/time.h>
+#include <qdir.h>
+#include <cstdlib>
+
+#include "functions.h"
+
+
+namespace tk
+{
+ const double TO_KB = 1024.0;
+ const double TO_MEG = (1024.0 * 1024.0);
+ const double TO_GIG = (1024.0 * 1024.0 * 1024.0);
+
+ QString BytesToString(Uint64 bytes,int precision)
+ {
+ KLocale* loc = KGlobal::locale();
+ if (bytes >= 1024 * 1024 * 1024)
+ return i18n("%1 GB").arg(loc->formatNumber(bytes / TO_GIG,precision < 0 ? 2 : precision));
+ else if (bytes >= 1024*1024)
+ return i18n("%1 MB").arg(loc->formatNumber(bytes / TO_MEG,precision < 0 ? 1 : precision));
+ else if (bytes >= 1024)
+ return i18n("%1 KB").arg(loc->formatNumber(bytes / TO_KB,precision < 0 ? 1 : precision));
+ else
+ return i18n("%1 B").arg(bytes);
+ }
+
+ QString BytesPerSecToString(double bytes,int precision)
+ {
+ KLocale* loc = KGlobal::locale();
+ if (bytes >= 1024 * 1024 * 1024)
+ return i18n("%1 GB/s").arg(loc->formatNumber(bytes / TO_GIG,precision < 0 ? 2 : precision));
+ else if (bytes >= 1024*1024)
+ return i18n("%1 MB/s").arg(loc->formatNumber(bytes / TO_MEG,precision < 0 ? 1 : precision));
+ else if (bytes >= 1024)
+ return i18n("%1 KB/s").arg(loc->formatNumber(bytes / TO_KB,precision < 0 ? 1 : precision));
+ else
+ return i18n("%1 B/s").arg(loc->formatNumber(bytes,precision < 0 ? 1 : precision));
+ }
+
+ QString KBytesPerSecToString(double speed,int precision)
+ {
+ KLocale* loc = KGlobal::locale();
+ return i18n("%1 KB/s").arg(loc->formatNumber(speed,precision));
+ }
+
+
+ QString DurationToString(Uint32 nsecs)
+ {
+ KLocale* loc = KGlobal::locale();
+ QTime t;
+ int ndays = nsecs / 86400;
+ t = t.addSecs(nsecs % 86400);
+ QString s = loc->formatTime(t,true,true);
+ if (ndays > 0)
+ s = i18n("1 day ","%n days ",ndays) + s;
+
+ return s;
+ }
+
+ QString calcBW(const QStringList &bwlist, int num)
+ {
+
+ double totalbw = 0;
+ int numtmp=0;
+ for ( QStringList::ConstIterator it = bwlist.end(); it != bwlist.begin(); --it )
+ {
+ totalbw += (*it).toDouble();
+ numtmp++;
+ if (numtmp > num)
+ break;
+ }
+ double avgbw = totalbw / (900 * num);
+ return BytesPerSecToString(avgbw);
+ }
+
+}
+
+namespace bt
+{
+
+ void UpdateCurrentTime()
+ {
+ global_time_stamp = Now();
+ }
+
+ TimeStamp global_time_stamp = 0;
+
+ Uint64 Now()
+ {
+ struct timeval tv;
+ gettimeofday(&tv,0);
+ global_time_stamp = (Uint64)(tv.tv_sec * 1000 + tv.tv_usec * 0.001);
+ return global_time_stamp;
+ }
+
+}
+
+
+QString getFullLocation(const char *additionalPaths, const QString &name)
+{
+
+ // do not search one path twice
+ QStringList paths;
+ // get the environment path variable
+ paths = addPaths(getenv("PATH"));
+ paths += addPaths(additionalPaths);
+
+ QStringList::ConstIterator dirpath = paths.begin();
+ QStringList::ConstIterator end = paths.end();
+ for(; dirpath!=end; ++dirpath)
+ {
+ QDir dir = *dirpath;
+ if (!dir.exists()) continue;
+
+ QFile inf(*dirpath+'/'+name);
+ if (inf.exists())
+ return *dirpath+'/'+name;
+
+ }
+ return QString();
+}
+
+
+QStringList findPrograms(const QStringList &programList)
+{
+
+ // do not search one path twice
+ QStringList paths;
+ // get the environment path variable
+ paths = addPaths(getenv("PATH"));
+ QStringList tofind;
+ QStringList remaining;
+ QStringList finds;
+ QStringList::ConstIterator dirpath = paths.begin();
+ QStringList::ConstIterator end = paths.end();
+
+ tofind = programList;
+ remaining = tofind;
+ for(; dirpath!=end; ++dirpath)
+ {
+ QDir dir = *dirpath;
+ if (!dir.exists()) continue;
+
+ for ( QStringList::Iterator it = tofind.begin(); it != tofind.end(); ++it ){
+ QFile inf(*dirpath+'/'+*it);
+ if (inf.exists()){
+ finds.append(*it);
+ remaining.remove(*it);
+ }
+ }
+ tofind = remaining;
+ }
+
+ return finds;
+}
+
+
+QStringList addPaths(const char *env_path){
+
+ // do not search one path twice
+ QStringList paths;
+/* // get the environment path variable
+ char* env_path = getenv("PATH");*/
+ if( env_path ) {
+ QStringList env_pathList = QStringList::split(":", QString::fromLocal8Bit(env_path));
+ for( QStringList::const_iterator it = env_pathList.begin(); it != env_pathList.end(); ++it ) {
+ QString p = *it;
+ if( p[p.length()-1] == '/' )
+ p.truncate( p.length()-1 );
+ if( !paths.contains( p ) && !paths.contains( p + "/" ) )
+ paths.append(p);
+ }
+ }
+
+ return paths;
+}
diff --git a/src/functions.h b/src/functions.h
new file mode 100644
index 0000000..36b3f4c
--- /dev/null
+++ b/src/functions.h
@@ -0,0 +1,268 @@
+/***************************************************************************
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef FUNCTIONS_H
+#define FUNCTIONS_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qdir.h>
+#include "constants.h"
+#include <map>
+
+QString getFullLocation(const char *additionalPaths, const QString &name);
+
+QStringList findPrograms(const QStringList &programList);
+
+QStringList addPaths(const char *env_path);
+
+using namespace bt;
+namespace tk
+{
+
+ QString BytesToString(bt::Uint64 bytes,int precision = -1);
+ QString KBytesPerSecToString(double speed,int precision = 1);
+ QString BytesPerSecToString(double bytes,int precision = 1);
+ QString DurationToString(bt::Uint32 nsecs);
+ QString calcBW(const QStringList &bwlist, int num);
+
+ template<class T> int CompareVal(T a,T b)
+ {
+ if (a < b)
+ return -1;
+ else if (a > b)
+ return 1;
+ else
+ return 0;
+ }
+}
+
+namespace bt
+{
+ typedef Uint64 TimeStamp;
+
+ void UpdateCurrentTime();
+
+ extern TimeStamp global_time_stamp;
+
+ inline TimeStamp GetCurrentTime() {return global_time_stamp;}
+
+ TimeStamp Now();
+
+ /**
+ * @author Joris Guisson
+ * @brief Map of pointers
+ *
+ * A Map where the data is a pointer. The PtrMap has an autodeletion feature.
+ * When autodelete is on, every time we remove something from the map, the data
+ * will be deleted.
+ */
+ template <class Key,class Data>
+ class PtrMap
+ {
+ bool autodel;
+ std::map<Key,Data*> pmap;
+ public:
+ /**
+ * Constructor.
+ * @param auto_del Wether or not to enable auto deletion
+ */
+ PtrMap(bool autodel = false) : autodel(autodel)
+ {}
+
+ /**
+ * Destructor. Will delete all objects, if auto deletion is on.
+ */
+ virtual ~PtrMap()
+ {
+ clear();
+ }
+
+
+ /**
+ * Return the number of key data pairs in the map.
+ */
+ unsigned int count() const {return pmap.size();}
+
+ /**
+ * Enable or disable auto deletion.
+ * @param yes Enable if true, disable if false
+ */
+ void setAutoDelete(bool yes)
+ {
+ autodel = yes;
+ }
+
+ typedef typename std::map<Key,Data*>::iterator iterator;
+ typedef typename std::map<Key,Data*>::const_iterator const_iterator;
+
+ iterator begin() {return pmap.begin();}
+ iterator end() {return pmap.end();}
+
+ const_iterator begin() const {return pmap.begin();}
+ const_iterator end() const {return pmap.end();}
+
+ /**
+ * Remove all objects, will delete them if autodelete is on.
+ */
+ void clear()
+ {
+ if (autodel)
+ {
+ for (iterator i = pmap.begin();i != pmap.end();i++)
+ {
+ delete i->second;
+ i->second = 0;
+ }
+ }
+ pmap.clear();
+ }
+
+ /**
+ * Insert a key data pair.
+ * @param k The key
+ * @param d The data
+ * @param overwrite Wether or not to overwrite
+ * @return true if the insertion took place
+ */
+ bool insert(const Key & k,Data* d,bool overwrite = true)
+ {
+ iterator itr = pmap.find(k);
+ if (itr != pmap.end())
+ {
+ if (overwrite)
+ {
+ if (autodel)
+ delete itr->second;
+ itr->second = d;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ pmap[k] = d;
+ return true;
+ }
+ }
+
+ /**
+ * Find a key in the map and returns it's data.
+ * @param k The key
+ * @return The data of the key, 0 if the key isn't in the map
+ */
+ Data* find(const Key & k)
+ {
+ iterator i = pmap.find(k);
+ return (i == pmap.end()) ? 0 : i->second;
+ }
+
+ /**
+ * Find a key in the map and returns it's data.
+ * @param k The key
+ * @return The data of the key, 0 if the key isn't in the map
+ */
+ const Data* find(const Key & k) const
+ {
+ const_iterator i = pmap.find(k);
+ return (i == pmap.end()) ? 0 : i->second;
+ }
+
+ /**
+ * Check to see if a key is in the map.
+ * @param k The key
+ * @return true if it is part of the map
+ */
+ bool contains(const Key & k) const
+ {
+ const_iterator i = pmap.find(k);
+ return i != pmap.end();
+ }
+
+ /**
+ * Erase a key from the map. Will delete
+ * the data if autodelete is on.
+ * @param key The key
+ * @return true if an erase took place
+ */
+ bool erase(const Key & key)
+ {
+ iterator i = pmap.find(key);
+ if (i == pmap.end())
+ return false;
+
+ if (autodel)
+ delete i->second;
+ pmap.erase(i);
+ return true;
+ }
+ };
+
+
+ /**
+ * @author Joris Guisson
+ *
+ * Template array classes, makes creating dynamic buffers easier
+ * and safer.
+ */
+ template<class T>
+ class Array
+ {
+ Uint32 num;
+ T* data;
+ public:
+ Array(Uint32 num = 0) : num(num),data(0)
+ {
+ if (num > 0)
+ data = new T[num];
+ }
+
+ ~Array()
+ {
+ delete [] data;
+ }
+
+ T & operator [] (Uint32 i) {return data[i];}
+ const T & operator [] (Uint32 i) const {return data[i];}
+
+ operator const T* () const {return data;}
+ operator T* () {return data;}
+
+ /// Get the number of elements in the array
+ Uint32 size() const {return num;}
+
+ /**
+ * Fill the array with a value
+ * @param val The value
+ */
+ void fill(T val)
+ {
+ for (Uint32 i = 0;i < num;i++)
+ data[i] = val;
+ }
+ };
+
+}
+
+#endif
diff --git a/src/hiddensrvs.ui b/src/hiddensrvs.ui
new file mode 100644
index 0000000..21a4c09
--- /dev/null
+++ b/src/hiddensrvs.ui
@@ -0,0 +1,241 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>MyHidden</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>MyHidden</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>576</width>
+ <height>525</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Create and Manage Hidden Services on the Tor Network</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Your Hidden Services</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="2" column="1">
+ <property name="name">
+ <cstring>startService</cstring>
+ </property>
+ <property name="text">
+ <string>Start Service</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="3">
+ <property name="name">
+ <cstring>deleteService</cstring>
+ </property>
+ <property name="text">
+ <string>Delete Service</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="2">
+ <property name="name">
+ <cstring>startAllServices</cstring>
+ </property>
+ <property name="text">
+ <string>Start All Services</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="0">
+ <property name="name">
+ <cstring>createService</cstring>
+ </property>
+ <property name="text">
+ <string>Create Service</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>testService</cstring>
+ </property>
+ <property name="text">
+ <string>Test Service</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="3" column="2">
+ <property name="name">
+ <cstring>publishService</cstring>
+ </property>
+ <property name="text">
+ <string>Publish Service</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="1" column="0" rowspan="1" colspan="4">
+ <column>
+ <property name="text">
+ <string>Tor Address</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Nick</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Public Port</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Actual Address</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Folder Serving Files</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Service Folder</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>servicesList</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;blockquote&gt;Hidden Services are services you either run locally or redirect to remotely by offering them anonymously on the Tor network.&lt;/blockquote&gt;
+&lt;blockquote&gt;&lt;b&gt;For more information on hidden services, see http://www.torproject.org.&lt;/b&gt;&lt;/blockquote&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>createService</sender>
+ <signal>clicked()</signal>
+ <receiver>MyHidden</receiver>
+ <slot>createService_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>deleteService</sender>
+ <signal>clicked()</signal>
+ <receiver>MyHidden</receiver>
+ <slot>deleteService_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>startService</sender>
+ <signal>clicked()</signal>
+ <receiver>MyHidden</receiver>
+ <slot>startService_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>servicesList</sender>
+ <signal>selectionChanged()</signal>
+ <receiver>MyHidden</receiver>
+ <slot>servicesList_selectionChanged()</slot>
+ </connection>
+ <connection>
+ <sender>startAllServices</sender>
+ <signal>clicked()</signal>
+ <receiver>MyHidden</receiver>
+ <slot>startAllServices_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>testService</sender>
+ <signal>clicked()</signal>
+ <receiver>MyHidden</receiver>
+ <slot>testService_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>publishService</sender>
+ <signal>clicked()</signal>
+ <receiver>MyHidden</receiver>
+ <slot>publishService_clicked()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="global" impldecl="in declaration">kprocio.h</include>
+ <include location="local" impldecl="in implementation">hiddensrvs.ui.h</include>
+</includes>
+<slots>
+ <slot>createService_clicked()</slot>
+ <slot>addService( const QString &amp; nick, const QString &amp; publicport, const QString &amp; actualaddress, const QString &amp; toraddress, const QString &amp; folder, const QString &amp; servicefolder )</slot>
+ <slot>deleteService_clicked()</slot>
+ <slot>startService_clicked()</slot>
+ <slot>thttpdprocExited(KProcess *proc)</slot>
+ <slot>servicesList_selectionChanged()</slot>
+ <slot>startAllServices_clicked()</slot>
+ <slot>testService_clicked()</slot>
+ <slot>publishService_clicked()</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+ <function access="private" specifier="non virtual">destroyed()</function>
+ <function access="private" specifier="non virtual">updateServices()</function>
+ </functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/hiddensrvs.ui.h b/src/hiddensrvs.ui.h
new file mode 100644
index 0000000..8c2e2f8
--- /dev/null
+++ b/src/hiddensrvs.ui.h
@@ -0,0 +1,207 @@
+/***************************************************************************
+* Copyright (C) 2006 - 2008 Robert Hogan *
+* robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "torkconfig.h"
+#include "tork.h"
+#include "hidsrvwizard.h"
+#include <klocale.h>
+#include <kdebug.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <kurl.h>
+#include <kapplication.h>
+#include <kprocio.h>
+#include <kmessagebox.h>
+#include <cstdlib>
+
+void MyHidden::init()
+{
+
+ QStringList hiddenServices = TorkConfig::hiddenServices();
+ for ( QStringList::Iterator it = hiddenServices.begin(); it != hiddenServices.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+
+ new QListViewItem(servicesList,(*it).section("\n",-6,-6),(*it).section("\n",-5,-5),
+ (*it).section("\n",-4,-4),(*it).section("\n",-3,-3),(*it).section("\n",-2,-2),(*it).section("\n",-1));
+ }
+
+ deleteService->setEnabled(false);
+ startService->setEnabled(false);
+ testService->setEnabled(false);
+ publishService->setEnabled(false);
+}
+
+void MyHidden::destroyed()
+{
+
+}
+
+void MyHidden::createService_clicked()
+{
+
+ if (static_cast<tork*>(this->topLevelWidget()->parentWidget())->connectedToTor()){
+ HidSrvWizard wizard;
+ wizard.setCaption( i18n( "Hidden Services Wizard" ));
+ connect( &wizard, SIGNAL(createService(const QString&,const QString&)),this->topLevelWidget()->parent(), SLOT(createService(const QString&,const QString& )) );
+ connect( &wizard, SIGNAL(addService(const QString&,const QString&,const QString&,const QString&,const QString&,const QString&)), SLOT(addService(const QString&,const QString&,const QString&,const QString&,const QString&,const QString&)) );
+ wizard.exec();
+ }else{
+ QString caption = i18n("Not Connected To Tor!");
+ QString message = i18n("<p>TorK needs to be connected to Tor in order to create a hidden service. <br>"
+ "<b>To create a hidden service, first start TorK!");
+ KMessageBox::information (this, message, caption);
+ }
+
+
+}
+
+void MyHidden::updateServices()
+{
+ if ( servicesList->childCount() > 0 ) {
+ QStringList v_hiddenServices;
+ QListViewItemIterator it( servicesList );
+ while ( it.current() ) {
+ QString s_hiddenServices = it.current()->text(0) + "\n" + it.current()->text(1)
+ + "\n" + it.current()->text(2) + "\n" + it.current()->text(3)
+ + "\n" + it.current()->text(4)+ "\n" + it.current()->text(5);
+ v_hiddenServices.append(s_hiddenServices);
+ ++it;
+ }
+ TorkConfig::setHiddenServices( v_hiddenServices );
+ }else
+ TorkConfig::setHiddenServices( "" );
+ TorkConfig::writeConfig();
+}
+
+void MyHidden::addService(const QString& nick,const QString& publicport,const QString& actualaddress,const QString& toraddress,const QString& folder,const QString& servicefolder)
+{
+ new QListViewItem(servicesList,toraddress,nick,publicport,actualaddress,folder,servicefolder);
+ updateServices();
+}
+
+void MyHidden::deleteService_clicked()
+{
+ QString serviceDetails = servicesList->currentItem()->text(5);
+ QString serviceAddress = servicesList->currentItem()->text(0);
+
+ delete servicesList->currentItem();
+ QString caption = i18n("Service deleted!");
+ QString message = i18n("<p>The hidden service %1 has been de-configured. <br>"
+ "<b>However you will need to delete the service details in %2 yourself! Please do this!").arg(serviceAddress).arg(serviceDetails);
+ KMessageBox::information (this, message, caption);
+
+ updateServices();
+}
+
+
+void MyHidden::startService_clicked()
+{
+
+ KProcIO* thttpdproc = new KProcIO();
+ thttpdproc->setUseShell(TRUE);
+
+ QString curpath = (QString) getenv("PATH");
+ thttpdproc->setEnvironment("PATH",curpath + ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin");
+
+ *thttpdproc << "thttpd -p " << servicesList->currentItem()->text(3).section(":",1)
+ << "-h " << servicesList->currentItem()->text(3).section(":",0,0)
+ << "-d " << servicesList->currentItem()->text(4);
+
+ connect( thttpdproc, SIGNAL(processExited(KProcess *)),
+ SLOT(thttpdprocExited(KProcess *)) );
+
+ thttpdproc->start(KProcIO::NotifyOnExit) ;
+
+}
+
+void MyHidden::thttpdprocExited(KProcess *proc)
+{
+ QString caption;
+ QString message;
+
+ if (proc->exitStatus() == 0){
+ caption = i18n("Hidden Web Service Started");
+ message = i18n("<p>Simple web service started. Test the service to ensure it's running. <br>"
+ "<b>thttpd -p %1 -h %2 -d %3").arg(servicesList->currentItem()->text(3).section(":",1))
+ .arg(servicesList->currentItem()->text(3).section(":",0,0))
+ .arg(servicesList->currentItem()->text(4));
+ }else{
+ caption = i18n("Hidden Web Service Failed");
+ message = i18n("<p>Couldn't start the simple web service. Thttpd may not be installed properly. <br>"
+ "<b>thttpd -p %1 -h %2 -d %3").arg(servicesList->currentItem()->text(3).section(":",1))
+ .arg(servicesList->currentItem()->text(3).section(":",0,0))
+ .arg(servicesList->currentItem()->text(4));
+
+ }
+
+ KMessageBox::information (this, message, caption);
+
+}
+void MyHidden::servicesList_selectionChanged()
+{
+ if (servicesList->currentItem()->text(4).isEmpty())
+ startService->setEnabled(false);
+ else
+ startService->setEnabled(true);
+ deleteService->setEnabled(true);
+ testService->setEnabled(true);
+ publishService->setEnabled(true);
+}
+
+
+void MyHidden::startAllServices_clicked()
+{
+
+}
+
+
+void MyHidden::testService_clicked()
+{
+ if ((TorkConfig::kDEUsesTor()) &&
+ (static_cast<tork*>(this->topLevelWidget()->parentWidget())->connectedToTor())){
+ KURL url = QString("http://%1").arg(servicesList->currentItem()->text(0));
+ kapp->invokeBrowser(url.url(), "0");
+ }else{
+ QString caption = i18n("Not Connected To Tor!");
+ QString message = i18n("<p>Konqueror and TorK need to be using Tor in order to test a hidden service. <br>"
+ "<b>To test a hidden service, first start TorK and enable Konqueror to use Tor!");
+ KMessageBox::information (this, message, caption);
+ }
+
+}
+
+
+void MyHidden::publishService_clicked()
+{
+ if ((TorkConfig::kDEUsesTor()) &&
+ (static_cast<tork*>(this->topLevelWidget()->parentWidget())->connectedToTor())){
+
+ KURL url = QString("tor:6sxoyfb3h2nvok2d.onion/tor/FrontPage?action=edit");
+ kapp->invokeBrowser(url.url(), "0");
+ }else{
+ QString caption = i18n("Not Connected To Tor!");
+ QString message = i18n("<p>Konqueror and TorK need to be using Tor in order to publish a hidden service. <br>"
+ "<b>To publish a hidden service, first start TorK and enable Konqueror to use Tor!");
+ KMessageBox::information (this, message, caption);
+ }
+
+
+}
diff --git a/src/hidsrvwizard.ui b/src/hidsrvwizard.ui
new file mode 100644
index 0000000..1497ad5
--- /dev/null
+++ b/src/hidsrvwizard.ui
@@ -0,0 +1,484 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>HidSrvWizard</class>
+<widget class="QWizard">
+ <property name="name">
+ <cstring>HidSrvWizard</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>406</width>
+ <height>240</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Select Service Type</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QButtonGroup" row="1" column="0">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Service Types</string>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>localWeb</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>12</x>
+ <y>55</y>
+ <width>287</width>
+ <height>19</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>A local web service.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>remote</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>12</x>
+ <y>30</y>
+ <width>340</width>
+ <height>19</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>A redirect to a remote or local service, e.g. google.com</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>What kind of hidden service would you like to create?</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>LocalWebService</cstring>
+ </property>
+ <attribute name="title">
+ <string>Local Web Service</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;blockquote&gt;To run a local web service, the Tor people recommend thttpd. Would you like to download and install thttpd now? If not, you can just continue and set up the address and port of the service as normal.&lt;/blockquote&gt;</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>downloadThttpd</cstring>
+ </property>
+ <property name="text">
+ <string>Download thttpd</string>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>81</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>71</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>ServiceName</cstring>
+ </property>
+ <attribute name="title">
+ <string>Service Name</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>What name do you want to give to this service?</string>
+ </property>
+ </widget>
+ <spacer row="3" column="1">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="1">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>31</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="2">
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>101</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit" row="2" column="1">
+ <property name="name">
+ <cstring>Nick</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>180</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>RedirectService</cstring>
+ </property>
+ <attribute name="title">
+ <string>Redirect Service</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit" row="2" column="0">
+ <property name="name">
+ <cstring>RedirectAddress</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Enter the address and port your service will redirect to:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="2">
+ <property name="name">
+ <cstring>NonWebPort</cstring>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>Enter the port your hidden service will listen on:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>e.g. www.google.com&lt;br&gt;or localhost</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>RedirectPort</cstring>
+ </property>
+ <property name="maxValue">
+ <number>999999999</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>e.g. 80</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>LocalWebServiceFiles</cstring>
+ </property>
+ <attribute name="title">
+ <string>Local Web Service</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel5_2</cstring>
+ </property>
+ <property name="text">
+ <string>Select or accept the location of the files you will serve:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel6_2</cstring>
+ </property>
+ <property name="text">
+ <string>Enter the port your hidden service will listen on:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel6_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Enter the local port for your hidden service:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>localWebPort</cstring>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ <property name="value">
+ <number>5222</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>WebPort</cstring>
+ </property>
+ <property name="maxValue">
+ <number>99999</number>
+ </property>
+ <property name="value">
+ <number>80</number>
+ </property>
+ </widget>
+ <widget class="KURLComboRequester" row="3" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>FilesToServe</cstring>
+ </property>
+ <property name="mode">
+ <number>6</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>ServiceConfigured</cstring>
+ </property>
+ <attribute name="title">
+ <string>Service Configured.</string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel6_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>14</x>
+ <y>8</y>
+ <width>350</width>
+ <height>90</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>OK. Your hidden service has been configured.&lt;br&gt;Now Tor needs to create it. Click 'Next' to create the service.</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>GatherDetails</cstring>
+ </property>
+ <attribute name="title">
+ <string>Gathering Service Details from Tor</string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>GatheringDetailsText</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>5</x>
+ <y>15</y>
+ <width>370</width>
+ <height>130</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Please wait a moment while Tor creates the service details.</string>
+ </property>
+ <property name="textFormat">
+ <enum>RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ </widget>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>localWeb</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>HidSrvWizard</receiver>
+ <slot>localWeb_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>downloadThttpd</sender>
+ <signal>clicked()</signal>
+ <receiver>HidSrvWizard</receiver>
+ <slot>downloadThttpd_clicked()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>remote</tabstop>
+ <tabstop>downloadThttpd</tabstop>
+ <tabstop>Nick</tabstop>
+ <tabstop>NonWebPort</tabstop>
+ <tabstop>RedirectAddress</tabstop>
+ <tabstop>RedirectPort</tabstop>
+ <tabstop>WebPort</tabstop>
+ <tabstop>localWebPort</tabstop>
+ <tabstop>FilesToServe</tabstop>
+</tabstops>
+<includes>
+ <include location="local" impldecl="in implementation">hidsrvwizard.ui.h</include>
+</includes>
+<signals>
+ <signal>createService(const QString &amp;,const QString &amp;)</signal>
+ <signal>addService(const QString &amp;,const QString &amp;,const QString &amp;,const QString &amp;,const QString &amp;,const QString &amp;)</signal>
+</signals>
+<slots>
+ <slot>localWeb_toggled( bool state )</slot>
+ <slot>downloadThttpd_clicked()</slot>
+ <slot>showPage( QWidget * w )</slot>
+ <slot>checkServiceDetails()</slot>
+ <slot>accept()</slot>
+ <slot>reject()</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/src/hidsrvwizard.ui.h b/src/hidsrvwizard.ui.h
new file mode 100644
index 0000000..685f01f
--- /dev/null
+++ b/src/hidsrvwizard.ui.h
@@ -0,0 +1,163 @@
+/***************************************************************************
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "tork.h"
+#include "functions.h"
+#include <qtimer.h>
+#include <kmessagebox.h>
+#include <cstdlib>
+
+bool local;
+QString thttpd;
+
+
+void HidSrvWizard::init()
+{
+ local=false;
+ setAppropriate ( LocalWebService, false );
+ setAppropriate ( LocalWebServiceFiles, false );
+ setAppropriate ( ServiceName, true );
+ setAppropriate ( RedirectService, true );
+
+ QString location = getenv("HOME");
+ location += "/.tork";
+ QDir torkdir(location);
+ if (!torkdir.exists() && !torkdir.mkdir(location)){
+ KMessageBox::information (this,QString("Couldn't create directory: %1. Check the permissions!").arg(location));
+ reject();
+ }
+
+
+}
+void HidSrvWizard::localWeb_toggled( bool state)
+{
+
+
+
+ if (state){
+ const char *paths = ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin";
+ thttpd = getFullLocation(paths,"thttpd");
+
+ if (thttpd)
+ setAppropriate ( LocalWebService, !state );
+ else
+ setAppropriate ( LocalWebService, state );
+ }else
+ setAppropriate ( LocalWebService, state );
+
+ setAppropriate ( LocalWebServiceFiles, state );
+ setAppropriate ( RedirectService, !state );
+ local = state;
+
+
+}
+
+
+void HidSrvWizard::downloadThttpd_clicked()
+{
+ TorkUpdate* updater = new TorkUpdate(this);
+ updater->downloadThttpd();
+
+}
+
+
+void
+HidSrvWizard::showPage( QWidget *w ) //virtual
+{
+ QWizard::showPage( w );
+
+
+ if (currentPage() == this->GatherDetails){
+ if (local)
+ emit createService(QString("%1/.tork/%2/").arg(getenv("HOME")).arg(Nick->text()), QString("%1 localhost:%2").arg(WebPort->text()).arg(localWebPort->text()));
+ else
+ emit createService(QString("%1/.tork/%2/").arg(getenv("HOME")).arg(Nick->text()), QString("%1 %2:%3").arg(NonWebPort->text()).arg(RedirectAddress->text()).arg(RedirectPort->text()));
+ GatheringDetailsText->setText("Please wait while Tor attempts to create the service.");
+ QTimer::singleShot( 3000, this, SLOT(checkServiceDetails()) );
+ finishButton()->setEnabled(false);
+ }
+
+}
+
+void
+HidSrvWizard::checkServiceDetails()
+{
+
+ QString hostname;
+ QFile inf(QString("%1/.tork/%2/hostname").arg(getenv("HOME")).arg(Nick->text()));
+ if ( inf.open(IO_ReadOnly) ) {
+ inf.readLine(hostname,50);
+ inf.close();
+ }else{
+ GatheringDetailsText->setText("Failed. Click Back and Next to try again.");
+ return;
+ }
+
+ hostname.replace("\n","");
+
+ cancelButton()->setEnabled(false);
+
+ QString serviceDetails = "Hidden Service Hostname: ";
+ serviceDetails += hostname;
+ serviceDetails += "<br>";
+ if (local){
+ serviceDetails += "Serving files in:";
+ serviceDetails += FilesToServe->url();
+ serviceDetails += "<br>";
+ serviceDetails += "Public Facing Port:";
+ serviceDetails += WebPort->text();
+ serviceDetails += "<br>";
+ serviceDetails += "Tor Facing Port:";
+ serviceDetails += localWebPort->text();
+ emit addService(Nick->text(),WebPort->text(),QString("localhost:%1").arg(localWebPort->text()),hostname,FilesToServe->url(),QString("%1/.tork/%2/").arg(getenv("HOME")).arg(Nick->text()));
+
+ }else{
+ serviceDetails += "Redirecting to:";
+ serviceDetails += RedirectAddress->text();
+ serviceDetails += "<br>";
+ serviceDetails += "On Port:";
+ serviceDetails += RedirectPort->text();
+ serviceDetails += "<br>";
+ serviceDetails += "Serving Tor Network with Port:";
+ serviceDetails += NonWebPort->text();
+ serviceDetails += "<br>";
+ emit addService(Nick->text(),NonWebPort->text(),QString("%1:%2").arg(RedirectAddress->text()).arg(RedirectPort->text()),hostname,"",QString("%1/.tork/%2/").arg(getenv("HOME")).arg(Nick->text()));
+
+ }
+
+
+ GatheringDetailsText->setText(serviceDetails);
+ finishButton()->setEnabled(true);
+
+}
+
+void
+HidSrvWizard::accept()
+{
+ QDialog::accept();
+}
+
+void
+HidSrvWizard::reject()
+{
+ QDialog::reject();
+}
+
+
diff --git a/src/hitwidget.cpp b/src/hitwidget.cpp
new file mode 100644
index 0000000..33d021d
--- /dev/null
+++ b/src/hitwidget.cpp
@@ -0,0 +1,208 @@
+/***************************************************************************
+ * Copyright (C) 2005 Novell, Inc. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
+ ***************************************************************************/
+
+#include "hitwidget.h"
+#include "kerrylabel.h"
+
+#include <kpushbutton.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+#include <qtoolbutton.h>
+#include <klocale.h>
+#include <kurllabel.h>
+#include <kglobalsettings.h>
+#include <qlayout.h>
+/*#include <konq_filetip.h>*/
+#include <qscrollview.h>
+#include <qcombobox.h>
+
+HitWidget::HitWidget(QString uri, QString mimetype, KWidgetListbox *parent, const char *name)
+ : HitWidgetLayout(parent, name), m_uri(uri), m_mimetype(mimetype), m_collapsed(false),
+ m_was_collapsed(false), m_icon(QString::null)
+{
+ HitWidgetLayoutLayout->setMargin(4);
+ toolButton1->setEnabled(false);
+ toolButton1->hide();
+ score->setHidden(true);
+ //score->setText("");
+ setDescriptionText("");
+ setPropertiesText("");
+ icon->installEventFilter(this);
+/* pFileTip = new KonqFileTip(parent);*/
+/* pFileTip->setItem(0L);*/
+ qsv=parent;
+
+}
+
+HitWidget::~HitWidget()
+{
+/* delete pFileTip;*/
+}
+
+void HitWidget::setIcon(const QString name)
+{
+ m_icon = name;
+ if (m_collapsed)
+ icon->setPixmap(KGlobal::iconLoader()->loadIcon(m_icon, KIcon::NoGroup, KIcon::SizeSmall));
+ else
+ icon->setPixmap(KGlobal::iconLoader()->loadIcon(m_icon, KIcon::NoGroup, KIcon::SizeLarge));
+}
+
+void HitWidget::toggleCollapsed()
+{
+ setCollapsed(!m_collapsed);
+}
+
+void HitWidget::setCollapsed(bool collapsed)
+{
+ if (m_collapsed==collapsed)
+ return;
+
+ if (collapsed) {
+ toolButton1->setEnabled(true);
+ m_was_collapsed = true;
+ icon->setPixmap(KGlobal::iconLoader()->loadIcon(m_icon, KIcon::NoGroup, KIcon::SizeSmall));
+#if 0
+ i18n("Expand");
+ i18n("Collapse");
+ i18n("Expand All");
+ i18n("Collapse All");
+ i18n("(still searching)");
+#endif
+ toolButton1->setIconSet(SmallIconSet("info"));
+ description->setHidden(true);
+ properties->setHidden(true);
+ score->setHidden(true);
+ icon->setMinimumSize( QSize( 64, 16 ) );
+ icon->setMaximumSize( QSize( 64, 16 ) );
+ m_collapsed = collapsed;
+ }
+ else {
+ icon->setPixmap(KGlobal::iconLoader()->loadIcon(m_icon, KIcon::NoGroup, KIcon::SizeLarge));
+ toolButton1->setIconSet(SmallIconSet("2uparrow"));
+ description->setHidden(false);
+ properties->setHidden(false);
+ //score->setHidden(false);
+ icon->setMinimumSize( QSize( 64, 64 ) );
+ icon->setMaximumSize( QSize( 64, 64 ) );
+ m_collapsed = collapsed;
+ emit uncollapsed(this);
+ }
+
+ if (qsv)
+ qsv->adjustSize(this);
+}
+
+bool HitWidget::isCollapsed() const
+{
+ return m_collapsed;
+}
+
+void HitWidget::setDescriptionText(QString text)
+{
+ description->setText(text);
+}
+
+void HitWidget::setPropertiesText(QString text)
+{
+ properties->setText(text);
+}
+
+void HitWidget::insertHeaderWidget( int index, QWidget * widget)
+{
+ layoutHeader->insertWidget(index,widget);
+}
+
+void HitWidget::insertHitWidget( int index, QWidget * widget)
+{
+ layoutButton->insertWidget(index,widget);
+}
+
+void HitWidget::insertTextWidget( int index, QWidget * widget)
+{
+ layoutText->insertWidget(index,widget);
+}
+
+void HitWidget::insertHitSpacing( int index, int size)
+{
+ layoutButton->insertSpacing(index,size);
+}
+
+QString HitWidget::uri() const
+{
+ return m_uri;
+}
+
+void HitWidget::setUri(const QString uri)
+{
+/* pFileTip->setItem(0L);*/
+ m_uri = uri;
+}
+
+QString HitWidget::mimetype() const
+{
+ return m_mimetype;
+}
+
+void HitWidget::adjustSize()
+{
+ int dwidth, pwidth;
+
+ HitWidgetLayout::adjustSize();
+ if (m_was_collapsed) {
+ dwidth = width()-160;
+ pwidth = width()-160;
+ }
+ else {
+ dwidth = description->size().width() + 160;
+ pwidth = properties->size().width() + 160;
+ }
+
+ description->setFixedSize(dwidth,description->heightForWidth(dwidth));
+ properties->setFixedSize(pwidth,properties->heightForWidth(pwidth));
+ HitWidgetLayout::adjustSize();
+}
+
+bool HitWidget::eventFilter( QObject *, QEvent * )
+{
+/* if ( obj == icon && !m_uri.isEmpty() ) {
+ if ( ev->type() == QEvent::Enter && parent() ) {
+ pFileTip->setOptions(true, true, 6);
+ KFileItem *fileitem=new KFileItem(m_uri,m_mimetype,KFileItem::Unknown);
+ QPoint viewport = qsv->viewport()->mapFromGlobal(mapToGlobal(icon->pos()));
+ QRect qr(qsv->viewportToContents(viewport),QSize(icon->width()*2,icon->height()));
+ pFileTip->setItem(fileitem,qr,icon->pixmap());
+ }
+ else if ( ev->type() == QEvent::Leave )
+ pFileTip->setItem(0L);
+ return HitWidgetLayout::eventFilter( obj, ev );
+ }*/
+ return false;
+}
+
+void HitWidget::changeTerminalUrl(int ) {
+
+ QString app = score->currentText();
+ QString title = shellTitles[score->currentText()];
+
+ icon->setURL(QString("%1 %2").arg(app).arg(title));
+
+}
+
+#include "hitwidget.moc"
diff --git a/src/hitwidget.h b/src/hitwidget.h
new file mode 100644
index 0000000..6c3eaaa
--- /dev/null
+++ b/src/hitwidget.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ * Copyright (C) 2005 Novell, Inc. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
+ ***************************************************************************/
+
+#ifndef HITWIDGET_H
+#define HITWIDGET_H
+
+#include <hitwidget_layout.h>
+#include "kwidgetlistbox.h"
+
+class QScrollView;
+// class KonqFileTip;
+
+class HitWidget : public HitWidgetLayout
+{
+ Q_OBJECT
+ public:
+ HitWidget(QString uri, QString mimetype, KWidgetListbox *parent = 0, const char *name = 0);
+ ~HitWidget();
+
+ void setCollapsed(bool);
+ bool isCollapsed() const;
+ void setIcon(QString name);
+
+ void setDescriptionText(QString text);
+ void setPropertiesText(QString text);
+ void setUri(const QString uri);
+ QString uri() const;
+ QString mimetype() const;
+
+ void insertHeaderWidget( int index, QWidget * widget);
+ void insertTextWidget( int index, QWidget * widget);
+ void insertHitWidget( int index, QWidget * widget);
+ void insertHitSpacing( int index, int size);
+
+ virtual void adjustSize();
+ virtual bool eventFilter(QObject*, QEvent*);
+
+ QMap<QString,QString> shellTitles;
+
+ signals:
+ void uncollapsed(HitWidget*);
+
+ private slots:
+ void toggleCollapsed();
+ void changeTerminalUrl(int no);
+
+ private:
+ KWidgetListbox* qsv;
+ QString m_uri, m_mimetype;
+/* KonqFileTip* pFileTip;*/
+ bool m_collapsed, m_was_collapsed;
+ QString m_icon;
+};
+
+#endif
diff --git a/src/hitwidget_layout.ui b/src/hitwidget_layout.ui
new file mode 100644
index 0000000..46a7ce2
--- /dev/null
+++ b/src/hitwidget_layout.ui
@@ -0,0 +1,343 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>HitWidgetLayout</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>HitWidgetLayout</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QToolButton" row="0" column="0">
+ <property name="name">
+ <cstring>toolButton1</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer5_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget" row="0" rowspan="2" column="2">
+ <property name="name">
+ <cstring>layoutIcon</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KerryLabel">
+ <property name="name">
+ <cstring>icon</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>64</width>
+ <height>64</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>64</width>
+ <height>64</height>
+ </size>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="alignment">
+ <set>AlignCenter</set>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>score</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <spacer row="0" column="1">
+ <property name="name">
+ <cstring>spacer6_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>8</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="0" column="3">
+ <property name="name">
+ <cstring>spacer6_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>8</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget" row="0" column="4" rowspan="2">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layoutHeader</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>210</width>
+ <height>1</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout27</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layoutText</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>description</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>properties</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Properties</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignTop</set>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layoutButton</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>10</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>10</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="PNG" length="5116">89504e470d0a1a0a0000000d4948445200000040000000470806000000b76c4166000013c349444154789cd59b797c54e5b9c7bfef39b36526939504123611300ae202294a412c52aca0423197c5da96aa148b8ab6b4f45a976b5d3ef62af4f6aab5d88216efd52ab457f40388209b20d42218a0e06509040890852c6499c96ce73cf78f33998430249310d4fb7c3eef273367ce79dff7f77b96f7799ff704bea6f20790c9203920ce68f380f407b91de437205ff51c2f8a3c07721988b200b6d9d2406680ac834b3b3b9eea8a4977853c0bf20670a8c5355dd7e9dbb72fbd7bf72635351511a1bcbc9c03070e505b5b1bbb2f1df829f0e4d7084f5c590d3b5a7e7f03e46e90dc165acdcbcb93471e7944366edc28959595621886b416bfdf2f6bd7ae955b6fbd55945242d4620abe8e6ef12ac850103b881ef5653788a305e8a4a4249932658aac5fbf5e2291c83980cf27a669caf2e5cb25232323d6d7ad1d24e1a29acc22909f00b9bd7b3369d224b2b3b3a9afafe7f4e9d3d4d5d5919999c9f5d75fcf6db7dd46767676a7c7d9b3670f37df7c33e5e5e500dc0ffce1ebe00e4341aeb9e61aa9aaaa4a58ab9d95ad5bb78acbe512a2d6b5fcab7687c7409240366fde7cd1c137c9534f3d157385895f3501978278bd5e0904025f1a010d0d0d9293932344738644e6a95d2c026c80520aa5da77c56030d8e9714cd38c7df6783ccc983103001ff06202245c340286000d0d0d1c3d7af4bcf7048341e6cd9bc7c183073bdcffce9d3bb9e1861bf0fbfdb16b7bf7ee25292929f67d7f02fd5c3402be81a59d0d1b36c4fd7dfbf6ed8c1c3992d75f7f9d81030776a8efa3478f3261c204f2f2f2484e4e8e5d1f3c7830c1603066751f004f7d55b1e0896830bae38e3b623eba7bf76e79e2892764c48811a2699a003266cc980ef9792412911b6fbc51745d975dbb76c5bde785175e88f50fc8c82e24c10ef402ae044601e3807c6002f063e0c9eb60cfd5205a74f0dcdc5c314d53f6eedd2bd9d9d9e7e4f34f3cf144870858b2648900327efc7889442262188698a629a6699e75dfc2850bcf22a1b359621e3017f81b701808b706d0d49452a2699a689a26baae4b5a5a9a0c19324466cf9e2da1504844444a4b4b65d8b061b1679c4ea7ecdbb72f61f0a15048060c1820802c5dba541a1b1b25100848301894502824e17038468a6118f2ca2bafc448d0acbd46c2240c063e04ccf3016ed95e7ae925a9aaaa129fcf27a150e81c6db494aaaa2a993a75aae4e7e7cbead5ab3ba4fd356bd608206eb75b4a4a4aa4b6b656eaeaeaa4bebe5e1a1a1ac4e7f389dfef3f8b98c71f7f3c36cf6f2748c0f5407d4bcdde70c30dd2bf7fffb8e0dd6eb79497977708486765eedcb90248efdebda5a2a2422a2b2ba5aaaa4aaaababa5a6a6466a6a6ae4cc993367115357572763c78e8d6588adc1c65b057e072403a4a5a5b164c91294521c3e7c382e5bf7de7bef05e5f11d91a625d5eff7e3f7fb09854267b570387c4e330c83f9f3e7e3743a0901cfb722211e01c300bc5e2f1b366ce0e0c1836cdebc39ee84ba77efce934f3ed9a520db926eddba01505d5d4d5959590c646b225ab75ebd7af1ddef7e1780ddadfa8c47400540414101575d75158b162d8a3b194dd358b870219999995d06b03d193264080022427d7d7d9b9a6fdd264e9c089c5d70012b636d2dab8199cb972f273737978a8a8ab89379e08107983c7972d7a14b401c0e07006eb79bb4b434c2e130d09c72b7d5060d1a84aeeb941bc6597dc623603130b3b6b696e79e7b2eee446ebae926162c58d095d81292eddbb703306ad4286c361ba150a84dd0d04c8ec7e3c1e57251ebf39dd5673c02fe01ac07c6c69b446e6e2e6fbdf5564c1b5f961c3f7e9c65cb96e1743a9931634687b4dfd4448448ab7ee31100300ff814380ba5a669bcf6da6bf4e8d1a3cb01b625c16090993367525f5fcf9c3973e8d3a74f87b4af94a2a1a1816030481ad64eb149ce474021f024f09b96171f7cf0416eb9e5968b81f1bc120e8799356b161f7df411e3c78f67e2c48984c3e1b820db6abb76edc2300c7280aa16fd9f8f0080e7817f018629a59832650af3e7cfbf7848e388dfefe7eebbef66d9b2658c1c3992d9b367138944300c2361cd37b5f7df7f1fb0362e7b5b8cd11601027c020c9b3a752a6fbffd7642c58dae92d2d252a64d9bc6962d5b183e7c380f3ffc3022d2aee9c76bfbf6ed63d3a64dd88149c09216e3b44500c03ae0e1eaeaea2f157c61612105050514171773cd35d73067ce1c8036c1437ccdd7d4d4f0ecb3cf6218063380c9adaac5ed11f031e02b2c2cf498a689a65db4fa494c3efcf043a64f9f4e6d6d2d7dfaf461f6ecd928a53ae5f7814080679e79868a8a0a4602afc72995b787a81ef8b0aaaa8a03070e743dda56b272e54a0a0a0aa8adadc5e572316bd6acd87adf5ed6d73afdf5f97c3cfffcf3ecdfbf9f41c0d6f39c1324a2d2b74484952b57762dda56525858c85d77dd15abf14d983081cccccc7681c62326180cf2eaabaf525858487fe03fe1bef38d9b88633b81e343870ecddeb163c74589055bb66c61ecd8b1b1e4a667cf9edc77df7de8ba9e90a943b35b78bd5ede7bef3d56ac58410656c09bd8064e3d81f919408fb2b2b26f8e1a358a4b2fedf449f47965f4e8d1d4d4d400169049932691969686699ab16618c659dfe3b55028c4eeddbb59b66c1922c263c08fdb5172a2eabc1cd8377cf8706debd6add86cedc5cec465cb962d8c1e3d3af6fdb2cb2ee38e3beee890d69bdad6ad5bd9b8712381408041c01709e04b34acef1f33668cb67dfb761e7df451443a5f646d6868a0a8a888a2a222bea7d459e001860d1b9690dfb7bea7a6a6864d9b36110804f83570245d91d93fa9dd8926acca871e7a888d1b37b260c1024cd3e4e9a79fc6ed769f739f8870faf4690e1d3ac4912347282929e1c489131c3f7e9ca2a2224a4b4ba9afafc71387445dd7494e4eee709eaf9462c3860d343636320d583f7a048e439fa1b9c2ede2ea5044bbfdf6db65c58a1500e4e5e5316bd62cf2f3f3d1759da2a222b66ddbc6d6ad5b3974e810a150a8ddfe92812ca0b8c5b569d3a6919e9edea135fff0e1c3ac58b102d334599a99c9627f0dbbb234f42c8db29da12e890100141616568f1f3f3ebdacac2ca1fb1d580708df02928008e0029a6a48e380b780675b3c3362c408060d1a745e025a5fabacac64f9f2e531c22b74c549b1f1fb94086b07da29f9ac0b090058bb76ad4c9b362d16b5e3890db816f835d03dceefce68d3a313180194b7f8bd4f9f3e8c1b37eebcfd1f3f7e9c8f3ffe985028c40d585bd6eb95429410128d1a143b75e1992b1decd8156813638773db9b6fbe59ad59b3863163c69c93132403538095c042e2838766e082b5c64e6bf5fb891327a8afaf3fe7b96030c8b66ddb58b76e1d4628c443c046ac3a3e8012d004c024d3807e67cc73fa682d9dce6a0a0b0babef9f3933fdf0e79f932c829de6a442c7327f2f90035ca2147d95d0cf840c2c775058a72e260a0d611450dba2fffcfc7caebefa6ac00aac454545ecd8b103bfdf8f07788156e95d144948e99c128362a5f17696c6ebe5913631766a41dffe8f4fe5de1f7c9fa37bf7e146a16399921605a5015e4f32975f974fff9c9ef44a4d21f0d9a7a81dbb4184306028e0f23c7acdb887fadd3b29787b29afb718a3a2a202d33429292961d7ae5d54565602d659ddd34041eb4989022518a6494841c814c291f697eb0e13b061e306f9e1f4e9d4141fc781c286c4fcc8c452840674efd387abf2f3e9df3d975edd32d8b16e2388c2a74c6c28f4c183b976feef503db2c8b8ed76e6b9dd2c7dedcfb172d5c9932779e79d77686c6c042cabf911f0721b731320a484b08288d2d01adb27a0433160d5aa5572ef9ddfa3bcf818214cec08369ab5af68f26f45cf4bfa92ee4e26d5e3417c7e42a52789208494c2183090ab17bc80caed86386de080febf7a9cdb5b8c6518068d8d8d3880c9c05fdb052f180a02a2f0a3b15f4ccada5f8913b78065cb96ca8c1ffc005f4d0d9a1252c53a2bb745416b28246a0d769b4eaf3e7d48732793e27653b1670f2e9f8fb0022d27876be7ff165b4e0ecae604cd86681aa7febc98bb80e54008e80d7c07ab82730bcd8791cd0e1dfda49ab5ec13c52107acefeb64756588eada2e728155ab56c9b4a95309f87d68026e9ac15b9a57688044ff66a4a791969e86c7e3c2ed7472fac86122220492dc5cfff8e3b8fae6a2940dc3aea38be2d8ab7f447bf925c62a8d37c4c40bdcccd9113a7e245310cd28439ac63e37bc36c6cdc9fe0edc675239bdae064eb4fdfe5142042c7ff75d7c3e1fba5238109c58098d9d26b31754f4b31dc8cecec6e372e3763871d874ce949e22aceb8cfaf94f49cbbf1e74856836f44884838b16a1fd7e213d2361ec62c6825bbbcb939218789422ace96cced43998e22a8f94998b7d3567360732a496136d7793500cb8ffc107f8ef37ff8b4179797850b8b0986b6a4de075c0a6203525058fcb4592cd8e8970faf871ae2828e092f1b7a1e9825296bd1c58fc1abcfc0772c2215c22984d569dc8a45adc18528add221cccd08a03bec043e5871b5f3a7dd8d834f492d1dbdbeb22210b187aed500570efd429b276ff7eec58eb7c53c46f5afe9a129ccc8c0c5c4e3b4ebb83706323e9fd0770dd3df7806e0365bd3cb3eb4f0b712c5c448e118ae5054deedcd273cf478600261a4a991802fe017a79ed58e7e29c24d7aaddef95fa005617ad6b175b8796416f4a0a0e9acd1f9aa3bf169d9443c0e34d21c9e1c06eb3a1743b53e6fe0c9bc70d4a81283e5ff657fc0bff489611c24d7c336cca14db169388b2713a4bd83627b33a3d4b5fbe647a89afddc75a488796c1cb075f891d8583666d5be0ade0e7049251646677c3ed70a1db34323d29a4a665a0340d34eb7c2eb4e333bc86894314365131c0f1e4bc24886575b52e838f7e9285ef0ae7dd4ba697fc6f47f04082163079ca6d2a6fe0e05bcb2b2b2d3f152b876f39691d6b75f0ea36b2bb75c36577e0d46d883210cd8c2e92a06c3ad7cc7b84034507318b8e6228b0c541190fb8b4ba5e69d3587d4f7af93f873baefefdb78bcbe33cd2ae24521364ff1707d97364fbf12dffd83cc31692548fd9acb526137261fde7469ac3c988f1b790969a863dc9c59677dfa757cf5cec6eaf75aea02bb4b454bc03f2a85ab3066f38823dc1b067288552105150e6547cf2a3ece2f5dfd02f5d3ced645dc7a15b92b00bd49d0c071c5ef58b60ba865f596b7e186b8f6f62c5043790a4295c0e079a4dc7268adada1ab6bff917cc480843039442b36978467d13cfd871849560b431aea2a5ab0986d8a84e52ec999553bea3c071dd9bf794b55ff669433a14031c6eb5da9163aff7b92de04d26a9d3b4bf57b8535248727b2c82c206015f3dbb57aea064ed1ad06ce07060daec689a46b7390f509f9a8ed9cae055abbf4de318288e5daaf8e0d93e4c7cf9548fdf7da7e4f48580870e129092e5687067d90f491f3bf5766216d0b432a0846e970f4477ba30cd08758d0d94edde455238cc3f5f5b8271a61c250a655a9b37c71583f03e703f215dc7542a464353ca2b2afaa2a202bf43f1e98454fee7c55ef7cd9a7baccb0e273a4440d126bf1c5adf30cc96ad08f476128c461085550c49164873b81011c434894422d81b032403ea741927feb214d314ab0ea0039a8ef7de1904877dc302defad0452cf0b55e8d0f66f760ccaa33eab1db8bfff4fdb7bb27d345d2a9d3cee28f83ca4c127cc92ae6ffc9401aa0f91b0946c2440c033122b882615281145194bff357fc9ffd1d9b802e764cbb42f36692f6e27c1abbe7a25ab98280ef54ae7ddfdf7ed1f7b13b5f2c55003f7abb6fd69b7796375c18ec66e9fc71af29d4db21a859feef069215786d3a4a8bee0c952229ba6b4c42e8e66fa0fcf15f13a92a25a229547d030dbb0a096eda86ad5b7a748dd32d7f578aa22b92f8db2ffbfd7df6bf153ff7d467570e025872e7b184fdfe81d59764b4774fa78f78c261938809018f06f5e0c2c42d60b3390847045d45f0979c44852328acf258b280f3d4294eff6c1e221ab62345786aaab01b26ba98a0744c6560a23839c4cd964707ac0877b7ffe5df770ed31f19b6f38b8ecef195f147abdbbba7d3c124294b856c76cd9ee2d6187ccce05b11931c14de4157e0bcb41f75c5c7683c70889470901c057d059214248915344d05280d4d045309ba680882a914a7ae4c62e78b831f9b32667bfcf7f41290c92f65bb963f541168efbe4e5940bf51eee492c2c677bc39fad8a41c2dd7a61cb88bfcf412a8fc623f27f77d8189c2ab04b7d2f18a810d7088b59d1605ba2814621545a3ae5f97a9537a4f5ff6dd9a31f0a8e9efd699b93549c84f02f5a00bb0004f37dd95ded7f1e39e03ddf9791ed788fc374a075e1d3169c0aaf15763b1db17b882e66ab093e832a73454b48a682a28bbc4f9c9a167f24a2b87273f327de0d6239d9d5747a5d331c05769047c958d2f0fbb3163822bcbe93432f481f60a21036844a800ec28d251b8306315242babb336d0a65288521c1895b27ff7dc7e2ffc7052e18aae8195b85cf04b3f8d6163475d205c549be540a1a12b65d50480de2892317160f9bd2d6a70a612ab9a85c61763d3d838b7dfab5f0578e80202d6be5c5611f4199b6b339d9c5626d562620049283c982d8ec1a2db4865e5f4268aa0078a1feab7e0a7930a5ffc8f6dc3fb5de85c3a235df2da573062d41a5e1d44a8538a10908a908922052b4d8e6efb31a39a0fdb14c7bedfb3aae0b69df300e67e737bf17907b888d22504f86bcdaa804b8868e017c10da462253f764057a02989fe2b99c29704077e7559fdd6821e3fffed27d726b425bf5872c1efba5c31da9b545a1c4c72191a95285211d25131f076ac034b0584743899a31f7d7778f2e707f0fdabfe79e389c5bf3cd6d66ef8ff87f4186c5f9493a9c98b369bbc0fb201e43334398a92332001a5a4bc9b4d3e9fd3bfee836da3ee03f8a8fca68bffd6650272c11670cb4fb25424647f3f5cdf38b3fa5484cc6d3e9c62e251824b29fc3d1d278ede98f645f9949eafc865362dbdbb6d1bc0b8ee1bda3fbbfe12e4ff00e8dbd0e166c8e7ef0000000049454e44ae426082</data>
+ </image>
+</images>
+<layoutdefaults spacing="6" margin="6"/>
+<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/>
+<includes>
+ <include location="local" impldecl="in implementation">hitwidget_layout.ui.h</include>
+</includes>
+</UI>
diff --git a/src/hitwidget_layout.ui.h b/src/hitwidget_layout.ui.h
new file mode 100644
index 0000000..379c5f9
--- /dev/null
+++ b/src/hitwidget_layout.ui.h
@@ -0,0 +1 @@
+#include "kerrylabel.h"
diff --git a/src/icons/FLAGS_LICENCE b/src/icons/FLAGS_LICENCE
new file mode 100644
index 0000000..6584a86
--- /dev/null
+++ b/src/icons/FLAGS_LICENCE
@@ -0,0 +1,3 @@
+Flag images found at http://www.hahn-hotel.com/flags/
+The flags can be used under this Creative Commons License:
+http://creativecommons.org/licenses/by/2.0/de/
diff --git a/src/icons/Makefile.am b/src/icons/Makefile.am
new file mode 100644
index 0000000..1fecb80
--- /dev/null
+++ b/src/icons/Makefile.am
@@ -0,0 +1,5 @@
+KDE_ICON = tork
+
+pics_ICON = AUTO
+picsdir = $(kde_datadir)/tork/icons
+
diff --git a/src/icons/cr16-action-likeback_bug_tork.png b/src/icons/cr16-action-likeback_bug_tork.png
new file mode 100755
index 0000000..1edc6c1
--- /dev/null
+++ b/src/icons/cr16-action-likeback_bug_tork.png
Binary files differ
diff --git a/src/icons/cr16-action-likeback_configure_tork.png b/src/icons/cr16-action-likeback_configure_tork.png
new file mode 100644
index 0000000..7b94f00
--- /dev/null
+++ b/src/icons/cr16-action-likeback_configure_tork.png
Binary files differ
diff --git a/src/icons/cr16-action-likeback_dislike_tork.png b/src/icons/cr16-action-likeback_dislike_tork.png
new file mode 100644
index 0000000..fdc9a13
--- /dev/null
+++ b/src/icons/cr16-action-likeback_dislike_tork.png
Binary files differ
diff --git a/src/icons/cr16-action-likeback_feature_tork.png b/src/icons/cr16-action-likeback_feature_tork.png
new file mode 100755
index 0000000..8d72794
--- /dev/null
+++ b/src/icons/cr16-action-likeback_feature_tork.png
Binary files differ
diff --git a/src/icons/cr16-action-likeback_like_tork.png b/src/icons/cr16-action-likeback_like_tork.png
new file mode 100644
index 0000000..b62b611
--- /dev/null
+++ b/src/icons/cr16-action-likeback_like_tork.png
Binary files differ
diff --git a/src/icons/hi16-action-tork_torsmall.png b/src/icons/hi16-action-tork_torsmall.png
new file mode 100644
index 0000000..e45d573
--- /dev/null
+++ b/src/icons/hi16-action-tork_torsmall.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_19.png b/src/icons/hi16-app-tork_19.png
new file mode 100644
index 0000000..ad14856
--- /dev/null
+++ b/src/icons/hi16-app-tork_19.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_33.png b/src/icons/hi16-app-tork_33.png
new file mode 100644
index 0000000..06fc78c
--- /dev/null
+++ b/src/icons/hi16-app-tork_33.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_FAILED.png b/src/icons/hi16-app-tork_FAILED.png
new file mode 100644
index 0000000..9990797
--- /dev/null
+++ b/src/icons/hi16-app-tork_FAILED.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ad.png b/src/icons/hi16-app-tork_ad.png
new file mode 100644
index 0000000..1626403
--- /dev/null
+++ b/src/icons/hi16-app-tork_ad.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ae.png b/src/icons/hi16-app-tork_ae.png
new file mode 100644
index 0000000..a38d1d4
--- /dev/null
+++ b/src/icons/hi16-app-tork_ae.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_af.png b/src/icons/hi16-app-tork_af.png
new file mode 100644
index 0000000..67c5f86
--- /dev/null
+++ b/src/icons/hi16-app-tork_af.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ag.png b/src/icons/hi16-app-tork_ag.png
new file mode 100644
index 0000000..473e15f
--- /dev/null
+++ b/src/icons/hi16-app-tork_ag.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ai.png b/src/icons/hi16-app-tork_ai.png
new file mode 100644
index 0000000..2ba44b0
--- /dev/null
+++ b/src/icons/hi16-app-tork_ai.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_aim_protocol.png b/src/icons/hi16-app-tork_aim_protocol.png
new file mode 100644
index 0000000..0f28349
--- /dev/null
+++ b/src/icons/hi16-app-tork_aim_protocol.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_al.png b/src/icons/hi16-app-tork_al.png
new file mode 100644
index 0000000..ff1d2ff
--- /dev/null
+++ b/src/icons/hi16-app-tork_al.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_am.png b/src/icons/hi16-app-tork_am.png
new file mode 100644
index 0000000..991ceae
--- /dev/null
+++ b/src/icons/hi16-app-tork_am.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_an.png b/src/icons/hi16-app-tork_an.png
new file mode 100644
index 0000000..008f91f
--- /dev/null
+++ b/src/icons/hi16-app-tork_an.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ao.png b/src/icons/hi16-app-tork_ao.png
new file mode 100644
index 0000000..f2df3b0
--- /dev/null
+++ b/src/icons/hi16-app-tork_ao.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_aq.png b/src/icons/hi16-app-tork_aq.png
new file mode 100644
index 0000000..fb22a45
--- /dev/null
+++ b/src/icons/hi16-app-tork_aq.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ar.png b/src/icons/hi16-app-tork_ar.png
new file mode 100644
index 0000000..5594fcc
--- /dev/null
+++ b/src/icons/hi16-app-tork_ar.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_as.png b/src/icons/hi16-app-tork_as.png
new file mode 100644
index 0000000..712bb62
--- /dev/null
+++ b/src/icons/hi16-app-tork_as.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_at.png b/src/icons/hi16-app-tork_at.png
new file mode 100644
index 0000000..99e81c8
--- /dev/null
+++ b/src/icons/hi16-app-tork_at.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_au.png b/src/icons/hi16-app-tork_au.png
new file mode 100644
index 0000000..f160add
--- /dev/null
+++ b/src/icons/hi16-app-tork_au.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_aw.png b/src/icons/hi16-app-tork_aw.png
new file mode 100644
index 0000000..a970f15
--- /dev/null
+++ b/src/icons/hi16-app-tork_aw.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ax.png b/src/icons/hi16-app-tork_ax.png
new file mode 100644
index 0000000..5b35dc3
--- /dev/null
+++ b/src/icons/hi16-app-tork_ax.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_az.png b/src/icons/hi16-app-tork_az.png
new file mode 100644
index 0000000..f25b2df
--- /dev/null
+++ b/src/icons/hi16-app-tork_az.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ba.png b/src/icons/hi16-app-tork_ba.png
new file mode 100644
index 0000000..6953136
--- /dev/null
+++ b/src/icons/hi16-app-tork_ba.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bb.png b/src/icons/hi16-app-tork_bb.png
new file mode 100644
index 0000000..c1d1403
--- /dev/null
+++ b/src/icons/hi16-app-tork_bb.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bd.png b/src/icons/hi16-app-tork_bd.png
new file mode 100644
index 0000000..afd1295
--- /dev/null
+++ b/src/icons/hi16-app-tork_bd.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_be.png b/src/icons/hi16-app-tork_be.png
new file mode 100644
index 0000000..e0eaa78
--- /dev/null
+++ b/src/icons/hi16-app-tork_be.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bf.png b/src/icons/hi16-app-tork_bf.png
new file mode 100644
index 0000000..c96dc87
--- /dev/null
+++ b/src/icons/hi16-app-tork_bf.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bg.png b/src/icons/hi16-app-tork_bg.png
new file mode 100644
index 0000000..96840c0
--- /dev/null
+++ b/src/icons/hi16-app-tork_bg.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bh.png b/src/icons/hi16-app-tork_bh.png
new file mode 100644
index 0000000..816400e
--- /dev/null
+++ b/src/icons/hi16-app-tork_bh.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bi.png b/src/icons/hi16-app-tork_bi.png
new file mode 100644
index 0000000..2b14a28
--- /dev/null
+++ b/src/icons/hi16-app-tork_bi.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bj.png b/src/icons/hi16-app-tork_bj.png
new file mode 100644
index 0000000..45d1564
--- /dev/null
+++ b/src/icons/hi16-app-tork_bj.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bm.png b/src/icons/hi16-app-tork_bm.png
new file mode 100644
index 0000000..2490b8d
--- /dev/null
+++ b/src/icons/hi16-app-tork_bm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bn.png b/src/icons/hi16-app-tork_bn.png
new file mode 100644
index 0000000..0b055c6
--- /dev/null
+++ b/src/icons/hi16-app-tork_bn.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bo.png b/src/icons/hi16-app-tork_bo.png
new file mode 100644
index 0000000..0363e29
--- /dev/null
+++ b/src/icons/hi16-app-tork_bo.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_br.png b/src/icons/hi16-app-tork_br.png
new file mode 100644
index 0000000..3a29afb
--- /dev/null
+++ b/src/icons/hi16-app-tork_br.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bs.png b/src/icons/hi16-app-tork_bs.png
new file mode 100644
index 0000000..ce6cb8b
--- /dev/null
+++ b/src/icons/hi16-app-tork_bs.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bt.png b/src/icons/hi16-app-tork_bt.png
new file mode 100644
index 0000000..11c312a
--- /dev/null
+++ b/src/icons/hi16-app-tork_bt.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bv.png b/src/icons/hi16-app-tork_bv.png
new file mode 100644
index 0000000..7f67f39
--- /dev/null
+++ b/src/icons/hi16-app-tork_bv.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bw.png b/src/icons/hi16-app-tork_bw.png
new file mode 100644
index 0000000..adb73ef
--- /dev/null
+++ b/src/icons/hi16-app-tork_bw.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_by.png b/src/icons/hi16-app-tork_by.png
new file mode 100644
index 0000000..3f83cbe
--- /dev/null
+++ b/src/icons/hi16-app-tork_by.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_bz.png b/src/icons/hi16-app-tork_bz.png
new file mode 100644
index 0000000..5505c1c
--- /dev/null
+++ b/src/icons/hi16-app-tork_bz.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ca.png b/src/icons/hi16-app-tork_ca.png
new file mode 100644
index 0000000..f14d86c
--- /dev/null
+++ b/src/icons/hi16-app-tork_ca.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cc.png b/src/icons/hi16-app-tork_cc.png
new file mode 100644
index 0000000..07bb8fb
--- /dev/null
+++ b/src/icons/hi16-app-tork_cc.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cd.png b/src/icons/hi16-app-tork_cd.png
new file mode 100644
index 0000000..ba3bc04
--- /dev/null
+++ b/src/icons/hi16-app-tork_cd.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cf.png b/src/icons/hi16-app-tork_cf.png
new file mode 100644
index 0000000..546bf23
--- /dev/null
+++ b/src/icons/hi16-app-tork_cf.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cg.png b/src/icons/hi16-app-tork_cg.png
new file mode 100644
index 0000000..bfd3784
--- /dev/null
+++ b/src/icons/hi16-app-tork_cg.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ch.png b/src/icons/hi16-app-tork_ch.png
new file mode 100644
index 0000000..bdbc492
--- /dev/null
+++ b/src/icons/hi16-app-tork_ch.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ci.png b/src/icons/hi16-app-tork_ci.png
new file mode 100644
index 0000000..cfb3fdc
--- /dev/null
+++ b/src/icons/hi16-app-tork_ci.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ck.png b/src/icons/hi16-app-tork_ck.png
new file mode 100644
index 0000000..8228a9a
--- /dev/null
+++ b/src/icons/hi16-app-tork_ck.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cl.png b/src/icons/hi16-app-tork_cl.png
new file mode 100644
index 0000000..2bda656
--- /dev/null
+++ b/src/icons/hi16-app-tork_cl.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cm.png b/src/icons/hi16-app-tork_cm.png
new file mode 100644
index 0000000..0b1441f
--- /dev/null
+++ b/src/icons/hi16-app-tork_cm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cn.png b/src/icons/hi16-app-tork_cn.png
new file mode 100644
index 0000000..81bdbee
--- /dev/null
+++ b/src/icons/hi16-app-tork_cn.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_co.png b/src/icons/hi16-app-tork_co.png
new file mode 100644
index 0000000..224947c
--- /dev/null
+++ b/src/icons/hi16-app-tork_co.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cr.png b/src/icons/hi16-app-tork_cr.png
new file mode 100644
index 0000000..87d2fd3
--- /dev/null
+++ b/src/icons/hi16-app-tork_cr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cs.png b/src/icons/hi16-app-tork_cs.png
new file mode 100644
index 0000000..1ec1b1a
--- /dev/null
+++ b/src/icons/hi16-app-tork_cs.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cu.png b/src/icons/hi16-app-tork_cu.png
new file mode 100644
index 0000000..f30421a
--- /dev/null
+++ b/src/icons/hi16-app-tork_cu.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cv.png b/src/icons/hi16-app-tork_cv.png
new file mode 100644
index 0000000..42492cc
--- /dev/null
+++ b/src/icons/hi16-app-tork_cv.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cx.png b/src/icons/hi16-app-tork_cx.png
new file mode 100644
index 0000000..86d7a11
--- /dev/null
+++ b/src/icons/hi16-app-tork_cx.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cy.png b/src/icons/hi16-app-tork_cy.png
new file mode 100644
index 0000000..b0cb805
--- /dev/null
+++ b/src/icons/hi16-app-tork_cy.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_cz.png b/src/icons/hi16-app-tork_cz.png
new file mode 100644
index 0000000..d7f67ce
--- /dev/null
+++ b/src/icons/hi16-app-tork_cz.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_de.png b/src/icons/hi16-app-tork_de.png
new file mode 100644
index 0000000..4c8e140
--- /dev/null
+++ b/src/icons/hi16-app-tork_de.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_dj.png b/src/icons/hi16-app-tork_dj.png
new file mode 100644
index 0000000..3c9f7b8
--- /dev/null
+++ b/src/icons/hi16-app-tork_dj.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_dk.png b/src/icons/hi16-app-tork_dk.png
new file mode 100644
index 0000000..02bff52
--- /dev/null
+++ b/src/icons/hi16-app-tork_dk.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_dm.png b/src/icons/hi16-app-tork_dm.png
new file mode 100644
index 0000000..9dc0570
--- /dev/null
+++ b/src/icons/hi16-app-tork_dm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_do.png b/src/icons/hi16-app-tork_do.png
new file mode 100644
index 0000000..6044975
--- /dev/null
+++ b/src/icons/hi16-app-tork_do.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_dz.png b/src/icons/hi16-app-tork_dz.png
new file mode 100644
index 0000000..092f120
--- /dev/null
+++ b/src/icons/hi16-app-tork_dz.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ec.png b/src/icons/hi16-app-tork_ec.png
new file mode 100644
index 0000000..4f88dda
--- /dev/null
+++ b/src/icons/hi16-app-tork_ec.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ee.png b/src/icons/hi16-app-tork_ee.png
new file mode 100644
index 0000000..976ff9a
--- /dev/null
+++ b/src/icons/hi16-app-tork_ee.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_eg.png b/src/icons/hi16-app-tork_eg.png
new file mode 100644
index 0000000..32016b0
--- /dev/null
+++ b/src/icons/hi16-app-tork_eg.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_eh.png b/src/icons/hi16-app-tork_eh.png
new file mode 100644
index 0000000..b91161b
--- /dev/null
+++ b/src/icons/hi16-app-tork_eh.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_er.png b/src/icons/hi16-app-tork_er.png
new file mode 100644
index 0000000..a01d7df
--- /dev/null
+++ b/src/icons/hi16-app-tork_er.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_es.png b/src/icons/hi16-app-tork_es.png
new file mode 100644
index 0000000..c2078c9
--- /dev/null
+++ b/src/icons/hi16-app-tork_es.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_et.png b/src/icons/hi16-app-tork_et.png
new file mode 100644
index 0000000..3bba22f
--- /dev/null
+++ b/src/icons/hi16-app-tork_et.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_eu.png b/src/icons/hi16-app-tork_eu.png
new file mode 100644
index 0000000..137ee96
--- /dev/null
+++ b/src/icons/hi16-app-tork_eu.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_fi.png b/src/icons/hi16-app-tork_fi.png
new file mode 100644
index 0000000..cb7b566
--- /dev/null
+++ b/src/icons/hi16-app-tork_fi.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_fj.png b/src/icons/hi16-app-tork_fj.png
new file mode 100644
index 0000000..4772696
--- /dev/null
+++ b/src/icons/hi16-app-tork_fj.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_fk.png b/src/icons/hi16-app-tork_fk.png
new file mode 100644
index 0000000..16b89e1
--- /dev/null
+++ b/src/icons/hi16-app-tork_fk.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_fm.png b/src/icons/hi16-app-tork_fm.png
new file mode 100644
index 0000000..df87e2d
--- /dev/null
+++ b/src/icons/hi16-app-tork_fm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_fo.png b/src/icons/hi16-app-tork_fo.png
new file mode 100644
index 0000000..f871c20
--- /dev/null
+++ b/src/icons/hi16-app-tork_fo.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_fr.png b/src/icons/hi16-app-tork_fr.png
new file mode 100644
index 0000000..2d0892f
--- /dev/null
+++ b/src/icons/hi16-app-tork_fr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ga.png b/src/icons/hi16-app-tork_ga.png
new file mode 100644
index 0000000..6a0acff
--- /dev/null
+++ b/src/icons/hi16-app-tork_ga.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gadu_protocol.png b/src/icons/hi16-app-tork_gadu_protocol.png
new file mode 100644
index 0000000..9edaf5b
--- /dev/null
+++ b/src/icons/hi16-app-tork_gadu_protocol.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gb.png b/src/icons/hi16-app-tork_gb.png
new file mode 100644
index 0000000..4f727e4
--- /dev/null
+++ b/src/icons/hi16-app-tork_gb.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gd.png b/src/icons/hi16-app-tork_gd.png
new file mode 100644
index 0000000..405556a
--- /dev/null
+++ b/src/icons/hi16-app-tork_gd.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ge.png b/src/icons/hi16-app-tork_ge.png
new file mode 100644
index 0000000..0f22f27
--- /dev/null
+++ b/src/icons/hi16-app-tork_ge.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gf.png b/src/icons/hi16-app-tork_gf.png
new file mode 100644
index 0000000..2d0892f
--- /dev/null
+++ b/src/icons/hi16-app-tork_gf.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gg.png b/src/icons/hi16-app-tork_gg.png
new file mode 100644
index 0000000..fbe3a92
--- /dev/null
+++ b/src/icons/hi16-app-tork_gg.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gh.png b/src/icons/hi16-app-tork_gh.png
new file mode 100644
index 0000000..8665b60
--- /dev/null
+++ b/src/icons/hi16-app-tork_gh.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gi.png b/src/icons/hi16-app-tork_gi.png
new file mode 100644
index 0000000..1b6f9b6
--- /dev/null
+++ b/src/icons/hi16-app-tork_gi.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gl.png b/src/icons/hi16-app-tork_gl.png
new file mode 100644
index 0000000..19169cb
--- /dev/null
+++ b/src/icons/hi16-app-tork_gl.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gm.png b/src/icons/hi16-app-tork_gm.png
new file mode 100644
index 0000000..c97de64
--- /dev/null
+++ b/src/icons/hi16-app-tork_gm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gn.png b/src/icons/hi16-app-tork_gn.png
new file mode 100644
index 0000000..c5c7765
--- /dev/null
+++ b/src/icons/hi16-app-tork_gn.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gp.png b/src/icons/hi16-app-tork_gp.png
new file mode 100644
index 0000000..2d0892f
--- /dev/null
+++ b/src/icons/hi16-app-tork_gp.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gq.png b/src/icons/hi16-app-tork_gq.png
new file mode 100644
index 0000000..a5b4c9e
--- /dev/null
+++ b/src/icons/hi16-app-tork_gq.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gr.png b/src/icons/hi16-app-tork_gr.png
new file mode 100644
index 0000000..ec21bdf
--- /dev/null
+++ b/src/icons/hi16-app-tork_gr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_groupwise_protocol.png b/src/icons/hi16-app-tork_groupwise_protocol.png
new file mode 100644
index 0000000..8353eb9
--- /dev/null
+++ b/src/icons/hi16-app-tork_groupwise_protocol.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gs.png b/src/icons/hi16-app-tork_gs.png
new file mode 100644
index 0000000..1bb8aec
--- /dev/null
+++ b/src/icons/hi16-app-tork_gs.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gt.png b/src/icons/hi16-app-tork_gt.png
new file mode 100644
index 0000000..eca08d2
--- /dev/null
+++ b/src/icons/hi16-app-tork_gt.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gu.png b/src/icons/hi16-app-tork_gu.png
new file mode 100644
index 0000000..e0edc03
--- /dev/null
+++ b/src/icons/hi16-app-tork_gu.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gw.png b/src/icons/hi16-app-tork_gw.png
new file mode 100644
index 0000000..1c95cd0
--- /dev/null
+++ b/src/icons/hi16-app-tork_gw.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_gy.png b/src/icons/hi16-app-tork_gy.png
new file mode 100644
index 0000000..06d7c7f
--- /dev/null
+++ b/src/icons/hi16-app-tork_gy.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_hk.png b/src/icons/hi16-app-tork_hk.png
new file mode 100644
index 0000000..d0bc24f
--- /dev/null
+++ b/src/icons/hi16-app-tork_hk.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_hm.png b/src/icons/hi16-app-tork_hm.png
new file mode 100644
index 0000000..71fe874
--- /dev/null
+++ b/src/icons/hi16-app-tork_hm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_hn.png b/src/icons/hi16-app-tork_hn.png
new file mode 100644
index 0000000..a4731d7
--- /dev/null
+++ b/src/icons/hi16-app-tork_hn.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_hr.png b/src/icons/hi16-app-tork_hr.png
new file mode 100644
index 0000000..f2ce5f7
--- /dev/null
+++ b/src/icons/hi16-app-tork_hr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ht.png b/src/icons/hi16-app-tork_ht.png
new file mode 100644
index 0000000..390fb97
--- /dev/null
+++ b/src/icons/hi16-app-tork_ht.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_hu.png b/src/icons/hi16-app-tork_hu.png
new file mode 100644
index 0000000..6a42fe1
--- /dev/null
+++ b/src/icons/hi16-app-tork_hu.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_icq_protocol.png b/src/icons/hi16-app-tork_icq_protocol.png
new file mode 100644
index 0000000..4f14e00
--- /dev/null
+++ b/src/icons/hi16-app-tork_icq_protocol.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_id.png b/src/icons/hi16-app-tork_id.png
new file mode 100644
index 0000000..71526bb
--- /dev/null
+++ b/src/icons/hi16-app-tork_id.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ie.png b/src/icons/hi16-app-tork_ie.png
new file mode 100644
index 0000000..6f0e754
--- /dev/null
+++ b/src/icons/hi16-app-tork_ie.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_il.png b/src/icons/hi16-app-tork_il.png
new file mode 100644
index 0000000..eb5b901
--- /dev/null
+++ b/src/icons/hi16-app-tork_il.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_in.png b/src/icons/hi16-app-tork_in.png
new file mode 100644
index 0000000..4f23f9d
--- /dev/null
+++ b/src/icons/hi16-app-tork_in.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_io.png b/src/icons/hi16-app-tork_io.png
new file mode 100644
index 0000000..1174685
--- /dev/null
+++ b/src/icons/hi16-app-tork_io.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_iq.png b/src/icons/hi16-app-tork_iq.png
new file mode 100644
index 0000000..48720e5
--- /dev/null
+++ b/src/icons/hi16-app-tork_iq.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ir.png b/src/icons/hi16-app-tork_ir.png
new file mode 100644
index 0000000..b50b539
--- /dev/null
+++ b/src/icons/hi16-app-tork_ir.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_irc_protocol.png b/src/icons/hi16-app-tork_irc_protocol.png
new file mode 100644
index 0000000..7ea87c8
--- /dev/null
+++ b/src/icons/hi16-app-tork_irc_protocol.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_is.png b/src/icons/hi16-app-tork_is.png
new file mode 100644
index 0000000..5ad1e1c
--- /dev/null
+++ b/src/icons/hi16-app-tork_is.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_it.png b/src/icons/hi16-app-tork_it.png
new file mode 100644
index 0000000..8e8971d
--- /dev/null
+++ b/src/icons/hi16-app-tork_it.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_jabber_protocol.png b/src/icons/hi16-app-tork_jabber_protocol.png
new file mode 100644
index 0000000..a9a1477
--- /dev/null
+++ b/src/icons/hi16-app-tork_jabber_protocol.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_je.png b/src/icons/hi16-app-tork_je.png
new file mode 100644
index 0000000..ac7309a
--- /dev/null
+++ b/src/icons/hi16-app-tork_je.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_jm.png b/src/icons/hi16-app-tork_jm.png
new file mode 100644
index 0000000..462b18c
--- /dev/null
+++ b/src/icons/hi16-app-tork_jm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_jo.png b/src/icons/hi16-app-tork_jo.png
new file mode 100644
index 0000000..e9bf4ab
--- /dev/null
+++ b/src/icons/hi16-app-tork_jo.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_jp.png b/src/icons/hi16-app-tork_jp.png
new file mode 100644
index 0000000..d0a0bd5
--- /dev/null
+++ b/src/icons/hi16-app-tork_jp.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ke.png b/src/icons/hi16-app-tork_ke.png
new file mode 100644
index 0000000..bc5357e
--- /dev/null
+++ b/src/icons/hi16-app-tork_ke.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_kg.png b/src/icons/hi16-app-tork_kg.png
new file mode 100644
index 0000000..9c32663
--- /dev/null
+++ b/src/icons/hi16-app-tork_kg.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_kh.png b/src/icons/hi16-app-tork_kh.png
new file mode 100644
index 0000000..f001381
--- /dev/null
+++ b/src/icons/hi16-app-tork_kh.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ki.png b/src/icons/hi16-app-tork_ki.png
new file mode 100644
index 0000000..9f153e7
--- /dev/null
+++ b/src/icons/hi16-app-tork_ki.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_km.png b/src/icons/hi16-app-tork_km.png
new file mode 100644
index 0000000..6847889
--- /dev/null
+++ b/src/icons/hi16-app-tork_km.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_kn.png b/src/icons/hi16-app-tork_kn.png
new file mode 100644
index 0000000..03c3906
--- /dev/null
+++ b/src/icons/hi16-app-tork_kn.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_konqueroroff.png b/src/icons/hi16-app-tork_konqueroroff.png
new file mode 100644
index 0000000..dd0681e
--- /dev/null
+++ b/src/icons/hi16-app-tork_konqueroroff.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_konqueroron.png b/src/icons/hi16-app-tork_konqueroron.png
new file mode 100644
index 0000000..f599408
--- /dev/null
+++ b/src/icons/hi16-app-tork_konqueroron.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_kp.png b/src/icons/hi16-app-tork_kp.png
new file mode 100644
index 0000000..7738e91
--- /dev/null
+++ b/src/icons/hi16-app-tork_kp.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_kr.png b/src/icons/hi16-app-tork_kr.png
new file mode 100644
index 0000000..0fb400c
--- /dev/null
+++ b/src/icons/hi16-app-tork_kr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_kw.png b/src/icons/hi16-app-tork_kw.png
new file mode 100644
index 0000000..7d1b73d
--- /dev/null
+++ b/src/icons/hi16-app-tork_kw.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ky.png b/src/icons/hi16-app-tork_ky.png
new file mode 100644
index 0000000..badf6aa
--- /dev/null
+++ b/src/icons/hi16-app-tork_ky.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_kz.png b/src/icons/hi16-app-tork_kz.png
new file mode 100644
index 0000000..c34d835
--- /dev/null
+++ b/src/icons/hi16-app-tork_kz.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_la.png b/src/icons/hi16-app-tork_la.png
new file mode 100644
index 0000000..211b507
--- /dev/null
+++ b/src/icons/hi16-app-tork_la.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_lb.png b/src/icons/hi16-app-tork_lb.png
new file mode 100644
index 0000000..c34b10e
--- /dev/null
+++ b/src/icons/hi16-app-tork_lb.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_lc.png b/src/icons/hi16-app-tork_lc.png
new file mode 100644
index 0000000..8d41e11
--- /dev/null
+++ b/src/icons/hi16-app-tork_lc.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_li.png b/src/icons/hi16-app-tork_li.png
new file mode 100644
index 0000000..4bf6a60
--- /dev/null
+++ b/src/icons/hi16-app-tork_li.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_lk.png b/src/icons/hi16-app-tork_lk.png
new file mode 100644
index 0000000..2f56a7f
--- /dev/null
+++ b/src/icons/hi16-app-tork_lk.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_lr.png b/src/icons/hi16-app-tork_lr.png
new file mode 100644
index 0000000..cef52ea
--- /dev/null
+++ b/src/icons/hi16-app-tork_lr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ls.png b/src/icons/hi16-app-tork_ls.png
new file mode 100644
index 0000000..5937aa6
--- /dev/null
+++ b/src/icons/hi16-app-tork_ls.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_lt.png b/src/icons/hi16-app-tork_lt.png
new file mode 100644
index 0000000..26c119e
--- /dev/null
+++ b/src/icons/hi16-app-tork_lt.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_lu.png b/src/icons/hi16-app-tork_lu.png
new file mode 100644
index 0000000..155f4da
--- /dev/null
+++ b/src/icons/hi16-app-tork_lu.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_lv.png b/src/icons/hi16-app-tork_lv.png
new file mode 100644
index 0000000..6bfd2fb
--- /dev/null
+++ b/src/icons/hi16-app-tork_lv.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ly.png b/src/icons/hi16-app-tork_ly.png
new file mode 100644
index 0000000..ef9a6ba
--- /dev/null
+++ b/src/icons/hi16-app-tork_ly.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ma.png b/src/icons/hi16-app-tork_ma.png
new file mode 100644
index 0000000..2e04a8b
--- /dev/null
+++ b/src/icons/hi16-app-tork_ma.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mc.png b/src/icons/hi16-app-tork_mc.png
new file mode 100644
index 0000000..0d76fa8
--- /dev/null
+++ b/src/icons/hi16-app-tork_mc.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_md.png b/src/icons/hi16-app-tork_md.png
new file mode 100644
index 0000000..ba07201
--- /dev/null
+++ b/src/icons/hi16-app-tork_md.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_me.png b/src/icons/hi16-app-tork_me.png
new file mode 100644
index 0000000..2654bca
--- /dev/null
+++ b/src/icons/hi16-app-tork_me.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mg.png b/src/icons/hi16-app-tork_mg.png
new file mode 100644
index 0000000..218e6df
--- /dev/null
+++ b/src/icons/hi16-app-tork_mg.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mh.png b/src/icons/hi16-app-tork_mh.png
new file mode 100644
index 0000000..4a7c87c
--- /dev/null
+++ b/src/icons/hi16-app-tork_mh.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mk.png b/src/icons/hi16-app-tork_mk.png
new file mode 100644
index 0000000..c34fbf2
--- /dev/null
+++ b/src/icons/hi16-app-tork_mk.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ml.png b/src/icons/hi16-app-tork_ml.png
new file mode 100644
index 0000000..aab4a45
--- /dev/null
+++ b/src/icons/hi16-app-tork_ml.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mm.png b/src/icons/hi16-app-tork_mm.png
new file mode 100644
index 0000000..bd406ab
--- /dev/null
+++ b/src/icons/hi16-app-tork_mm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mn.png b/src/icons/hi16-app-tork_mn.png
new file mode 100644
index 0000000..e13cbe4
--- /dev/null
+++ b/src/icons/hi16-app-tork_mn.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mo.png b/src/icons/hi16-app-tork_mo.png
new file mode 100644
index 0000000..a2f24ff
--- /dev/null
+++ b/src/icons/hi16-app-tork_mo.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mp.png b/src/icons/hi16-app-tork_mp.png
new file mode 100644
index 0000000..3a99331
--- /dev/null
+++ b/src/icons/hi16-app-tork_mp.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mq.png b/src/icons/hi16-app-tork_mq.png
new file mode 100644
index 0000000..2d0892f
--- /dev/null
+++ b/src/icons/hi16-app-tork_mq.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mr.png b/src/icons/hi16-app-tork_mr.png
new file mode 100644
index 0000000..16b4718
--- /dev/null
+++ b/src/icons/hi16-app-tork_mr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ms.png b/src/icons/hi16-app-tork_ms.png
new file mode 100644
index 0000000..162a8a9
--- /dev/null
+++ b/src/icons/hi16-app-tork_ms.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_msn_protocol.png b/src/icons/hi16-app-tork_msn_protocol.png
new file mode 100644
index 0000000..054b0d2
--- /dev/null
+++ b/src/icons/hi16-app-tork_msn_protocol.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mt.png b/src/icons/hi16-app-tork_mt.png
new file mode 100644
index 0000000..2d8d3e7
--- /dev/null
+++ b/src/icons/hi16-app-tork_mt.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mu.png b/src/icons/hi16-app-tork_mu.png
new file mode 100644
index 0000000..b6c9c14
--- /dev/null
+++ b/src/icons/hi16-app-tork_mu.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mv.png b/src/icons/hi16-app-tork_mv.png
new file mode 100644
index 0000000..79a273e
--- /dev/null
+++ b/src/icons/hi16-app-tork_mv.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mw.png b/src/icons/hi16-app-tork_mw.png
new file mode 100644
index 0000000..4d0524d
--- /dev/null
+++ b/src/icons/hi16-app-tork_mw.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mx.png b/src/icons/hi16-app-tork_mx.png
new file mode 100644
index 0000000..0ee779a
--- /dev/null
+++ b/src/icons/hi16-app-tork_mx.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_my.png b/src/icons/hi16-app-tork_my.png
new file mode 100644
index 0000000..beec3ad
--- /dev/null
+++ b/src/icons/hi16-app-tork_my.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_mz.png b/src/icons/hi16-app-tork_mz.png
new file mode 100644
index 0000000..f75c834
--- /dev/null
+++ b/src/icons/hi16-app-tork_mz.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_na.png b/src/icons/hi16-app-tork_na.png
new file mode 100644
index 0000000..0a47063
--- /dev/null
+++ b/src/icons/hi16-app-tork_na.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_nc.png b/src/icons/hi16-app-tork_nc.png
new file mode 100644
index 0000000..2d0892f
--- /dev/null
+++ b/src/icons/hi16-app-tork_nc.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ne.png b/src/icons/hi16-app-tork_ne.png
new file mode 100644
index 0000000..5e70b40
--- /dev/null
+++ b/src/icons/hi16-app-tork_ne.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_nf.png b/src/icons/hi16-app-tork_nf.png
new file mode 100644
index 0000000..2e5e4b9
--- /dev/null
+++ b/src/icons/hi16-app-tork_nf.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ng.png b/src/icons/hi16-app-tork_ng.png
new file mode 100644
index 0000000..f231654
--- /dev/null
+++ b/src/icons/hi16-app-tork_ng.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ni.png b/src/icons/hi16-app-tork_ni.png
new file mode 100644
index 0000000..87f818f
--- /dev/null
+++ b/src/icons/hi16-app-tork_ni.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_nl.png b/src/icons/hi16-app-tork_nl.png
new file mode 100644
index 0000000..eb0f3af
--- /dev/null
+++ b/src/icons/hi16-app-tork_nl.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_no.png b/src/icons/hi16-app-tork_no.png
new file mode 100644
index 0000000..7f67f39
--- /dev/null
+++ b/src/icons/hi16-app-tork_no.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_np.png b/src/icons/hi16-app-tork_np.png
new file mode 100644
index 0000000..ffe524a
--- /dev/null
+++ b/src/icons/hi16-app-tork_np.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_nr.png b/src/icons/hi16-app-tork_nr.png
new file mode 100644
index 0000000..1e0c199
--- /dev/null
+++ b/src/icons/hi16-app-tork_nr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_nu.png b/src/icons/hi16-app-tork_nu.png
new file mode 100644
index 0000000..12877de
--- /dev/null
+++ b/src/icons/hi16-app-tork_nu.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_nz.png b/src/icons/hi16-app-tork_nz.png
new file mode 100644
index 0000000..700d59e
--- /dev/null
+++ b/src/icons/hi16-app-tork_nz.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_om.png b/src/icons/hi16-app-tork_om.png
new file mode 100644
index 0000000..a861e7a
--- /dev/null
+++ b/src/icons/hi16-app-tork_om.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pa.png b/src/icons/hi16-app-tork_pa.png
new file mode 100644
index 0000000..85aa92b
--- /dev/null
+++ b/src/icons/hi16-app-tork_pa.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pe.png b/src/icons/hi16-app-tork_pe.png
new file mode 100644
index 0000000..d7866d9
--- /dev/null
+++ b/src/icons/hi16-app-tork_pe.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pf.png b/src/icons/hi16-app-tork_pf.png
new file mode 100644
index 0000000..93d930f
--- /dev/null
+++ b/src/icons/hi16-app-tork_pf.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pg.png b/src/icons/hi16-app-tork_pg.png
new file mode 100644
index 0000000..c428c69
--- /dev/null
+++ b/src/icons/hi16-app-tork_pg.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ph.png b/src/icons/hi16-app-tork_ph.png
new file mode 100644
index 0000000..695e497
--- /dev/null
+++ b/src/icons/hi16-app-tork_ph.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pk.png b/src/icons/hi16-app-tork_pk.png
new file mode 100644
index 0000000..826fadf
--- /dev/null
+++ b/src/icons/hi16-app-tork_pk.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pl.png b/src/icons/hi16-app-tork_pl.png
new file mode 100644
index 0000000..4b8c0fc
--- /dev/null
+++ b/src/icons/hi16-app-tork_pl.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pm.png b/src/icons/hi16-app-tork_pm.png
new file mode 100644
index 0000000..2d0892f
--- /dev/null
+++ b/src/icons/hi16-app-tork_pm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pn.png b/src/icons/hi16-app-tork_pn.png
new file mode 100644
index 0000000..88109b9
--- /dev/null
+++ b/src/icons/hi16-app-tork_pn.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pr.png b/src/icons/hi16-app-tork_pr.png
new file mode 100644
index 0000000..05329cc
--- /dev/null
+++ b/src/icons/hi16-app-tork_pr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ps.png b/src/icons/hi16-app-tork_ps.png
new file mode 100644
index 0000000..dee693b
--- /dev/null
+++ b/src/icons/hi16-app-tork_ps.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pt.png b/src/icons/hi16-app-tork_pt.png
new file mode 100644
index 0000000..e30c99b
--- /dev/null
+++ b/src/icons/hi16-app-tork_pt.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_pw.png b/src/icons/hi16-app-tork_pw.png
new file mode 100644
index 0000000..044b9a6
--- /dev/null
+++ b/src/icons/hi16-app-tork_pw.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_py.png b/src/icons/hi16-app-tork_py.png
new file mode 100644
index 0000000..a219b43
--- /dev/null
+++ b/src/icons/hi16-app-tork_py.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_qa.png b/src/icons/hi16-app-tork_qa.png
new file mode 100644
index 0000000..b80c601
--- /dev/null
+++ b/src/icons/hi16-app-tork_qa.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_re.png b/src/icons/hi16-app-tork_re.png
new file mode 100644
index 0000000..2d0892f
--- /dev/null
+++ b/src/icons/hi16-app-tork_re.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ro.png b/src/icons/hi16-app-tork_ro.png
new file mode 100644
index 0000000..8908ff7
--- /dev/null
+++ b/src/icons/hi16-app-tork_ro.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_rs.png b/src/icons/hi16-app-tork_rs.png
new file mode 100644
index 0000000..91dea92
--- /dev/null
+++ b/src/icons/hi16-app-tork_rs.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_rs.woa.png b/src/icons/hi16-app-tork_rs.woa.png
new file mode 100644
index 0000000..b90f732
--- /dev/null
+++ b/src/icons/hi16-app-tork_rs.woa.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ru.png b/src/icons/hi16-app-tork_ru.png
new file mode 100644
index 0000000..6106596
--- /dev/null
+++ b/src/icons/hi16-app-tork_ru.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_rw.png b/src/icons/hi16-app-tork_rw.png
new file mode 100644
index 0000000..200fe22
--- /dev/null
+++ b/src/icons/hi16-app-tork_rw.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sa.png b/src/icons/hi16-app-tork_sa.png
new file mode 100644
index 0000000..4a4bee2
--- /dev/null
+++ b/src/icons/hi16-app-tork_sa.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sb.png b/src/icons/hi16-app-tork_sb.png
new file mode 100644
index 0000000..1a39b69
--- /dev/null
+++ b/src/icons/hi16-app-tork_sb.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sc.png b/src/icons/hi16-app-tork_sc.png
new file mode 100644
index 0000000..25acc0f
--- /dev/null
+++ b/src/icons/hi16-app-tork_sc.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sd.png b/src/icons/hi16-app-tork_sd.png
new file mode 100644
index 0000000..d01001c
--- /dev/null
+++ b/src/icons/hi16-app-tork_sd.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_se.png b/src/icons/hi16-app-tork_se.png
new file mode 100644
index 0000000..7d94199
--- /dev/null
+++ b/src/icons/hi16-app-tork_se.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sg.png b/src/icons/hi16-app-tork_sg.png
new file mode 100644
index 0000000..9727b34
--- /dev/null
+++ b/src/icons/hi16-app-tork_sg.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sh.png b/src/icons/hi16-app-tork_sh.png
new file mode 100644
index 0000000..79f86da
--- /dev/null
+++ b/src/icons/hi16-app-tork_sh.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_si.png b/src/icons/hi16-app-tork_si.png
new file mode 100644
index 0000000..3a03f4a
--- /dev/null
+++ b/src/icons/hi16-app-tork_si.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sj.png b/src/icons/hi16-app-tork_sj.png
new file mode 100644
index 0000000..7f67f39
--- /dev/null
+++ b/src/icons/hi16-app-tork_sj.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sk.png b/src/icons/hi16-app-tork_sk.png
new file mode 100644
index 0000000..eadebd6
--- /dev/null
+++ b/src/icons/hi16-app-tork_sk.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sl.png b/src/icons/hi16-app-tork_sl.png
new file mode 100644
index 0000000..687cf7a
--- /dev/null
+++ b/src/icons/hi16-app-tork_sl.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sm.png b/src/icons/hi16-app-tork_sm.png
new file mode 100644
index 0000000..ce136fa
--- /dev/null
+++ b/src/icons/hi16-app-tork_sm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sms_protocol.png b/src/icons/hi16-app-tork_sms_protocol.png
new file mode 100644
index 0000000..080663f
--- /dev/null
+++ b/src/icons/hi16-app-tork_sms_protocol.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sn.png b/src/icons/hi16-app-tork_sn.png
new file mode 100644
index 0000000..3ba5558
--- /dev/null
+++ b/src/icons/hi16-app-tork_sn.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_so.png b/src/icons/hi16-app-tork_so.png
new file mode 100644
index 0000000..e67e4cc
--- /dev/null
+++ b/src/icons/hi16-app-tork_so.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sr.png b/src/icons/hi16-app-tork_sr.png
new file mode 100644
index 0000000..c67258a
--- /dev/null
+++ b/src/icons/hi16-app-tork_sr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_st.png b/src/icons/hi16-app-tork_st.png
new file mode 100644
index 0000000..93f6cc8
--- /dev/null
+++ b/src/icons/hi16-app-tork_st.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sv.png b/src/icons/hi16-app-tork_sv.png
new file mode 100644
index 0000000..44962d4
--- /dev/null
+++ b/src/icons/hi16-app-tork_sv.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sy.png b/src/icons/hi16-app-tork_sy.png
new file mode 100644
index 0000000..4711c19
--- /dev/null
+++ b/src/icons/hi16-app-tork_sy.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_sz.png b/src/icons/hi16-app-tork_sz.png
new file mode 100644
index 0000000..b198278
--- /dev/null
+++ b/src/icons/hi16-app-tork_sz.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tc.png b/src/icons/hi16-app-tork_tc.png
new file mode 100644
index 0000000..cd58e3c
--- /dev/null
+++ b/src/icons/hi16-app-tork_tc.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_td.png b/src/icons/hi16-app-tork_td.png
new file mode 100644
index 0000000..8908ff7
--- /dev/null
+++ b/src/icons/hi16-app-tork_td.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_testbed_protocol.png b/src/icons/hi16-app-tork_testbed_protocol.png
new file mode 100644
index 0000000..36b1d22
--- /dev/null
+++ b/src/icons/hi16-app-tork_testbed_protocol.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tf.png b/src/icons/hi16-app-tork_tf.png
new file mode 100644
index 0000000..d573df5
--- /dev/null
+++ b/src/icons/hi16-app-tork_tf.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tg.png b/src/icons/hi16-app-tork_tg.png
new file mode 100644
index 0000000..8164f65
--- /dev/null
+++ b/src/icons/hi16-app-tork_tg.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_th.png b/src/icons/hi16-app-tork_th.png
new file mode 100644
index 0000000..bab12be
--- /dev/null
+++ b/src/icons/hi16-app-tork_th.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tj.png b/src/icons/hi16-app-tork_tj.png
new file mode 100644
index 0000000..57e22f5
--- /dev/null
+++ b/src/icons/hi16-app-tork_tj.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tk.png b/src/icons/hi16-app-tork_tk.png
new file mode 100644
index 0000000..700d59e
--- /dev/null
+++ b/src/icons/hi16-app-tork_tk.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tl.png b/src/icons/hi16-app-tork_tl.png
new file mode 100644
index 0000000..21949df
--- /dev/null
+++ b/src/icons/hi16-app-tork_tl.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tm.png b/src/icons/hi16-app-tork_tm.png
new file mode 100644
index 0000000..e507c6b
--- /dev/null
+++ b/src/icons/hi16-app-tork_tm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tn.png b/src/icons/hi16-app-tork_tn.png
new file mode 100644
index 0000000..70a28a9
--- /dev/null
+++ b/src/icons/hi16-app-tork_tn.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_to.png b/src/icons/hi16-app-tork_to.png
new file mode 100644
index 0000000..7324ab8
--- /dev/null
+++ b/src/icons/hi16-app-tork_to.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tp.png b/src/icons/hi16-app-tork_tp.png
new file mode 100644
index 0000000..6fe0055
--- /dev/null
+++ b/src/icons/hi16-app-tork_tp.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tr.png b/src/icons/hi16-app-tork_tr.png
new file mode 100644
index 0000000..fc9f650
--- /dev/null
+++ b/src/icons/hi16-app-tork_tr.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tt.png b/src/icons/hi16-app-tork_tt.png
new file mode 100644
index 0000000..012e0a2
--- /dev/null
+++ b/src/icons/hi16-app-tork_tt.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tv.png b/src/icons/hi16-app-tork_tv.png
new file mode 100644
index 0000000..cd39a2d
--- /dev/null
+++ b/src/icons/hi16-app-tork_tv.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tw.png b/src/icons/hi16-app-tork_tw.png
new file mode 100644
index 0000000..77bdb6d
--- /dev/null
+++ b/src/icons/hi16-app-tork_tw.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_tz.png b/src/icons/hi16-app-tork_tz.png
new file mode 100644
index 0000000..346c1da
--- /dev/null
+++ b/src/icons/hi16-app-tork_tz.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ua.png b/src/icons/hi16-app-tork_ua.png
new file mode 100644
index 0000000..4eb5632
--- /dev/null
+++ b/src/icons/hi16-app-tork_ua.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ug.png b/src/icons/hi16-app-tork_ug.png
new file mode 100644
index 0000000..3bead34
--- /dev/null
+++ b/src/icons/hi16-app-tork_ug.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_um.png b/src/icons/hi16-app-tork_um.png
new file mode 100644
index 0000000..393e97f
--- /dev/null
+++ b/src/icons/hi16-app-tork_um.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_us.png b/src/icons/hi16-app-tork_us.png
new file mode 100644
index 0000000..393e97f
--- /dev/null
+++ b/src/icons/hi16-app-tork_us.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_uy.png b/src/icons/hi16-app-tork_uy.png
new file mode 100644
index 0000000..ead435e
--- /dev/null
+++ b/src/icons/hi16-app-tork_uy.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_uz.png b/src/icons/hi16-app-tork_uz.png
new file mode 100644
index 0000000..a6a372f
--- /dev/null
+++ b/src/icons/hi16-app-tork_uz.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_va.png b/src/icons/hi16-app-tork_va.png
new file mode 100644
index 0000000..9d60eaa
--- /dev/null
+++ b/src/icons/hi16-app-tork_va.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_vc.png b/src/icons/hi16-app-tork_vc.png
new file mode 100644
index 0000000..f9d3e5f
--- /dev/null
+++ b/src/icons/hi16-app-tork_vc.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ve.png b/src/icons/hi16-app-tork_ve.png
new file mode 100644
index 0000000..1cd2b0f
--- /dev/null
+++ b/src/icons/hi16-app-tork_ve.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_vg.png b/src/icons/hi16-app-tork_vg.png
new file mode 100644
index 0000000..8a09386
--- /dev/null
+++ b/src/icons/hi16-app-tork_vg.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_vi.png b/src/icons/hi16-app-tork_vi.png
new file mode 100644
index 0000000..aafc321
--- /dev/null
+++ b/src/icons/hi16-app-tork_vi.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_vn.png b/src/icons/hi16-app-tork_vn.png
new file mode 100644
index 0000000..7fb59f4
--- /dev/null
+++ b/src/icons/hi16-app-tork_vn.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_vu.png b/src/icons/hi16-app-tork_vu.png
new file mode 100644
index 0000000..4d84240
--- /dev/null
+++ b/src/icons/hi16-app-tork_vu.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_wf.png b/src/icons/hi16-app-tork_wf.png
new file mode 100644
index 0000000..2d0892f
--- /dev/null
+++ b/src/icons/hi16-app-tork_wf.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ws.png b/src/icons/hi16-app-tork_ws.png
new file mode 100644
index 0000000..ec4e0fa
--- /dev/null
+++ b/src/icons/hi16-app-tork_ws.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_yahoo_protocol.png b/src/icons/hi16-app-tork_yahoo_protocol.png
new file mode 100644
index 0000000..6c45d3d
--- /dev/null
+++ b/src/icons/hi16-app-tork_yahoo_protocol.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_ye.png b/src/icons/hi16-app-tork_ye.png
new file mode 100644
index 0000000..4dfc768
--- /dev/null
+++ b/src/icons/hi16-app-tork_ye.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_yt.png b/src/icons/hi16-app-tork_yt.png
new file mode 100644
index 0000000..2d0892f
--- /dev/null
+++ b/src/icons/hi16-app-tork_yt.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_yu.png b/src/icons/hi16-app-tork_yu.png
new file mode 100644
index 0000000..1ec1b1a
--- /dev/null
+++ b/src/icons/hi16-app-tork_yu.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_za.png b/src/icons/hi16-app-tork_za.png
new file mode 100644
index 0000000..ae2f5ad
--- /dev/null
+++ b/src/icons/hi16-app-tork_za.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_zm.png b/src/icons/hi16-app-tork_zm.png
new file mode 100644
index 0000000..28ea9f8
--- /dev/null
+++ b/src/icons/hi16-app-tork_zm.png
Binary files differ
diff --git a/src/icons/hi16-app-tork_zw.png b/src/icons/hi16-app-tork_zw.png
new file mode 100644
index 0000000..42dd716
--- /dev/null
+++ b/src/icons/hi16-app-tork_zw.png
Binary files differ
diff --git a/src/icons/hi22-action-tokr_green.png b/src/icons/hi22-action-tokr_green.png
new file mode 100644
index 0000000..f63b742
--- /dev/null
+++ b/src/icons/hi22-action-tokr_green.png
Binary files differ
diff --git a/src/icons/hi22-action-tork.png b/src/icons/hi22-action-tork.png
new file mode 100644
index 0000000..ececd8d
--- /dev/null
+++ b/src/icons/hi22-action-tork.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_green.png b/src/icons/hi22-action-tork_green.png
new file mode 100644
index 0000000..a6b7499
--- /dev/null
+++ b/src/icons/hi22-action-tork_green.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_green_exit.png b/src/icons/hi22-action-tork_green_exit.png
new file mode 100644
index 0000000..7dd5875
--- /dev/null
+++ b/src/icons/hi22-action-tork_green_exit.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_guard_detached.png b/src/icons/hi22-action-tork_guard_detached.png
new file mode 100644
index 0000000..791a1b3
--- /dev/null
+++ b/src/icons/hi22-action-tork_guard_detached.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_guard_down.png b/src/icons/hi22-action-tork_guard_down.png
new file mode 100644
index 0000000..63089e9
--- /dev/null
+++ b/src/icons/hi22-action-tork_guard_down.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_guard_little.png b/src/icons/hi22-action-tork_guard_little.png
new file mode 100644
index 0000000..0b26d9f
--- /dev/null
+++ b/src/icons/hi22-action-tork_guard_little.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_guard_red.png b/src/icons/hi22-action-tork_guard_red.png
new file mode 100644
index 0000000..a6eb9ea
--- /dev/null
+++ b/src/icons/hi22-action-tork_guard_red.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_guard_unlisted.png b/src/icons/hi22-action-tork_guard_unlisted.png
new file mode 100644
index 0000000..4b29151
--- /dev/null
+++ b/src/icons/hi22-action-tork_guard_unlisted.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_guard_unusable.png b/src/icons/hi22-action-tork_guard_unusable.png
new file mode 100644
index 0000000..2228639
--- /dev/null
+++ b/src/icons/hi22-action-tork_guard_unusable.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_guard_up.png b/src/icons/hi22-action-tork_guard_up.png
new file mode 100644
index 0000000..351df87
--- /dev/null
+++ b/src/icons/hi22-action-tork_guard_up.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_konqueror_https.png b/src/icons/hi22-action-tork_konqueror_https.png
new file mode 100644
index 0000000..aa97c0d
--- /dev/null
+++ b/src/icons/hi22-action-tork_konqueror_https.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_konsole_https.png b/src/icons/hi22-action-tork_konsole_https.png
new file mode 100644
index 0000000..118c734
--- /dev/null
+++ b/src/icons/hi22-action-tork_konsole_https.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_little.png b/src/icons/hi22-action-tork_little.png
new file mode 100644
index 0000000..eebf63a
--- /dev/null
+++ b/src/icons/hi22-action-tork_little.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_little_exit.png b/src/icons/hi22-action-tork_little_exit.png
new file mode 100644
index 0000000..59dd208
--- /dev/null
+++ b/src/icons/hi22-action-tork_little_exit.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_none.png b/src/icons/hi22-action-tork_none.png
new file mode 100644
index 0000000..4b29151
--- /dev/null
+++ b/src/icons/hi22-action-tork_none.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_orange.png b/src/icons/hi22-action-tork_orange.png
new file mode 100644
index 0000000..180d1ff
--- /dev/null
+++ b/src/icons/hi22-action-tork_orange.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_orange_exit.png b/src/icons/hi22-action-tork_orange_exit.png
new file mode 100644
index 0000000..eab1348
--- /dev/null
+++ b/src/icons/hi22-action-tork_orange_exit.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_play.png b/src/icons/hi22-action-tork_play.png
new file mode 100644
index 0000000..4191979
--- /dev/null
+++ b/src/icons/hi22-action-tork_play.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_red.png b/src/icons/hi22-action-tork_red.png
new file mode 100644
index 0000000..63089e9
--- /dev/null
+++ b/src/icons/hi22-action-tork_red.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_red_exit.png b/src/icons/hi22-action-tork_red_exit.png
new file mode 100644
index 0000000..dedca30
--- /dev/null
+++ b/src/icons/hi22-action-tork_red_exit.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_server.png b/src/icons/hi22-action-tork_server.png
new file mode 100644
index 0000000..6984fc3
--- /dev/null
+++ b/src/icons/hi22-action-tork_server.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_stop.png b/src/icons/hi22-action-tork_stop.png
new file mode 100644
index 0000000..113a1a6
--- /dev/null
+++ b/src/icons/hi22-action-tork_stop.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_tor.png b/src/icons/hi22-action-tork_tor.png
new file mode 100644
index 0000000..7da8845
--- /dev/null
+++ b/src/icons/hi22-action-tork_tor.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_torsmall.png b/src/icons/hi22-action-tork_torsmall.png
new file mode 100644
index 0000000..4b5faa3
--- /dev/null
+++ b/src/icons/hi22-action-tork_torsmall.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_uncensor.png b/src/icons/hi22-action-tork_uncensor.png
new file mode 100644
index 0000000..c6cd900
--- /dev/null
+++ b/src/icons/hi22-action-tork_uncensor.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_yellow.png b/src/icons/hi22-action-tork_yellow.png
new file mode 100644
index 0000000..d17bbba
--- /dev/null
+++ b/src/icons/hi22-action-tork_yellow.png
Binary files differ
diff --git a/src/icons/hi22-action-tork_yellow_exit.png b/src/icons/hi22-action-tork_yellow_exit.png
new file mode 100644
index 0000000..3583a69
--- /dev/null
+++ b/src/icons/hi22-action-tork_yellow_exit.png
Binary files differ
diff --git a/src/icons/hi32-action-tork.png b/src/icons/hi32-action-tork.png
new file mode 100644
index 0000000..814780e
--- /dev/null
+++ b/src/icons/hi32-action-tork.png
Binary files differ
diff --git a/src/icons/hi32-action-tork_Apply_Settings.png b/src/icons/hi32-action-tork_Apply_Settings.png
new file mode 100644
index 0000000..5650b7c
--- /dev/null
+++ b/src/icons/hi32-action-tork_Apply_Settings.png
Binary files differ
diff --git a/src/icons/hi32-action-tork_DNS_Leak_Warnings.png b/src/icons/hi32-action-tork_DNS_Leak_Warnings.png
new file mode 100644
index 0000000..2c340ec
--- /dev/null
+++ b/src/icons/hi32-action-tork_DNS_Leak_Warnings.png
Binary files differ
diff --git a/src/icons/hi32-action-tork_Usage_Warnings.png b/src/icons/hi32-action-tork_Usage_Warnings.png
new file mode 100644
index 0000000..942fa61
--- /dev/null
+++ b/src/icons/hi32-action-tork_Usage_Warnings.png
Binary files differ
diff --git a/src/icons/hi32-action-tork_green.png b/src/icons/hi32-action-tork_green.png
new file mode 100644
index 0000000..f4ff5e8
--- /dev/null
+++ b/src/icons/hi32-action-tork_green.png
Binary files differ
diff --git a/src/icons/hi32-action-tork_none.png b/src/icons/hi32-action-tork_none.png
new file mode 100644
index 0000000..0999c81
--- /dev/null
+++ b/src/icons/hi32-action-tork_none.png
Binary files differ
diff --git a/src/icons/hi32-action-tork_orange.png b/src/icons/hi32-action-tork_orange.png
new file mode 100644
index 0000000..2c340ec
--- /dev/null
+++ b/src/icons/hi32-action-tork_orange.png
Binary files differ
diff --git a/src/icons/hi32-action-tork_red.png b/src/icons/hi32-action-tork_red.png
new file mode 100644
index 0000000..e079e9a
--- /dev/null
+++ b/src/icons/hi32-action-tork_red.png
Binary files differ
diff --git a/src/icons/hi32-action-tork_yellow.png b/src/icons/hi32-action-tork_yellow.png
new file mode 100644
index 0000000..83a92a0
--- /dev/null
+++ b/src/icons/hi32-action-tork_yellow.png
Binary files differ
diff --git a/src/icons/hi32-app-tork_FAILED.png b/src/icons/hi32-app-tork_FAILED.png
new file mode 100644
index 0000000..dd5dc21
--- /dev/null
+++ b/src/icons/hi32-app-tork_FAILED.png
Binary files differ
diff --git a/src/icons/hi32-app-tork_General_Warnings.png b/src/icons/hi32-app-tork_General_Warnings.png
new file mode 100644
index 0000000..dd5dc21
--- /dev/null
+++ b/src/icons/hi32-app-tork_General_Warnings.png
Binary files differ
diff --git a/src/icons/hi32-app-tork_Security_Warnings.png b/src/icons/hi32-app-tork_Security_Warnings.png
new file mode 100644
index 0000000..dd5dc21
--- /dev/null
+++ b/src/icons/hi32-app-tork_Security_Warnings.png
Binary files differ
diff --git a/src/icons/hi32-app-tork_TorK_Feedback.png b/src/icons/hi32-app-tork_TorK_Feedback.png
new file mode 100644
index 0000000..dd5dc21
--- /dev/null
+++ b/src/icons/hi32-app-tork_TorK_Feedback.png
Binary files differ
diff --git a/src/icons/hi32-app-tork_green.png b/src/icons/hi32-app-tork_green.png
new file mode 100644
index 0000000..a409b91
--- /dev/null
+++ b/src/icons/hi32-app-tork_green.png
Binary files differ
diff --git a/src/icons/hi48-app-tork.png b/src/icons/hi48-app-tork.png
new file mode 100644
index 0000000..541b0a6
--- /dev/null
+++ b/src/icons/hi48-app-tork.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_FAILED.png b/src/icons/hi48-app-tork_FAILED.png
new file mode 100644
index 0000000..ac18f84
--- /dev/null
+++ b/src/icons/hi48-app-tork_FAILED.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_a1.png b/src/icons/hi48-app-tork_a1.png
new file mode 100644
index 0000000..5d7517d
--- /dev/null
+++ b/src/icons/hi48-app-tork_a1.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_a2.png b/src/icons/hi48-app-tork_a2.png
new file mode 100644
index 0000000..0ad792c
--- /dev/null
+++ b/src/icons/hi48-app-tork_a2.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_agent.png b/src/icons/hi48-app-tork_agent.png
new file mode 100644
index 0000000..5d7517d
--- /dev/null
+++ b/src/icons/hi48-app-tork_agent.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_alert.png b/src/icons/hi48-app-tork_alert.png
new file mode 100644
index 0000000..c023137
--- /dev/null
+++ b/src/icons/hi48-app-tork_alert.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_firefox.png b/src/icons/hi48-app-tork_firefox.png
new file mode 100644
index 0000000..e48d705
--- /dev/null
+++ b/src/icons/hi48-app-tork_firefox.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_green.png b/src/icons/hi48-app-tork_green.png
new file mode 100644
index 0000000..d41ce8d
--- /dev/null
+++ b/src/icons/hi48-app-tork_green.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_help.png b/src/icons/hi48-app-tork_help.png
new file mode 100644
index 0000000..2fac291
--- /dev/null
+++ b/src/icons/hi48-app-tork_help.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_identity.png b/src/icons/hi48-app-tork_identity.png
new file mode 100644
index 0000000..90aedf0
--- /dev/null
+++ b/src/icons/hi48-app-tork_identity.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_info.png b/src/icons/hi48-app-tork_info.png
new file mode 100644
index 0000000..a051bcf
--- /dev/null
+++ b/src/icons/hi48-app-tork_info.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_internet.png b/src/icons/hi48-app-tork_internet.png
new file mode 100644
index 0000000..b68acc2
--- /dev/null
+++ b/src/icons/hi48-app-tork_internet.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_kgpg.png b/src/icons/hi48-app-tork_kgpg.png
new file mode 100644
index 0000000..a01145e
--- /dev/null
+++ b/src/icons/hi48-app-tork_kgpg.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_konqueror_play.png b/src/icons/hi48-app-tork_konqueror_play.png
new file mode 100644
index 0000000..331fdc5
--- /dev/null
+++ b/src/icons/hi48-app-tork_konqueror_play.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_konqueror_stop.png b/src/icons/hi48-app-tork_konqueror_stop.png
new file mode 100644
index 0000000..0494c7f
--- /dev/null
+++ b/src/icons/hi48-app-tork_konqueror_stop.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_konsole.png b/src/icons/hi48-app-tork_konsole.png
new file mode 100644
index 0000000..6aee403
--- /dev/null
+++ b/src/icons/hi48-app-tork_konsole.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_konsolessh.png b/src/icons/hi48-app-tork_konsolessh.png
new file mode 100644
index 0000000..1658b5e
--- /dev/null
+++ b/src/icons/hi48-app-tork_konsolessh.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_mail.png b/src/icons/hi48-app-tork_mail.png
new file mode 100644
index 0000000..f72c796
--- /dev/null
+++ b/src/icons/hi48-app-tork_mail.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_opera.png b/src/icons/hi48-app-tork_opera.png
new file mode 100644
index 0000000..b5e97a5
--- /dev/null
+++ b/src/icons/hi48-app-tork_opera.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_penguin.png b/src/icons/hi48-app-tork_penguin.png
new file mode 100644
index 0000000..e8d33ab
--- /dev/null
+++ b/src/icons/hi48-app-tork_penguin.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_play.png b/src/icons/hi48-app-tork_play.png
new file mode 100644
index 0000000..a6575d2
--- /dev/null
+++ b/src/icons/hi48-app-tork_play.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_pressplay.png b/src/icons/hi48-app-tork_pressplay.png
new file mode 100644
index 0000000..a6575d2
--- /dev/null
+++ b/src/icons/hi48-app-tork_pressplay.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_privoxy.png b/src/icons/hi48-app-tork_privoxy.png
new file mode 100644
index 0000000..f867947
--- /dev/null
+++ b/src/icons/hi48-app-tork_privoxy.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_remotetor.png b/src/icons/hi48-app-tork_remotetor.png
new file mode 100644
index 0000000..68900ff
--- /dev/null
+++ b/src/icons/hi48-app-tork_remotetor.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_stop.png b/src/icons/hi48-app-tork_stop.png
new file mode 100644
index 0000000..3414612
--- /dev/null
+++ b/src/icons/hi48-app-tork_stop.png
Binary files differ
diff --git a/src/icons/hi48-app-tork_torserver.png b/src/icons/hi48-app-tork_torserver.png
new file mode 100644
index 0000000..1c6abdd
--- /dev/null
+++ b/src/icons/hi48-app-tork_torserver.png
Binary files differ
diff --git a/src/introwizard.ui b/src/introwizard.ui
new file mode 100644
index 0000000..97117ca
--- /dev/null
+++ b/src/introwizard.ui
@@ -0,0 +1,1858 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>IntroWizard</class>
+<widget class="QWizard">
+ <property name="name">
+ <cstring>IntroWizard</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>614</width>
+ <height>405</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Introduction To TorK</string>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="2">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel3</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The 'Anonymous Traffic' OSD&lt;/i&gt;</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer row="0" column="2">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="2">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>81</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="Line" row="0" column="1" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Anonymous Traffic OSD&lt;/h2&gt;
+&lt;p align="left"&gt;When your traffic is anonymous it appears in the 'Anonymous Traffic' OSD (pictured).&lt;/p&gt;
+&lt;p align="left"&gt;Most columns in this OSD are self-explanatory, apart from 'Exit'.&lt;/p&gt;
+&lt;p align="left"&gt; 'Exit' is the nickname and probable location of the computer you are using to leave the tor network and enter the internet proper. &lt;/p&gt;
+&lt;p align="left"&gt;This computer is your 'identity' on the internet for this particular connection.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="Line" row="0" column="1" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>line1_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;IP Address vs Hostname&lt;/h2&gt;
+&lt;p align="left"&gt;When traffic is truly 'anonymous' Tor uses the hostname (e.g. www.google.com).&lt;/p&gt;
+&lt;p align="left"&gt;Sometimes you may see an IP address instead of a hostname in the OSD.&lt;/p&gt;
+&lt;p align="left"&gt;In such cases, you need to be sure that you have not bypassed Tor to get the IP address. &lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>pixmapLabel3_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="2">
+ <property name="name">
+ <cstring>pixmapLabel4</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Using hostname - www.showmyip.com&lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="2">
+ <property name="name">
+ <cstring>textLabel2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Using IP Address &lt;/i&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="2" column="2">
+ <property name="name">
+ <cstring>pixmapLabel4_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="Line" row="0" column="1" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>line1_2_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="2">
+ <property name="name">
+ <cstring>textLabel2_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Using hostname - www.showmyip.com&lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="3" colspan="1">
+ <property name="name">
+ <cstring>textLabel1_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Good Reasons For Seeing An IP in the OSD&lt;/h2&gt;
+&lt;p align="left"&gt;You deliberately requested an IP address instead of a hostname.&lt;/p&gt;
+&lt;p align="left"&gt;Tor is managing internal connections using an IP address.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="2">
+ <property name="name">
+ <cstring>textLabel2_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Using IP Address &lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>pixmapLabel3_2_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>296</x>
+ <y>11</y>
+ <width>3</width>
+ <height>282</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>305</x>
+ <y>146</y>
+ <width>279</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Using hostname - www.showmyip.com&lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>11</y>
+ <width>279</width>
+ <height>282</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Bad Reasons For Seeing An IP in the OSD&lt;/h2&gt;
+&lt;p align="left"&gt;Your application is bypassing Tor to resolve the hostname.&lt;/p&gt;
+&lt;p align="left"&gt;Your socks library is bypassing Tor to resolve the hostname..&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>305</x>
+ <y>299</y>
+ <width>279</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Using IP Address &lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel3_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>305</x>
+ <y>11</y>
+ <width>279</width>
+ <height>129</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel4_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>305</x>
+ <y>170</y>
+ <width>279</width>
+ <height>123</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>11</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Is an Application By-Passing Tor?&lt;/h2&gt;
+&lt;p align="left"&gt;To check this out, select the 'Traffic Log' tab in TorK.&lt;/p&gt;
+&lt;p align="left"&gt;In the 'Non-Tor Traffic' pane entries with a warning symbol denote hostname lookups that have bypassed Tor..&lt;/p&gt;
+&lt;p align="left"&gt; In the illustration it is pretty clear that konqueror has looked up the hostname www.kde.org. before opening it. &lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>280</x>
+ <y>10</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel6</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>0</y>
+ <width>292</width>
+ <height>327</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image2</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>11</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Can I Stop Applications By-Passing Tor?&lt;/h2&gt;
+&lt;p align="left"&gt;If you run Linux, yes.&lt;/p&gt;
+&lt;p align="left"&gt;The 'Fail-Safe' button allows you to force DNS requests through Tor using the 'DNS Failsafe' setting.&lt;/p&gt;
+&lt;p align="left"&gt;The 'System Fail-Safe' setting allows you to force selected secure traffic through Tor, such as browsing and email downloads. &lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>280</x>
+ <y>10</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>300</x>
+ <y>210</y>
+ <width>279</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The Fail-Safe button. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel1</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>310</x>
+ <y>70</y>
+ <width>221</width>
+ <height>135</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image3</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>20</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>21</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Now let's see some of TorK's other features.&lt;/h2&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel6_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>300</x>
+ <y>100</y>
+ <width>250</width>
+ <height>220</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image4</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel5_2_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>330</x>
+ <y>10</y>
+ <width>268</width>
+ <height>204</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image5</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel1_2_4</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>300</x>
+ <y>50</y>
+ <width>172</width>
+ <height>115</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image6</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel5_2_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>390</x>
+ <y>220</y>
+ <width>198</width>
+ <height>72</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image7</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>11</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Browse the Internet 'From Another Country'.&lt;/h2&gt;
+&lt;p align="left"&gt;The 'Citizen Of..' button allows you to browse the internet as if you're located in another country. All your internet traffic will appear to come from the country you choose.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>280</x>
+ <y>10</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>320</x>
+ <y>230</y>
+ <width>220</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The 'Citizen Of..' button. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel1_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>330</x>
+ <y>90</y>
+ <width>172</width>
+ <height>115</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image6</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>20</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>21</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Change Your Identity on the Fly.&lt;/h2&gt;
+&lt;p align="left"&gt;The 'Change Identity' button allows you to switch identity at the flick of a switch.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>340</x>
+ <y>240</y>
+ <width>190</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The 'Change Identity' button. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel1_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>340</x>
+ <y>110</y>
+ <width>198</width>
+ <height>109</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image8</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>20</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>21</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Configure and Run a Tor Server.&lt;/h2&gt;
+&lt;p align="left"&gt;You can start running a full Tor server at the press of a button. We recommend running a 'relay server' to begin with.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>330</x>
+ <y>230</y>
+ <width>220</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The 'Run Server..' button. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel1_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>340</x>
+ <y>120</y>
+ <width>160</width>
+ <height>92</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image9</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_4</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>21</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;The TorK Quick-Start Applet.&lt;/h2&gt;
+&lt;p align="left"&gt;You can add a quick-start applet for TorK to your taskbar. Right-click on the taskbar and select 'Panel Menu' then 'Add Applet to Panel. Select the Tork applet as pictured on the top-right. This will add the applet pictured on the bottom-right to your taskbar..&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3_4</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>20</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel5</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>324</x>
+ <y>1</y>
+ <width>215</width>
+ <height>84</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image10</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel6_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>310</x>
+ <y>100</y>
+ <width>250</width>
+ <height>220</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image4</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel5_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>314</x>
+ <y>131</y>
+ <width>240</width>
+ <height>99</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image11</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3_4_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>280</x>
+ <y>20</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_4_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>21</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;The TorK Konqueror Button.&lt;/h2&gt;
+&lt;p align="left"&gt;You can quickly switch to anonymous browsing while in Konqueror by using the Tork Button in the toolbar...&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>324</x>
+ <y>250</y>
+ <width>220</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The Tork Button in Konqueror. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_4_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>31</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;The 'tor:' prefix.&lt;/h2&gt;
+&lt;p align="left"&gt;You can request a website to be loaded anonymously at anytime by simply prefixing it's name with 'tor:'..&lt;/p&gt;
+&lt;p align="left"&gt;This works in Konqueror and the KDE command line.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3_4_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>30</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel5_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>324</x>
+ <y>31</y>
+ <width>198</width>
+ <height>72</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image7</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_3_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>334</x>
+ <y>110</y>
+ <width>180</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The 'tor:' prefix in Konqueror. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel5_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>330</x>
+ <y>180</y>
+ <width>178</width>
+ <height>76</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image12</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_3_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>310</x>
+ <y>270</y>
+ <width>260</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The 'tor:' prefix on the KDE command console. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_4_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>18</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;The Tor Status Display.&lt;/h2&gt;
+&lt;p align="left"&gt;This can be displayed at any time by just hovering your mouse over the TorK icon in the system tray...&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3_4_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>17</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel5_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>304</x>
+ <y>33</y>
+ <width>268</width>
+ <height>204</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image5</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_3_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>334</x>
+ <y>267</y>
+ <width>220</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The Tork Button in Konqueror. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_3_2_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>324</x>
+ <y>100</y>
+ <width>180</width>
+ <height>18</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The 'tor:' prefix in Konqueror. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel5_2_2_4</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>50</x>
+ <y>20</y>
+ <width>439</width>
+ <height>98</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image13</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line16</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>14</x>
+ <y>138</y>
+ <width>531</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_4_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>162</y>
+ <width>530</width>
+ <height>150</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Avoiding the Use of Specific Servers or Countries (1).&lt;/h2&gt;
+&lt;p align="left"&gt;You can prevent Tor from using specific servers or even countries by right-clicking on the selected servers in the 'Tor Network' tab.&lt;/p&gt;
+&lt;p align="left"&gt;You can enforce these settings for just one session or enforce them permanently.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_3_2_3_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>304</x>
+ <y>58</y>
+ <width>280</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Clicking the 'wrench' opens the Tork Config panel. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel5_2_3_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>310</x>
+ <y>92</y>
+ <width>268</width>
+ <height>204</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image14</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_4_2_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>28</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Avoiding the Use of Specific Servers or Countries (2).&lt;/h2&gt;
+&lt;p align="left"&gt;You can modify the servers/countries you chose in the 'Tor Network' tab by accessing the 'My Network View' tab in the TorK configuration panel...&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_3_2_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>304</x>
+ <y>306</y>
+ <width>280</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The 'My Network View' section of the Config Panel. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3_4_2_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>27</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel7</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>370</x>
+ <y>0</y>
+ <width>123</width>
+ <height>54</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image15</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_4_2_3_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>26</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Filtering and Selecting Servers.&lt;/h2&gt;
+&lt;p align="left"&gt;You can filter the list of servers displayed in the 'Tor Network' tab by using the 'Servers' button. You can filter on any number of criteria, including country, status and text you enter yourself.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3_4_2_3_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>300</x>
+ <y>26</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel5_2_3_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>340</x>
+ <y>20</y>
+ <width>203</width>
+ <height>275</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image16</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_3_2_3_2_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>314</x>
+ <y>308</y>
+ <width>280</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;The 'Servers' button displaying available filters. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_4_2_3_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>16</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Building Circuits Manually.&lt;/h2&gt;
+&lt;p align="left"&gt;You can drag and drop servers from the Network pane to the Circuits pane to manually create your own circuits.&lt;/p&gt;
+&lt;p align="left"&gt;By right-clicking on the Connections pane you can select to attach new traffic streams manually to these circuits..&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3_4_2_3_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>300</x>
+ <y>16</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel8</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>314</x>
+ <y>58</y>
+ <width>281</width>
+ <height>201</height>
+ </rect>
+ </property>
+ <property name="pixmap">
+ <pixmap>image17</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2_2_2_2_2_2_2_3_2_3_2_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>314</x>
+ <y>298</y>
+ <width>280</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;i&gt;Building a circuit manually with TorK. &lt;/i&gt;</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Final</cstring>
+ </property>
+ <attribute name="title">
+ <string></string>
+ </attribute>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_3_2_3_4_2_3_2_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>290</x>
+ <y>6</y>
+ <width>3</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>VLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_3_4_2_3_2_2_2_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>6</y>
+ <width>250</width>
+ <height>306</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;h2&gt;Umm, that's it.&lt;/h2&gt;
+&lt;p align="left"&gt;Hope you enjoy using Tor.&lt;/p&gt;
+&lt;p align="left"&gt;Please report any bugs you encounter or improvements you would like to see in TorK to tork-users@lists.sf.net.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>pixmapLabel8_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>304</x>
+ <y>88</y>
+ <width>296</width>
+ <height>130</height>
+ </rect>
+ </property>
+ <property name="frameShape">
+ <enum>Panel</enum>
+ </property>
+ <property name="pixmap">
+ <pixmap>image18</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+</widget>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="89542">789ced9dd772e438b0a6efcf534c1cde9dd8e0a92afad8d80b79efbd36f602005d15bd29b98d7df705f12729db927a667aba7b549d3192be2201028944226158f3dffff5c7e5e1de1ffff5dfffd1b4ac9d8a3f44ccea3ffecb9f67d9fdfffe3fffebfffec77f4e2ceb8ff1c4fb636c9ade1f93fffc1ffff19facf843fca18dd4bf8eb363e23178ce061e779cb4031b8ab7148fbb4f146bc4945e6c0dacae8bbd81d5f3f9f2c02abfea766053e5b74a3c41fa2c1858a52fc28155faf0686095de3f1bd8ea78ba33b0dd71ee0decaae7ad111bc83f69144ffafab527c454bf647b60d4bf1e58a5cffc8155f9d22931d527a90656f787e6c0eafe6c8fd8407d4a6f604fb51fca67f4cfe78703433fd1c0787e4b4ccfabb70756d7b93930f4cf880d5c6fcf884de833b922b6a04fff8ed81ea33df70756f965cdc0488ff630fbf2b72531952f9d0facf2ab1f884d94af60c4369ecfaf889d1157fa8c7a1eabf62d6e0756faab05b13bc6fd23626f142ad67b1e2b6e919fd5eb23e5c416f4d116c4ce88a9eb336217ed5579c4de44d94f6412b3b1aabfbfd1f344e53f3d22e61355bf34566cf7f690cc89491fd909b1037b6e4f0746791a628ff47346ccc6aa3c3c27e613959ef5f98989ba9fc13f38bdfd160931e9a37c1818ed1310bb783ebf2316a86f7348ec43dfd30bc56e9f7f3b2536c93e2f892df23f9cd8457d03d8b72bcd5de97b160d2c94ff59221e1baa3ee260605f3d7f53b1d7f518a5af0b620fedc78f88c3b1b2cfd2018f2d13fe00e9a53661efed8c788cfbab656203d76b466c9a8e6abf15c57cf0273a31477b25d03f9797d1df1b62731ca8f29bc4b689fa2c0d8ceb09b1632a7d17fd75179c6f127ba6d2e7f45ab1e8fd61067d08f93c755dd0f531b394fda7681fbf1355df75f0d81eabf62f4c62df521c403f41d7c3d578c389a528fdc2be83b185feca51be70ec4e94fef82e310357187fc28981f254aa3f4967edc23fd4f70343df37c48cfa870077a2fae3167862d9b05fd59fc6e3ce42d4fd47e0ee9fea4fb83e91f9a9e7070678e239aa7c33d59e63a3b7dfec92d841f9b255622a0fdf21e6c8af5a024bf788fea0fcd9d8942da4d28716781c4e54fd9275b0bc1ff6b64f2c5c95de57f638b686f28c886dea6f35313d3fe260993ff4b90b3646ae7ade34556cf7e9b36562b2870cfab0fbe707ca1f8c9dfefed0200ec97f25e0890dff33db21760df8cb73c56e9f3e298919dab718110bd84f82f6753b51f583bedcc904feaed8041b0cf561cadec7dea08f0d621ffa4e5c7027aa7d94bf94d6e8a3bd03072c0718b43ff4c73b0fa9f401fbe1138efa8831d81c5be85f6b3d23bd3821362da58fa9f21f63310e26cabf95cb3d5bf0a7683f316106e2877be2c0803f82fe8574dfaa3e82d8343cd873426ca1bfa66a7c1dfb9da8fa9c1387d43ed09f2ff357f52b54ff96a5f3f1bc04f62e9f0eff1ca1fca1b460e47f4e1c62bc9de2fe500e07601f6c1ad06fa5da535af798aeaf830dd356d7751f6c3ab6f227a16a2f7937c57bdc2096239c6a8f3562b28f14e9c79d741c2b7f3031fafe1f5e8365f9557d9a183cb126aa3cc1086c7147e9a7c57553dab7e2f804dc0558ea79163137111f6d1087343ee0ba658c717f11130b5c1737604b3055be3c25f619e2ed4c7137fe637ccac132bd6aff40f9db898c1628de843e1c63ecaaebd50a7180f2653a58861f4a5fe125d89e30c427b8df95c5c5f8bb03b63c1bf14409b66da6ca1fa8f868e2f5cf6fcfc1d243abf4ac2666181ff805b86b41657f39b189f18fa37d3cc33555fd7de52f27accf9f1f80a505a3ffed832d61abf4e29ed8b7557b72e883d91e43ffdc20e64cb57f91110ba6ca5b1460c736557d7d353e4ce47889faa49be0893f51f6df6c83cdd052faa838583608fa9b1aefe5ddbea1aec787c421e2991afaf79d09eeafa1ef408ebfaa7ef51958f64f55fe1cfd2790f687fe3b01db9ea7f43955f3934938b1d01fe215621be34bb644ec80d36be210f6cf8fc10643fc55d8e0debf658238b0d07e4aff32f8f2f1bcec163c61a41f9f9823ff58c513c6781c20be883db0ac912acf5c0377a2ca47d7e5f3d4f5f2066c8d2d654ff516f1c482be47603bf054feb5aa9f3191cf53ed9d97c4219e3f5b03f7fe353f260e519e94b813551fe51f0d43d607e957c0860dff99cdc1aecdc1cabf19a6bc1ffe03e533a57e31ff68c1168d5fba003b138ef8fe0cecba1cf1b9f22786257b94aa6f6af48cf13d1e13336adf00dc89aadf36d81c9b88b71f881d13f111aedbd2e2547ba56a3e6b38131ffeba6cc0966bc37f287b365c19ff61bec3c09da8fe73003603c4b3c90958fa13cce7968839f24b2e06c6f882fca57fb0943dce605f9e6c01559fda2026fb999d1287a8cf0ccf63b23c88f73d628efed370621fe369067b665680f1a7a8c19ecb557933a497ad0fff551f81a5c6d11f6a62017b98dd1053fee9167100cedb8155f99b0a2cdb07f691816dcb512c606f5c765f557e1de5e7ee58201e827d734f70a5bf4cadb718d27f61fe5e9df68cf822a7eb7d7d1aa4175223aaff55edc0e8bf07c43eec295e25961e43d9c339d8326c8c8f3531e993193d0be40ffb13320045bc49e5b365c8a8ca43cfb36d07f3574eec3818ffd01f846338ca3e828cd8437f6da14f5fd61fed7109eecb3f3d1d18edc18903aa9f4b1ce27a7d38b06a2f7e0fb64c1bf3df146c1b0efabf466c394a1fb99a1f1bc184a33da6b0cfa0b36855be55e200ed139f0f8cfebd3130ecdd1b58e937873d0626c587b3e38131bfa0fc6c0ffa13017128303ea1ff8572fc463c0eff194a51e569c4c0983fde0e0cfb813d85e604f690a8f4e648fa5f94b7024bff82fe3001f7e56b0ae209fc479a8065fbe3fe8c3870953ecb5be2d0c5fa845a3f30c7521f88ff4ec1f213d57fd3b39e4d8c2f0eb8cf2f636067e4623d6e3a30e62b945e4e68b01e87fc27139abfc56be0be3e994d4cf1733aea19f14de1836d0efb2d04b18ff2d42bc401aed7cb03abf6ce0e7ac6fd693a30ea970f8cf5004e1c227dbd0e96f553f7977703abf64e2be20938847e8cde3e6ab49f21eb0f7bdd1f58b5df6c0e96f68d78c604cb4f547d72ba6e9a58cfc9a05f63a8ff0631d5afde1c18eb8d0531b57f05fd1bdd0296ba6e0f0cfba5f239343fab578927485faf0dacf29fc29ee48084f82c47fd65fc8ffa8563b04dfe272d89399edfec11537b54789e39e8d7251ea33d66b077abd7ef7499784cfd5123f6693d0aed6fc91104e545fd2c29589f867d59f21fe2d37bb0ac3ffcebcec0580f6c0786be768927984fe46afc97d59d50bc714d6c431f099e6777a2daf31c2cf3c3f87b3a30d63f0f07467f417b3bbd3f2bb7c17d7c32bf1f18fa417b39eec846ff813edd89612affc360cfae3de668bf19d8b118fcb11a8f4d4ff64ff86bd497c9f810f1b60e765cccc7e6c88f77a2c65f942790fa55f9871ed8b13c553e3f00bb23a1ca17c3df74f1b57a7e88fe23e3eb09e2b9317188f5bd4c8d8f969cad61be966d137b14bf2d81e527f08f61cf96ca7f7641ec61fc89cfc0b6cf10df28fd49f31268bffc102ced49dd1fac833d3b807f50e3b9359998587f6f1bb0ac11e6e30ed80e917f1e815d8361fd3001735b603d0bf9cb001ef3f1e4082c67e82aff4ad9a70c5739d6cf66aa3f58566781ea799bc43ee68f3aeaaffea9fbb7c0f688d6f37607c6f802b61d0bf1f6ec8ed845fb051b60360e547d821c2c032ce487f24aebc4f8986ae04e947d72b06d225e9b2a7f60b9b2bcd84fb0c0ee18f698a1bc9e9cdfc01f1d831d81f9cc54d98725a3355abf40799849f17db9451c627c6bd4786049ed21de9daaf5074bc8014da59fdf823b51e5df07bb2ee6c795f22f96dfdf2f18d80905e603b8df1723a1ecaf80fe8231ed9f143bc4b41e9f9e823b51f9c33e43795dd54fa8fada23cba0f1e08ed8b3547a5f3dcf1e4f0cac4fce547decc9d8c7fa4ca0ecc1369908e11f953dd8d638c0f5f404dc89d207f2b7fbf485eabfb6dbdf1faaf693b36be6a17d953fb05927aafc4adfb6d42ff9bf1131cd97b27bb04deb5b73412ce0af52351edabe41eb55b3033033b97a7e760df61df88f40f5373bb0297e280fc12210282fea175a648fd39238807ff0e76031e6aafe5ccd4f9c9165c27e8235b067233e8f2d307304fcc136b117a03f6f118721f6fb54fd9d31f3707faee23567d2aff734b87fd2d737afc08ce17e5e82fd09ea3b457e8608857ade5ce95fb97fec171f1207e8cfa10df67cd42f9e80d998abfc42652f8eed192eee57fdd1712663d853a3fc53e7ed31df6b54ff96b3090bed1b5f8219f5d719eac758e862ff04fae4328040ff2276683d51833e7dd7a7fab6603e82be13355ec8da507c17207de88558df89d5fcc91d5bb4df93ee8099e0585fdb02f311ca3f9d808583f87e3a1d18fb3bbbc4ae50f787fb603ff455f95ad51fdc893b7254fd980b961364657fb37562067b6d02628ef2544a5fae21389e57a9fee99a9d01a8f62fc016477d220d6c3b26d683efc06ee8a9f6e37b60d981b01e720f1602f6cfd578e85ab2ffe13cc315d861f0c71a9e6f795ca0ff1f80657fc3faf42158f8d49fa02fdba6f9d91cf5b39d10fad019b813f53ca4b73deeaaf2ce95ff719dfefe04f575a57d607d17ede3da0cfd73aee227d773c70efc2bda57ba1faeca1fde1173d84f784b4cf3b748f55f97c91113eb25d017b3478887c21b30f3e1af676a7c70b9ec2058efbd00770bb04a3f0d989b18af2bd5ff5d31a1fd664e2cdb4b95478fc0aeef21de53fdc3f5657d315fbc21e6887742e8d3f7e480abcaa3c65b57c653b85ea3fd02db30315f888999a5f4a7a3fe81c7305e256a3c74e56c15f169a1836d5a5f16ab60a7f777ca5f78a39e8501963d0ceb1d7760afb7ff4b62eaefbe0be64e80f5dc001c983ee26f557f4f46d7581f0876c0dcf2317e29fbf526968378c6f7c0523d88c7d478e919fd7e468efc0ddb437ca76d803d17f313e1835918a8f6d212303703cc9757c1c104ed5f52fac0f2e1bf55fb7b329cc17a898ffc4c2eef50e311ea2b0320c427a1004b8f8ef3475b608fd6ab9a2958fa1bf823d4d792fe1dfe568df79e9c3e617cd0547cee392cc0fd811a1f3dd708717dbe09f65ce41fcec1cc87ff112a3ef43c7384fbc503d8257d895d620e9ed3f5ee9fb29731d8b751be52277684f267428d07b23b8eb1bec32660d9a154797c621e04582f447e2c70a05f01fbe19e8bf960087d7016607ea2a560e93ee1efd7c1d29e307eabf1c213868bf5230dfa15723cc2fec6847802fb64d09f90ed877895eef70df8b754f557cfef1a5cf5e70a6c07882f18ca27c727f2f778bef48e586f9ceac43ec6eb06ed139816f637f9095886fb389f83fa05cc40f904ec3b948cfd16f4bf501801fa9fb20f3692fe11fe6519cc46f01751d6b387f17295d8e1d81f0ac19cfbca3fe627607f8cf286393870d13e21ee1f7b345ff2c7606e60bcd06c62ea4fe20c2c26d0473507fb34dfab236286785998e0c0237b50f165176d04189fb6c06244fee41cdcc74319d21b72f883fd6e839981f162e6129bd8cf8b8fc0b23c385f72030e0cf827a1da8b99868ffe12cec06640f33be8df7404987b60198f603ea0e2336659238c1f61036613a6f41fa5c436e67f3eca2f271888176701389820dec8f789998ff84ed917b3a53ee0ff7cb06fa23eadf257cce9edadbeeb19eb910cede33007e35101fd3a7d7b6b687f970b5f954fcb88c97f72b4b7db972751f1859c0cb88807821a2ced05fe6a026613ec676811b1057d842db180bfe6d05fe76f301f877dcb0e83f245ebc4fdf3715d3600fc2dc775199e637c9bc3fed43f55ff5b30a7f6aea00fd6dbdf5cf97fc619c778efc3fe390f519e56f92b264c6302c675e1da188f22d44f3017fd6f5e100bf867df028b20843f86bd0ae9eeb0ff80fafbfdf9ccfc9a98cea7252a9e628149fb15d101580ef7ea795a4c2cb0de20343067e42f1db0a0f96001ff10f4f56fd17ea1d427f6afd15f42593fb4ef1e58e68ff61d1387581f985d81657bc1be94fea5b7a4f66a4e8805c607aef4c3c79685fdbb7019cc683d66ba0296e305f4a39ec7272307eb7ff915b83be0a0f41d83653886f3033b603ff0317fdb04cbfa62be83fc0d3ec27983769998e6438dde33d6438447ec22fe0c768939e26f4ef9053eea2790dee463a46f6d62d3467f74c0b2b9b0dea9ec8177f183621ff7cbf8204479947d72dba5fdb57604e636fc5dabfc5937bdc27cacb67a467935e4efc8e938f6d394bfe1ae47ebb7f11298bbf0974cb53f97e10bcee7952698537c3055f6c399e360bc8ca07fd97de83cc42d31dd9f18c40cfb71adb267cee5f331ff52fe8bcbe114f6541c0c8cf8e3b467f88f64af67cc67a72ed8a7fdbf5cf91fee771b1caa7cfbe0ae84ca5e76887de497aef48cf9628df20786017f9a9f81fbf5dc7c1dcc03f4075deb19f3bd28210e69befd001606ec85417f81efc11f94c82fecf59ddf837988f318e972cfc8afba1a58b5bf0f7b08c508f3b746e527466e88f9435483658954fbcfa76031c27ef4bcec19f6daa8fa8ab118637da7757aa6fdd46c608cc7f1c088674f7bc67c3e57fe534cfaf315f91ed81e63fe97dc823b51f6a313bb88cf9907ee0232555f8dd885fefc23e200fe3dde064bff8af3786abc14861c90547df573b0d41fdacb05cbfa433f39b181f5e568b567d8777c3bb0bade5ef78cf968620e8cf9fdddc0cadfe8736213f1fd5c8d1f924ce8b3b47a86bd642a7ee89627e19f92bb9e915f321918e3633830f6bb553c22ecfebc5683e74b7f82f1a5c1f36c8fdea7602370df1e91476cc03fcfd7896dd43f5ded19cf4b9706c6fcda2616b49e05fbb1a53fc6fce5182ccd15fb33b04fa77fbfa38a8969fdb44e8905ce1b970cdc9d6850fa768943da3f39003b23f8cfe606ec9ac8bf417b395effbec531319dcf6829bd47fb157394df110e9d279bf68cf82a8b7a46fdb51db02f42ac27abf852b8fdf85e67c4549f760decfa285f0bfd4a7f8dfaebe89faeb0d01fc3ba67b47f3b267661bfc565cfd41e16b18ff8b156fe4ac8e91cd6ff6ae8c7ebcf3f4c614f72be88f94bbb4e1ca2fc33e8cfebf3cb95bf97d32f1bfa0e2fc052c1584f6cc1aec0f8ddc03e644049e785d19f64b881f5e246eb19eb3b330196f104cefb41dfbcb7971afd9d3bb45ed9409f72be49eb57d0bf1c3eb0be16dff74cfb41e82f3c08113f95a8bfe8df9768d0ff854be77575d8bbfcc7947eb47d7030467cefc39e4468c01f715cf73d07e7431a835860bf2d82ff91da44fbce1c62da6fa8713de8cf9f66576097c6d316fa09e48c46d54f437b4975c15fb4b7c4b41ede8c7ac679d97cad673aaff13030d69b5ae210fd5743fbcb680bf17289fe1af6faaad03e61f7829062b4b7ac0dce0397273dc31f26d1c0f0d7285fe87b989f54ca5e65e7e8cfebd76083e63bb100cbf11afe7b8998d68ba33131c3f538023b2ecee7942b6097e6538cee972540fd1bb03f86bf620c1c5888af63652f32fcb0e97ce90ed8a1f974bd07761d8ccfed06d8a3fed7ee8319adc7a50f60a95fcccf287d40f1e14c230ed01ea58aeffc497f1eb82cc1466f0f5760191ea9fa684bc413ec2f47b7c421d61ba3cb81b15e770df67cc40facead9867dad1007d8ff49d7c072feaecaafd7c4860f7faefaa36f18239c1f29513fc3f5112f340e58e607ff8bf6377c03fb7b0cf5370233c47c6f85d802c7789ee939183f2394d7f40d8c47ad456c421fcdb867ac0fe53938b450de00fae8ce1b607de9805880eb39b83fff13fb602bc4faa78ee75bbeedabe7fb17e03eff468defbeed59885fe38ad8a5f56194cf66d2e0d5f5e59eb19f36dd05733aff11a27dedaec6aafe3362dadf4a6e0656e9b58238f4311fd906f7e52bd578e73bfdfb261aecbf3b5f8df522f40f395e62fd7f76066626d693a309589898ffcf53b0dfaf9f97c42e9eafa13e4e60a33d7de2d0467972e57f7c578e57d03707bb639c976a501ee9aee9fc6dcf720853f9a3bfba3ec52ff92db10b7d24d381b15e81fee8f6faa8a12f6f32417fd361af5eaf8f9cb80be814a3bdbdfe7c8276423cc17a323f077b1ef6ef454bcc5dbc0f40f93113fbb701fc859cdd225e6b0d628fdeefdaed19e5d7d17fbd6084f2eb63e2b18ffd39e887f5e561681fe61ab47f8ffec6980d7bf64f881dd85f101307d8af2a501e2667fc988f40df4c9607e74d726246e52b8839d6bb2a3c9ff7ef6f44f05fdcb6b0bed4ac829983782fc6f3b908301f8a9607c6fc19fd414ef710cf44d39ea1bf647f60aca7aef48c78638af6e0327ec5feca8438a0f516d8070f1de85753f3195f866bd8ef8fe19f65c08bf1b4dd043313f58b61ff828f69fe4bd7b985f5f218cf17fe04f3fbe68a98d69785db338df78f8cf13427f6b1be17aaf8c0f75d0ffb3b01f42d1b1cfe30b826f6e0dfca11d8f7a1efe2b067d8eb7cb7675a2f467f0c5cd3c17978e82be0639c6f2c60ef811fd07ec45acf345e64c421f65f185d97d36df84bd42f641ceb7125fc73e853fcefdff48cf95e32eb19f1940efd85d2feb11fa9ca1b8c0c17e779740f6c8d2dd8d31d584e6fa0ef73b00c4fb17f7c451ce27d91e921b8dbb050faa4ebd24363bdd605cb27627fd4ea19eb69f3b667acb7170eb8f77fa51a5f82717fdebc45f9c79ccebff184d8c6fa4e740a962542fcbad133c687f29a98de2faded9e69bda0ea19e5d353e24980f5a42b625a7fac547f0fba7803eb69336286fc9a7b3033305f881a7040eb3925ee1ff6ff38b18c67f0feac20b670be3487fe0c993fe25994dfe8cf13b18498fa2383fe0c3941c2fab0090ee87c6696f40cffadf76ce2fc878ef633fbf2681ab1052e0b707fde35dc20a6fa6b0f60cbc5f923b60ff65c3aef84fa9ac246fc3835885df88f08f660ca4ff03e19ea6f8663e8bf56fe24b00c0bef5ff8c8cf324dc4a755454ceb5b2c20eecb77097618ce770ad4df920322fc27ea6705142f457b3d63be5319c416bdefe30c0cfdce7a46fbc4f39e619fedc0147f5f0e8cf5bca59ee11fb4037038827ff0ef8969fea0a13fd9b27e184f70dd76e9bcb3803ddbdec8c3f36c627a9f4c64c4139c876a515f9b3bd05f84fe6ecbf223feaf7a467c5e8d886de8a33ceb19fda3f606c6faca7dcfa83fbb1918fe6b46ec04987fc31f39b683f131427f76faf308fe14ccfaf374e83f8e9ca1e37daa929823de8cd1be8ef4c7f03ff01f4ee020de2af67b46f992fb81116f9603637c5c01870ced51a33cae45efe3f9b02f391b23fb86be5c3740f905dddf05108a611fb2fbe27daca22226fbcdf13c3770e9fd8cdd9e69ff77bd679457a7fc030ffbaf33d4df95d31fac4fa1fdbd7e3dd387bd788e89f3571cfaecce4761ff6c152ce8fc4d8bfeee051ec5ab373dc3de35f40f2f1cd1fc6597d8c17ca186fd328bde5ff2519e6e830fe79fe0cf98747f4a1ffa217188fd81760bcc0d94bf407998e0343fd506467f5827f66dacafc2de999cc1229e41fdbb700ffa5d1d18eb9957c40cfe39ce7a46ff88b607863d0df723de12180fb8e1a0bff8f5c0f0c7e8ef9c8f703e595b060b81f5fcea8838c079b929da93cb190afc17fa1f97cfc77cf76460ac679f1373b457690c8cf3cc5acf58bf603a383442acd7ef12f7fe07fd47f4f12b437b08e96fd05f1e8843ec4ff008cc47d8cf6f3c627a7f2ec0782f844de777d1dec2e71efcf145cfd82f88193898203e2cc7c482c6cfa581e11fcf7b46fb2449cff06729c633dfb7b1bf357d200ef03ef60ce3bf1f4c305eccfc9e515f76486c52bcb7492ce0dfca0b629fe29bc9c0b0a769cf743e54eb19fb7f6c3e30e2df213f9c37f0e97921ad5787e0405607f12afc4720fd3bc6e76d6217eb734d4d4ce76b6ad84fe04f30ff6d18b183f5e4d82616689f29da33080cece7c63a31ada7b62671fffeebeac0689f79cf34fe1a03e37cd675cfd0870efd05323e50fa659cd8c2fe4aa81173cc071bb467c80dd83f0f8919e2578efa858261be95237de85bf00ff5b867f8efbc26b6611fd35bb0ac1ecec7ac1187f4be403e30f687e11fc390c6ffe91631c5c39a1a7fc291347f8caf15d8f7b01e9227c41cefd3652db18ff53f71db33fce18c81e58883feb94b1c429fcd35381c513c7ad833ca1b2703c3dfecf48cf839581e18f6181153fce60b622bc4f9ec756281f62991ffb87fbfb54579c7c2a4f5b9b067d8b77e44ccb11f5ada60698f986feb03e3fb1052629acfb0bc67acaf14c4c118fa8a6e88693c284ec0b284389fb9d533ea1fad0cac9e3fdf1b18fb272eb11dc29ef1bc89ec9f986f6d83650080f95801f60c0ff345e43711541eb63b30d6f736c0d25f617c9883e5080e7f66130b3a4fe58065f960efcbc413d42f603d537b1ff78cf8280a06c6fcbb1c18ebb31eb183fad6b05fc3a4f50d3603f7fb69fa3e31ed17e407e06004ff526ac406e259ed9ad8a3f31a67e0d040f9fdb8675c8f6703a37d5607c6f73744c416ec71dae747eb1f15ea67f6eb5d950feedf3f605370b7c3a0ca87f466b742aafa570696e385d267c5886dcca7a757c401de370f8e88a97f6a6b60595ebcafb43e30c6f70b6293be4f24ee19e9a3a381d17eedc0d86f7dbc1feb7fa703a37d86eb74fe47103b880f6a9dd847f92ad8b7d5cf17cb9ee9fdf112e9adfefd9a2a20a6f74934d8afc55c9c7f6a61ef963069bd91d2cbf909d66fb6895ddabfdc1918e79dcf893dd8cf0cf66085747eb2bd23a6fd17aef54cfada1c18fed31f18fa1b0f8cf9b33130ec6983d805fbac67e84fc0be6c695f78dfa52166984fb6a89f2d68bf83c15e6d9fe61fda0531c50715fc4df7f509e81f1bc41cfe6186f2d93205e2af8381f13ef6d2c078dfd81e18f3039dd881fdb1feba87fece968919b83c2626fb088a81b17f81fcbafd68f82bd4b75b1fc7f87449ec607c601b3da33d828781d1ffaf06467c9a0d0cffdfdf4fe5e5b06fd7f4309ff6513ed7e1988f34a88f2b68fd45833db9c104e769454e4ce773b51b6293e6f335b187fa64157100ff9cef1287389f51f381e1ef617f6edf3fa7f4bcce02145379423a6fc604b14be7b9ec81b15e7ed333f6df98454ced55431f5ef7c693aa3fecc1e321d6a338faabd7cd3895bdc1febdd043fb14470363fc1b18f6d55e0d8c78fd6660e4ef0e8cf65a1f18fe211818eb453d33d89356f68cf577ed7060f49f53e200f757686fd6bfaf59a3bd9845dfe7d6c21fc8f924fc4f88f19ff9a44f0dfe83c91914e2eb1d621feb191aec9f85f43e40d5339d47296e884df8ff6a6f609c775c1958e9570f885d9c2f2efafce87c65351918df6794f60cfdb2eb81a1afe17ef4e779d333e6efe51131e92b80ffe326cd275ad4970bfa3e3b0df127ef2202555e8bd8c0f3b309b185fd0c3e1f18d76b621bf3df603a30c6a3e39ea9fdfafc39ed0f573d93ff3a1818eb113b03a37dc60323de7d1818eb535b3dd37c8b138b10e319f42bfaf5c7e082d8857e82e381b13f71424ceb3b01da53ba3f07f1d729b183fd0686fe287a7d0615b183f3324149ecd27c78422ca00fddec99c6a7d59eb11eaf1b03233e5a260ee00f74d8a31fd27e66a4137b88c7fd55625a0fe1e381113f393dc3ff052e31a7f3f0c5c098cf9df74cf3839e7d9c7fd1777b46ff4bef06467cb4d333fabbbe3d30cea395c421eca7c4f810f4f15d89f60dfaf743033c3fe84e4ca8ebf087720289f883a7c402d7fd9d81f1fd10edc0a88f4becd37ec5eec0588fbd27a6ef734b9c9e913e791818fd61ad67ec87cdeb9e619ff315e210cc9606c6f745a17f8506a7fd8d9a98de4f10d5c078bfa9679ff6d742e200e72f02c427a139c2f9b200f170174e403fd07fd89dc0518cf2847dfdfd3de200fd373d1818fb6d8fd7b17eb8461ca27f870703c31e1e06c6fa983d30d61f3606c67c47f48cfe111603c37eef07c6f9a8cb81b1de670d8cf3e2cec0386f733530c6df76608c27a381b19fbd3230fcb53f30fae7c9c0f057ab3d87e8df437af88fa3e17968ffa3f6478aaee94ce7bad07d3d7847c277af7e4509f5488ff5a93ed3133dd5333dd70bbdd42bbdd61bbdd5e7f2ea8dd46ca75da6dfea77fafd9f6b9f8505fcb2f28f5b80feb090af260b0bf8eab2b0805f5896f4e54fc8d25f4bb7b0805f56ba765cf984bcb481ef4cb7b0805f5696f5557d4d5fd737f44d7d4bdfd67724bd25bbf2ced7e91e654fdfd70ff443fd483f7e2bddc2027e5959d64f64ab9fea67fab97ea15fea57fab53ed2c7fa4437e4e78f62beb28093e19aa5dbbaa3bbbaa7e99aa6318d6be265ba8505fcb2b2acf9baa1055aa8455aac4db5999668a99669b95668a5b40212ad7a69015d3a75a5d61aadd5e6da8d762be54ebbd71eb4256df979ba8505fcb2b2acad68ab52d6b4756d43dbd4b6b46d6d47dbd5f6b47ded403b54d73a397a65014877ac9d68a7da9976fe442eb44bed4abb7e9a6e6101bfac2c6b236dac4d344333354bb3354773a5784c67dd77c570794d0913af2c60a43ef759c04216b1984d49babf672c6129cb1ed3bd6d012c678594f2a76ba12f4ff154debdb362356bba7b9efcf5419a5f549659ab4dd89cddb05b76c7ee996a2bb6c496d90a5b656b6c5d5a8714b6f1d20254ba4d69265b6c9bedc8343bf2f736db55e9f7d83e3b60878fe9be610147526bc7ec849dfe743da03c674abaf697bf9f7c7efeeace0b79cf6577cf93bf9ea5f96d64995db16b3662633651df0f66a18d98cd1ce6328febf2aa14aebdb200998e33ceb950df13131cb5ddf7bb746979c4633ee5339e3ca67bcb0278ca339e73a96faebc40a7795ef19a375cdec1e7fc86dff23b7ecf5f5f5be2cb7c45fe5e959faed1d575bec137f916dfe63b7c97efbd9583fee437dfe707fc901ff1e357ad3bf46595ef093fe567fc9c5ff04b7ec5aff9e8a5afe83d067e72f5bf01e326b7b8fdd35bf75316c01dee724fe8a2fb4609de5b8010c2eff65345d47d0f127745fcd202ba74622a662211a9c8a4e494b210a5a8442d1ad13ea67bcb02c49c15e246dcca9f77bdbec5bd90bfc592bcba2c7faf08d9c662edd5b575f97b43fede145b629baeee885df9734fecabbb0edecae169fb767d571c8a23f181058813712acec4b9b81097e24af2b5eaede4279e7a0ca41323794ff7dd7f86307f7aeb7eca0284256ce174dff6ebebbe7acf5889e8cefff9a11fe19b6bfc5716d0a5f3a7fecc4ffcd4cffcdc2fbab6f54bbfea44547eed378fe9deb200bf65853ff76ffc5bffcebf8706fd077f49f63b99c697ede7aff8b2fdfcbb57d7d6fc757fc3dff497fdadbea5fc6d7f47fddef5f7be95c3d3f6f5f7e5e707fea17ff4be05f8ca42fc13ff147ddd3f7b7dcfd3bffc7379cfc54f6fd7efb000ffd2bf9272adbec3a3fb1e0a75d6587de38017e881a6ae5e05eca50574e9ba536aeadd113f08d0feb081200c224d0be2c774af2d209806b3471f1a242fdbe8fdf60b52992693ffe54f3f7d370719ad0545500e3954411d749fbd9a99bcd5ba81f457c14d70fbf249afff0aee7e370b08ee83876029580e5682d5602d580f3682cd602bd80e7682dd602fd80f0ee4f587e0f0a505a874471a0b8e8393e0b46bd7e04cf67e6903c17970213fbd0cae1ed3bd6101d752a7a3eedde96022ff325eb65f60ca4fadc0963f9d372ca0fb92e722d443eddb16f03c8790c9fb7928fa7b42bf3bb7243f8b3e6501ddd3e270fab10584d2aec3244cc32ccc7f7aeb7eca02c2223808cbb00aebb009db701ede84b7e15d781f3e844be172b812ae4a1b3808d75e5a40974e7ebe1e6e849be1d6511b6ecbdf9bc3df1be14eb8fb98eeb50584d25787fbeaaf83f0303c0a8f9f6b97cfc393f0343c0bcfdf8ae3642a398e8797cf5be1bd1cc2abf0ba7b9768b080496884666885afe2b5b75a37744257a6f63eb680488fb488f1e588ff2e916024223f0aa2308aa2389a46b32889d2288bf2a888caa88aeaa8895a79c7fca505a8747e7413dd4677d17df420ffebe5417eb2142d472b8fe9feee15a168355a935a5effe9fafbfd6539da8836a56c45dbd18efcbd1bed45fbd14174181d45c7d149741a9dc9bf36a3f3571680749bd14574195d45d7d188e45ad2389a4486ba7afe632c80159119593f5d7bff06598e6cd9c28fb21539911b79b1feecd3a3f8d57ac063ba98c53c16b11f0752fc388ca3388ea7cfd32d56857f5991ed13cf9e4912a7f1f4c567b3387bb537f8345d1e17711957711d37711bcf25bf48b7b0805f5696c3033ffe58e29b5791e077a55b58c02f2b4bfa727cf3b1bc7546e87bd22d2ce01796c539c185fc03b2b080af2e0b0bf8eab2b080af2e0b0bf8eab2b080af2e6f59407c1bdf2de45f2fb7dfb200d5fef70bf9d70bd9c01b1620dbff532b0abfaf7c6ec5e4d7caf9efcfff24be7bc7023ef3e6e1ef2b9f7bb3f2d7caf9efcfff7d0b38f9c65b8aff06e9de97fb31f5fb7139ff88fcdfb500cd7ff66ee2bf4abaf7e57e4cfd7e5cce3f24fff72d6065782beddf2747c39b75bf4fce3f20ff0f2c60143ff4c28ae7bf5fc8d29b9ffec2d2bd2ff7b47ef172bc12afc66bf1fa9bb5f98efabd9bf367d2bfade16fe62fefdf50b2f9ecbe8dcf95fa7d0b606dff5ea23666c5f3dfcfe5ed4f7f65e9de977b5abf782bde963f77e2ddb76af33df57b2fe74fa5ffe0592ff3fff6fd9f29f50716708577d294148fbfe3bd783f3e880fe3a3f8383e894fe3336987e7f1f993bb7f79e9de977b5abff822be8c7ba6dac4d7f1281ec793c74f480b9d0efa9a7f5fce5d4e466cc6566cc74eecc6de547ffc6baa4dd9940f9afe64c91fef9f8aa93f0da6e134a24f3fd12aef5b807a638d04b9c9fc0aee4ee3e954fe9c4d93693acde45f79f7e9ef25ddfb724feb372da6e5b49ad6d3a6ab2b7dd6caffe6ece4f113fc563aa09a7f5fce5ddae9cdf4561c4cefa6f7f2dac374e9c95fcbddb58f74f932ffbe65a62b3297d5e9da747dba81327ea655deb700f5c61a092b1e7f4f37a75bf2e7f67467ba3bdd9bee4f0ffaabbf8f74efcb3dad1f647a383d7aacebf4787a323d155bcf6b4f3aa09a7f5fce5ddae9d9f45c6aee627aaae4f2f12f76dc5dfb48972ff37f7afff46a7a3d1df59f7ea655deb7007a634d092b1e7f4fc7d389fc694ccda9257fdbfe9dac85f378efef20ddfb724feb3775d54fcfdf903fa936337da6cd98aa71ff099f8999af3ea19a7f5fce9dfe66c12c9c45b378365539ce9efc9574d77a4d7fb6e44fef9fa5b36c96cf0a6aa74fb4cafb16a0de3c2361c5e3ef5939ab66f5ac99b5b3f9ec66763bbb9bddcf1e664b8f77ff0672486fd691cc96672bb3d5d9da6c5dfe4db5996dcc36675baac6fd27dbb39dd9aefa846afe7d3977fa9bedcdf66707b3c3d9d1ec7876323b7df2d7d9ec7c76d16bfab32597395e2ab99a5dcf46f279e3d984dae913adf2be0584c5ccf8b74af7bedc8fa9dffb39b3bffcccbfb7e4ef5b00bd79f6ef94f9f066dd3f9a332b7ead927f60011bcfdf4cfa57c9b97ab3eef7caf907e4ff8105d8afde4dfaf788d6bd59f79be5fc03f2ff606ff0e133ef1dfd9e82f7e57eaf9c7f44feef5bc067de3afa7de5736f55fd5a39fffdf97fe0037eec49979f2d8b33429d7c300a2ce45f2f1f58c0cc9c59337be6ccdc9997e8622bd11296f044247e122461f2ea3b7e7e5f49e2649acc9224497f7649fe61f9c002922cc9932229932aa9938635492bf6c41644dac2fca797ff6f93244d6e92dbe42eb94f7e7a59fe51f9c8029692e564859bc96ab296ac271bc966b23558c076b2f3d3cbffb789b4805d5d4bf692fde4e06797e533f2d6f7a6befe1ed54fc8471670981c25b56cede3e424394dce92f3e422b94cae926df9d97532fad97af87b247948c6720498c8f6371233b1123b717e76993e12b471e2265eaaa75aca12917256a43c15a99f06899f867f8f05a4511aa7d3749626699a66699e16699956699d36699bced39bbf5a8bbfaa87f4f6afeb32bd4befd3877449d7d2e5742531d2d5742d5dffeb6341ba916ea65be976fac453ca36ba95b2fbe293bd749fd21ca4879fd59d4c79941ea727e9697a969ea717d21e587a995ea5d7e9281d3f5a80bc6f921afc5bef027e640166e7ef532bb5532775532fd3332d6319cf44e6674116fe351dfd0adff62eec64378b92308bb36936cb922ccd324951968bbff87d83599195f26715eaefd5b8fb24abb386d2b4d927632b566437d96d7697dd670fd952b69cad4859cdd6b2f56c23dbccb6b2ed470b90f9ee88d7df3102f9c002b25db195ed65fbd94176981d65c789969d64a7d959769e5dc82bea1b23b3abecdadfc946d9389b64c67b44b534332bb333f54da4999b79b9d450aee52ce7b9c8fd9729589107799847799c4ff399bc33c955b49e6779de6b54de53e4655e21ffbcce9bbccde74f737d9d0fdd7b93dfa6abf95d7e9f3fe44bf972be92afe66bf97a223fcdf2bf635e906fe49b8f34ddc9b7f2edfc995790f7ecf6ad95efe5fbbd7ef283fc303fca8ff393c71a3d4d979fe667f9797e915fe657f9753ecac7f924377233b7723b7772f7a905f87bb9f7985ff759a143f31f5940a189bdee2bdc0b51f845508492a2224ed3625accc456917477166991c926288ab2a88afa3d428982bb425a7cd1aa72cc8b9b427af2e2aee89ef6502cbd4c21ef592e56f872b15aac74778607c55ab15e6c149b8f7d4adeb3556c0b8ae08a9d427ad962ef69aeaff3a17bf7b328bf2b0e8ac3e2a8382e4e8ad3e24cfe755e5cc84f2f8babbfdafec575312ac64f7822ff338a27df6ade8d028555d885a3eae63eeaa7f04ad942a5364d1e6bf4345dc94a5e8ad22f83322ca3322ea7e5ac4ccab4cccabc2ccaf2a9059495cc65c8efa9e63fb280524681a15936d941d99673cc01ca9bf2b6bc2befe55fea09e552b95cae94abe55ab95e6ebc472851b9596e95dbe5ce63fbc9beb11974e5dc9deebc4cf1784fffb3dc2bf7cb83f2f0e9e7e591bf37a59ec58e4bfa46fac75cdfca47e5759284e56979569e9717e56579555e97a3725c4e4aa3344b2b5dfbab16209f60972fa2cad22dbda72dd9fdacf44a933f59c51ff533bd5031c36d251e6bf4345de557411556511557d36a5625555a65555e15555955555d354fe280dbaaade68ff93dd3c3071650dd245bd56d7557dd6707d543b5542d572bd56a9a566bd5bad8aaa84dabcd6aab3caab6ab9deeff46f21ea9bba53d577bd5fed3725407956cd1eaa8b3cfe7295eb75c755c9d54a7c8adffbc3aabce7b1f505d5497e8314f737ddb02d2d5eaaaba2ecfab9194b16cfbcb6a5219955959959d18c5e55f69fb4ab57ce5564fdabb96bdb0d66af6d2026a5ecb76a9fd3a78d44f1dd66ac52d2b1e6bf4345d1dd7d37a5627755a67755e17755957755d37755bcfeb9bfaf6a90f50cf18f2fb1e0ba8efeafba4aa1feaa57ab95ea957ebb57abddea837ebad5ace076bea75d9552d4b5defd5fb1f5117bbd707f5617d541f3f2d477d529fe6bc3eabcf5fa678abe5ea8bfaf269eda436aeeaeb7a44f98feb496dd4e6f35cbf6501b555dbe5b876caf3e2a4766b57fa8273f9dba9bd466fb4bf62010d6b78231abf09fa9acbcfc2266ae266fab425bb7ed9cc1a69a54ddac58ebd7e9aacc99ba2299beab1464fd33575d3346d336f6e9adbe6aeb96f1e9aa566b95969569bb566bdd97869018ff97d8f05349bcd562abd7fda34dbcd4eb3dbec6567cd7e73d01c8abdd06c5efddf1ffe19698e9b93e7daf8b339a56bcd6973568d9af3e2b8bc6e2e9acbe64afe772dff1e257bcdf8cfe6fbe3455ac0a4311ab3b11abb711ab7f15abdd55ad6f256b47e1bb47fd37a401bb5713b155bc96ab2ddcedaa44ddbaccddba22d43b3addafa67d4bd6dda1773db3f6f01ed3c5d6d6fdadb6ad4dec9fe7fdede97a3e2ac7d6897dae56452ecff8cfa7d4e58d1aeb4abed5abbde6eb49bed56bbddeeb4bbed5ebbdf1eb487b2118fffa615a156fdbf7c681db83d694fdb3339279461477bde5eb47f699cfc15a4bdcaf2f6ba1db5e376d22e351795d51aadd95aaddd3aadfb2bef12fd53abc2ad37d7e75ab7ded85b012be66ccee762eecf83f95f5c11fa15a4bd4aac79348fe7d3f96c9eccd37936cfe7c5bc9c57bf72fbff8df28105cceba376deccdbf97c7e33bf9ddfcdefd3d3f9c37c695ecf97e72bf3959f5efebf41d2bbf9ea7c6dbe3edf986fceb7e6dbf39df9ee7c2fbdfbd9e5fa87647142e4abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba2c2ce0abcbc202beba7cdb026ee5959385fcdb45f6f4dbb72d0036b0907fbdd0f7acbf65010bf94ab2b080af2e0b0bf8eab2b080af2e0b0bf8eab2b080af2eaf2de033df5efeef94a77af9d965f9e76abcb080e7fa58584057f7a3b6bfe3f1afb7046970cfe35fcfaf7eebfe8f73ff39fa78b48097a57d5f0bbf533d9fd7f8af59c0cbbfdefbe4f567bf9a665e5ac0f7e8e077aae7f31a7f6c01f8efbd9abe6701dfd6d6a3efe83f7dfdd73faf8fd716f0be163eb6805faf9ecf6bfc190b785a93a7f2d4d7bdf4856ff9d0e79ff57afdf65f3f431fdfb680b7cbf5b605fcdaf57c5ee3cff980f7cafaf63ddfdb371eb5f6f374f2910f784b0bbf633d9fd7f8675bc0cb1cfead16f02bd5f3798dfffc28f0dacb7d8f053cef1fbf86777c2f12fcb316f02bd6f3798ddf5e0f783ecf7b1ebd3cade9db71c0537ff75c5bcf73ed3ffbf65fffbc3ebe351bfc56bffe1debf9bcc61faf08fdec52feb3fa58ac082d2c6061010bf95ab2b080af2ecf2de04789aee94ce7bad0fd77ef0a7f6c297e3fd1433dd2637daacff4444ff54ccff5422ff54aaff5466ff5b9bc7a2335db6997e9b7fa9d7e2ff94fc8c2027e55f91316c0fe8cfce7fffb9ffff1ff01c2535753</data>
+ </image>
+ <image name="image1">
+ <data format="XPM.GZ" length="89004">789cedbd5773e438b3f7797f3ec5c4e1dd898d7acbd0c61b7b21efbdd7c65e0074c5a2f7256dec777f51f82728a9adba35f3b4ba47836855fd8a04086426120910e4fcaffff9ebf6f4e8affff95fff5537ac89dcbfdc39abfefa1faf4dd387ffe7fffdbfffbffffaefa931fe6b329dfd35316de3afe97fff5ffff5dfdaf82ff72f6d2cff5b71e229b6dc1537078a5d73c56d35b0b5e2871a3c3190ff2107cf02e20c6ca8e329d864c409d852e7c760a68e2fc05c1d8fc09e4e3c07fb0ed8c5f1c92a494e0796ede57ce0d98a8392783ad657ecb5031b2b8eba8165fb832dc95391647e4d973c53d7e3c5c0b8de1631955f4f896724cf7a6047d6d7213627b2fc6a6360993fe303cbfae51792f5e1fa0fc4d698afd857c7ad892dcbf30696d7abd4f9f6449e1fac113be340e63f503c91dcec4b36c606f45ff5c4ce54ca3fdc226613591f2f543c95edc9ce89f914f25d1f58ca239f483685bc64fea0256613593ebb27e653d91e5613bb53597f06fbb4547ee610bba84f764ceccf6479d1ae645b9dcf97c406f4eb1960612e525ed16c60d93f5c463c99c9ebbbf9c09e3c1ff573561621f55d123baeac3f571c4ca4bd94c8ef4c0c5dd62ff325b331b3e5f9850d16c76579e58cd8d4e5f518ec914ff4892faf7f4a4cc7a36460797c6e115bbad46fae113bbabc5e04fdbb2b0b96ed7b044f9821f557e1b837f660bfdeb5645f580cec1ffd3398d85369bf3c2166e01ce707d38921eb97299e1952fe6539b0bc9e27fbb7e85c86c964798de4c94ac22b4e43f064e248f905383e151294f9eb09783275657e7f133c752c599f485e7f3253fae73131477e26e53fd18544e00fb6c193602afb8327fba7f086949fcd88297f700c16e7cbfc7394670a0b86bd497b9d588a834de2602cf5b1e8c0537b86fe05b6d5f9454aeca27f377be089ed4af972d4d79e4ea9ffc8fe2b8445f97948eca17d890f9e388e2ccf97fd65c284c380bcee2473d1a3e0af34b0388efeb14e3c31e4f55c5f31f2bb35b16ec8fe33bf95ec4efca9ccbf1ac5563c6533797e7a0ed66736dae32876a43cfc1b62c390faad64ff9c78aa7e8b1db090bfbcde02d7f7a6fe0cf23e921c080dcbfcb9416cc25e23c83310ee42f6977243b127ed6d3e06eb33d85329fd89182e26383f2ac133dd94c7fb0958b74cd91fd36362cf91d70fe4f544ee29f4cf378985c793f54379c2a0992c6f2eed7d3a53fd2178048bf648fd153ad8b018e4b546cc2d298f46daef74e5ff315ecdc053dd45f9b8be2e062cd9deea50b231355c79bd3a27e653f8131f3c9be07c6e810d97a17f48fb999ac3f5e6e089017d24b7e0a98bfc9e29d912fd599e5fed83a79687f642de9639853c5cd97fa7b6e198b27d1ae46d9b2693fdd5477e6728ef7a60d95f35b4df99b0b1d40fefc12b0d48fb1911ebf0afcd21b183f19143fececcd6e13f657f9f3275bd1ced11fe7b22f5c973628fc6ab003c654c5edfcdc0866bcaeb9586621be58f883d53ca9f43fecc7418fa5f48cc99b4875c8ea753315ea03f94d02f9f72e8bbf688bd996c4f7b04b698077f0f7b13e301ec31d5c0536f2aedb7acc14261b2be0b94e7a9f2e66bc401c6cf1afaf26634fe14d0bf6fe85cea7f81fee19b8e837801faf3ed19ea13c17e83a98178679e119bf0cfbc02cf18c6efe452b12eeb5b1460e5af4ad84360062efc858c97c460eea1fc7a0facecbd6dc0b331fc6d3d56ecc9f333e93f6713317e48fb9a9f8227fe445e3f39020b8b96ed995f11fb90d7e2106cfaf00f45040eac09e42beb3f9b8af3a53de4317180fce91c3c9b72d4c7020736e2b75a8ee7337118fa5b64e09949fd718fd899613c0d885d70710eb6a71ec6738fd8e432ff1cf5d785fc11bfa2fdba6142bffd09d89a82790bb66d0eff7f0f0e8ca9ec1fa94e4cf52f64ff9919a2c7caebcf8f8819f4bf803c0cddd2657d1a3adf9c70a9df62040e2cc4aba91c3f66e6d4877eb32db06970299f1af216d5c5f55397d8a378d9018bf365ff8d8fc11ec3f89fa13d96a83fe20394678b080ae3ef1d58f428d9de06f6638be14fda6fb131b06caf87f6d8ba8ff8ae2ac1015d2f85be84bf3264fe05ecc1111a87fe36891dc447f51db1b2bf2de200f26ba13f47f40ff807b4cfb15c0fe35f02f67cc41b2d95e73be012f6eb041ee907d767a245988f06c49cc6975d626f86f9d319d8b439f443f9cd005c1960511fcc3f604fcc99f8b2fc760af60df2571c1c38e87f35dac78505c9eb158fc40cf559b8c42efac72224a6fa2587c43e38cf0796edadafc1fa44477f80fd7393fa679311fbf0c72e5d4f0c78d25eb30e6cfbb08798f2bb33d86b05f989e933da57cd892d700dffe20a894afb9a3f127be89ff39c587848699fb89e6bcc4cccc736897d17f1c436d89a61fdc0bb2376e08faa1aecdb186fb23131c563ed13c33ee16f3c559f686b60c8f782d8477c38bf240e70bc3e1958ca3b837ff37486f905477ff70cddc4786b827d8fe24fb4cf5ff510599f9c585d6f6760c4f3d5c0f27af902ac8f717cb13130c623d8afaffa4f89faf8fe748af1a32676a7b23fb773e28018fdc717d347c9f53ab18efc73f49760321ecbf213d87330a3f96f911007684fb63fb09477723230e40d7f1888fe8bfaf56075fd85ec3f62f2e7a3bf24d7c401fc57ed82d5f5ea4bb03e9dc1de6bb0efa07ecd3a31d5b75e0e2ccb2ba83c3fa0f37bb0b07769ff73692fa2774d307f2fd715fbd21efb0db0ea3f6d0c16d7c77c3d20a6fe91e803cbfc853acea9ff48ff2dc265d26f1e104f71fdf6046cb9aeac5f62823dca5fb7607f4ae3a9464cf17095115b341e6b034b79fa72bcd3674adff52d58c81ff6fa3030e693a8df6a3cc7f553b0f805fee17e60cc370a621deb1b31ae3f333cc493d936d89ab9523ef319d83610ffa506d8b3d0bee6112cda27ebd7507edf04972e31b5af5e2376c001f4a99be46f163a316352be29f4afdb34df2f2f883df8ff9a8e7b14bf94688fee4f48fe1eb10efb2fe7c406f923193fe986927794124f48fec760e1f1a53c22c8df1049b27f0a16ff61fc9b804d1bf1fe624aec10cf88693e505c812d8ef8341d833d1ffda9823d1ba2fe185f603fa68808e1af0e884dd8435e8175d393f6b040ff34cd3143fc7b453c21be269e12df10cf886f897506fddc111bc4f7c426f198d882bdc4545f33803e0bc8c3b4c51447f6a704ecd3fa5ca558f99307621d5ccaf14b447f14ff2d600fd6d03e83d8c3f522d8bb658f4dcc6fb6891d57cabf847c453c87fe92cc8869bc69ba8165fd122a5fd5b7e0c413d42fa3fcaafe05f4614f67989f547b60ddf6e571cd018bf815fd0bd7b31dcb837dc05e6de15f64fe6683d803b73eb14ff597fe5f77740ff148b7005b36d917e4ef88fcf007727cd499e9225e69610f4c845bf007e88f4cf42fc8cb27f6e03fd209b18ff24ad807373dc4cbed39d8d25dac374660e13f104fa3bdaeb017ac379c812d03fea743fb5ddbc4fc2bdd21b6a1bf14f276bde90cf1fa26b189f5d53625b6c0854f6cd3f92db1036ee5fc5e17a763be52398a111fc507c416877cd11e4fcc9750df06ecda145f1bc424af1af5f33cf21f39ae2fa27d0ff307e8cfb70c07f66713072ed6e3201fdf1e83bb90d887bd74180f847bf565fddb1cec32b43f857e7c217f8cafe83fabf934d65b615f62fe4cf1c1086c4dd1fe56b149fa44ff0abc31f547d97f57cba73ae2e546b18ff9ed2eb163c9ebc5176093738cbfdbc41efc63cbc1ae41f2748939e4974d887d8abfa53e8c89f0d7888feec04a7f4d416c221eef50df8998dfe27e4b00764c1ff1a40116f2c3f841c7c5f408f1e89498aedfce88031deb43523f62f211a03db105b61897e57937606ed2fc08f29aaaf23d5c6f3631b0fed7ed80ed19fa575783b987f5962a07bb8e8e78c5236628af54eca23db5f40f42b8345f4a4ab035c67cbf7e00bb16f9af94d8c6f5ca7060ac576f11731c7f90fe6f75f710f7f716c86fac4630791cf9e57ff238da6f9863acbf2efa816579dd3ad8227fd51d816d07feb3ebc0dcd5311fb907bb63aaff82d80027d23f19e68c53fb0fc0223ec2f8097b32c58081f87b9bd8a7ebc39e4ddbc07c35d9043bb627e5eba37d269bf8f057a7c41ecef7503f933bb45ef7087667a87fb32426f92fd07e31fa217e2a880d2b40ff81bd5ba68ef96507f90b6fa5233ece886d03f3e705b187f5863624f6b11edac23e2d778ae375473ca3fb51a89f2dc61bac9f407fb6f09f529f21e465db13268f7787c40ced4ff7c16c0679960e988f5dcc07a83c4eeb21f5067180fb5d0503bb131c2f1703633d01ed710cc7c77ad719d872b1fed6ed816d5a7fe8f6891de20362aa6f45e5716ec09fac117bb85ed72ac6f1f696d887bc23d82b9b98e8cf35fc1fd3291e2d5be280fc35ec8b89e936ec17fe863906fc7d0bff27bc09ca2f19b16bc8fe55e37a7c3ac3fa6c067fc12d9b4b7beea01f6e5bd45ef47fd13cccaf8b9098a13d73190f18eec442fd1bd8872bfa03e489fe2fc66bf8a7d423b631bf682f885de837db200e309faae1ef3d31dfc27c02fede53e5f323623abf457ff3ec09c778a898d6ebba8d8171be46cca9bfa2be9ee362fd3983bd794cf765ffadd07f44f865603cd5894d03eb49b07f7fe2401e19dae74f27584f2f611fbee107182f212f5fb527833ff785fcb15fa3247651bf06f6ec8be903eed7405f81b81eee6fa1fe81f08788478f89a9fc527140fa89c136c3fa5e06ff1e88f6e3feb76caf3916d3558cff1a58c84bca333f003b0cf36d4ffa1373329d8de5f9f939589d5fde13537b921a2ce40b7f7005e60ed6eb23295f733af1b0ffa140fea94dfeb296f23167b64ff3a70bb0a80fecad058bf2b15e28e347311dd2038c8fbb03e37e281d6762c096c7a5fd98c6c4c7f5b3086c1af01fe9c0812c3fdf06338ae7bb4b621ff7c3239c6faaf6948f60953f41fb4c87d6cb0bd4df56d7cf212fdbb402dcef96fa341d8739e81f3198d17a48be436ca2fd85b43f93990cf9cb1bb063627caa74620febcf25eacfd918f14f6c129b743fc026f6b17e584aff26827317f3f3ae00b3a989f5b247621df19587ebf9e614f15be783457d31be56c436da93405f814eeb4701e4111834fe458cd8a77813f50fb84efeec82d831a5fe5cb4277027189f988cc7acb141f36bdf073b26e2c5ae27b6317f9c9f819905ffe52f881d1ffa898803e8b7cbc1ee04d7af65fbac89ede3fe5f770de6ba29dbcfa43fb7c46c02f17d82facd447e595e74481c40de9e94b7980efb888f821db0e3a17df3633023ff98df82f914f3ab18d7339898014b7bb827b661efd929d833713fcc97f2b54c6786fd2c818ce72c4bf83bdc3f35c0cca2fe7747eca0bdc509b14ffd6509e616e45ba37d369bc29fa590af63399067bd0d765c0bf7a3f6c08ce28bf896d887fd16949f05b87e24e30b8bb100fb0f2ae89bdbbe05fb83bc5c46f16486f2c57412f1bd86eb7bb607fde728cf638e85f87f9fd885fc18e4e1897806eb8f1b8a3d8c477b8a7dd93f2ae8c317ee4cda737c491ca03fc437e0d50d88153f487fb8da7d87f8da83bd044e80fbab31ec4bf407cc0717d23fdb63db277f3c05f329eadfb98a7da98fea8e7886fa9516d8a3f5cfb9d4a73d31e87e6fcac1cc85ff4f147bb04f1e81f918fa8d8ec1ae85f5f3b93130ee8f3e10dbd89f1464602fc07e0d26e5b75a4d827c16253183bfa9f789693c8a51beb02ee8a792fdc59eb91cd70ba4fdd9a23762fe9684609bc68f3805f309ec8b2ba6f92497fec836a61ef6bbb9a8bf6131ac0f6a73b0c3317f8e1ec14cad37d88ab1de11a3fe226083fee22b6207f6e183c50082f5e45e03af92d4e71ad8a178d62d8839f6f7540d31ed3f484d309b603d36e9c09cfcc102c72d551e97f66c8b0c343f96fed216c313e24bdf21e6e42f6d6275bfe4142cec0bf71b1e8975f48f84cae3e44fca136207eb09a1ecbf363374ecbf582cc126cdf7d25b309bd8186f47c49685fd9116b187fd9c19e517031ce62313b047eb2d11eacf8543c57a0ceac7571b44e4710fcc75cce7b9f43fb62bec09fe09d7776d0ffbdb72d99f6d31fb4279fe19d811134ee94f2b62d786fcc1be61607da681fdfacc207d1f139b9077ba0956f27451bfc052e39dccef8c15bb9b60d1a3e5f9a1031667607fe29298fca7b70716fac1fa624fecfb58cf5d038be924d6cba53f71843670bfae3b07f319dae7c7c406e28d8e13fb01e45782ddc0c6fc5ccad7991a16d613bc7d309fa2ff68b2ff3a33318143793760c66cdcbf3b250e605f233ace293e6d778919dad379034bfb8aef885df4cfc627f6609f2ecad7857da37dd27e1dc39a229e7940fbc40415fe3766603e413c1b17c40ef41bc7c434be4468bf21e205acb743fea67077f2f848fa7f478cb7f09f31ceb7547d7d397f70ec5980fd500fb8beedd8a88f6f8299077f5a11af0240d99f1ab03b857c5cb4c7d1c728cfd5c0b683f9a99b1073703503abf28a0cace28da223b6b0deeb42ffcc9960fc671b60d181b1bf9458d95f8ceb31778cf8b2ba259e61bdc4853d0bf1c29e821198f918ff47389f0b79cafa3513620fe5cf519fd57209da2bc717c79dd9d8df3dba028bf804fbb73688a7e83f0cf27739add7c62131c778165179de0cebf74c8ed7423c3ee26786faaee207c4070131c3f8b4803d7a627cc37eaa6b620ffe8ccb785a0c262ed6830bf4779f8d31bff06f8969bf661381853ca5fdbbd07f208e63be86fe13700bfe268e8803d8a307ff12b8331ff18394071b8bf143dac38883d918fe2fb853ec48fdfb1eb185f5627e0e160a91fa8de7c401e49927606f82f6faf760dfc67e121ff9270ead477beb603ec3f8aced10933fa82c6217fec26dc1ee14f2cd77894d8a9fb6c02220c4fd0dca2f1480fe40c77d07f529e5f8c2a6a2ffc03f1d83c57887f82102bb142f768cd8c6fcb5f6c16afe90435e33119ec0dfb86036c3f837477b671eed778b42b03f83bf76214f7de6a13fa727607d86fd73e5985807fbd7c43e9e47e0fb60118fa23fa27ebae83f88371ec0ae4dfe438e17cc30c6341eea6036c57ed7c519b181fb87c12db1c9707f0cf6b25a50823eb70696f28d152bffbd4dcc21cf6802f6a7d04fee12d37a892bd73f56a32bcd8fdd81b11e7b466cc1ff33d887980f61bc8fa10f8bd378d3c2be2c55df11ecd3e62ee663a33b6275fe2158948ff5228f98d62f38cab3557d3de95f9923ec1beb1de86f8e989f4b7d8d2e880dc8b735891dea6f06b14bf773d13f1de1efe10f036203f2e4d0dfca7fcbfc211d57f57990e3d9eae920cc57388e0b01603d5983fd334ef6d74aff29c2b1a923edf54123e688b7ca14ccc738ee9e1307b87e7c0476a70ef657ad11fbd04f80f6bbcc467b9706b18bf1cf837db8ae1f60fc7d240e687c5f80c57001ff0d7bf6bc31d6fb4bc8d3d7e9799d30073386eb8d2e895dac6771e8d7e70ce3498efafb42dfb81f48e5b90ef4efed1293fe7dc82310e541dfebc401ee5fc4c4a27e8897d13f03df84bdc7723c14b3531df6c864ffe613c3c07ecc808319dd9f8b32b06fa1fd4b69af5cc45f88b73b0dec4d21bf790d16fe0eeb07b2fff0191f633ff9f29098d617968d62ac8fb9fbc4b47e1d9f120b0b91ed4d14d37c8ccaf73dc40799f45f5cd703daaf7d00e61394bfbc22d6b17ec576c1423dd8bf21fb335fc56f92bd1db0681fe66b53e219eca3b925d6c97ef6883de82b059b868bfda74bd4cfe426fc73f740ec60bf7b07795b42a3d25f2db7c1e217e4cf15433ecd3dd8f5e0dfb405d89b603dba30c1421fd85f04f9d9dcc6fefbf20cacec99c978878b7015cf272d215f1140c1bf7768afe352bc13a13e62ba85fb69c12558948ffb9b3631e5ef036246ebe374bee85f585f91fe8bf3d58e7a597fe9af457033c6fd8d1ef627c21dd87b7f36b0d4473f530c7fd773c5581f8b703d57c40bd80fb14d6c415e21e4efad5a20fd9147ec51798562ac6f7467c43ef4d5c03e3c6f8af8a795e3b7187ca6e84ffd31b18ffedb198ab17e11dc1007a86f80fee5bb33d83b437d7ccf81bd65e84fbee8df581f80bd8a780cfb75fa5c31ca5b0603e3fee41ad81d637da23c072bffd0caf68aa336fa4f3023f6b1feb8bc07bb63dc9f5b9a8aa9bfc9f98a3b7127781e6c79ad18faefd706467dbb81a53e9703637d2ddf038bf6633d5cead79d9a9329d69b2db04beb9fc5d6c0b81f7f406c83d93e7815704bff73486c43be5e49ec63bc9ab76061afd8bf24fd893b9bfad85f39427d6742be181f51df999007e4a513cf703f3df414a3bf84f6c0f2f8f25831e6fb7d3830f6476e0f8cfd874703c39f8cc09e8bfb21ad43ec07f02fb23fbbbaab937d788a616fbd1c0f5dc335e0af3b5b31aed7fb03e3fc7660f467c8df10d7437c28d7375c11cdc17f31e8df54fa0af78967e82f0f236213f2e84bc528bfcf06c678da0d8cfbfd09b1da7f07fd9bfe84f4e9103bf03f359d2fc2073c3f48f50da6987fb4727c752df57c55b401761c13d74bc15cd93ffa8be55a585fee7bc58817fb4631ea9fc403637fa23e30fc0bea67791cf6afd1f94abf23c8df76e9f9077fa618fa4953622a7f794a4cfb3bfa7bc5b45e960c8cf5df8cd8c37c622efd9d2be6fb985fd619b18ffd1ec904cc02f8cb1ced7744427bd17f9c600cf906382ec269ecd758c2de45b883e7f196ad62d4bfd81e18f74bd15f56db2fb0bf20257621af08ed130115c6c346fa67313d9fd1fe5dd83bb70cecb7ccd03fb8f80ff519835d8ef5e3f94831ecb5dc520c7965f1c0b87f5b83fd00f695487fefbace14f74747a88ff88ff6cb2d15d3fda207b03f26fd67c413cc7f3cd8ab1bcce09f388e7b8e85fb79690e5e4520b27e0e7180f59f00f211da85fd240bc5d07723c74f3139d6717f4e0bc0e238e2bb1d62ba5fb7dc508ce73dfb23c5988ff7bb03cbf634c371f44f0df2f4c5782de59ba5c4338c774bb42f70033c9fda4f1543ded94231ce1fc1df049e83f9577e48ec63bda895c7bdf1ca814a7f7402d64df2d78c98ee8784ebc48c8e5f802d1bcf8b323a2eae80e7c7b7c11e3d8faa1d817d03f162bc43ecd0fd6c0e0ee87e4128c7676f22ea83f83a065bb4be91d8606ed078918285fc70ffef7860593f8d8efb14df4637c4b45f31bd04abeb2752dede74f5c4b2ccff00d62758afd218f114fbf9029b38c0fea4703930f60b1e801dda9fa44d15e37e685f813dda1f9e260363ff848c27bc99c3707f7139017b33da0fbaa318fa2fd09e99e83f783fc421b18efbe7cc2536c0a1f49fde6a832dfc9f0516e325e235d457f766e89fcb4b621df2881bc5e86fcb4dc5f0e795f47f9e31a3fdc9fe9298637f06cb895d70780a36027a1e06fa30543c97b460df0a107ff7e0c0c0fe9710f5351d1beb6f0bd89fc9e879fe79aa18f28c90dfe4631bf11ff46bae5a2cf99a58dd4f3707c6fad40331a3f58e317180f56f6f0156f51ba13ed6ea099c15bb3ad861b89fb540ffb1984ef72f36c0ae4ecf2fdc103ba8cf12edb53cba3fd3b68ab11fa6417d2c61ffb0df84d884fe63759ce2c198ea230274cc0777893d9cef51fec0447b8a23c588b742f43fdb9e58b2bc10e5d94c0c99b2fde8dfb6a7e29b2d629bf6034f06c6fe1d4331c69318f665fb0cfae71a78902feaeb28f96a35d89862ff17efc08e83f19b1bc4dc86bd537ea663bf830ffb13b37dc46fcb736207e5f74c31ea5b9d28863f193d82fd31d56f9d7802fd64676025cf11e4c5547db55bb03dc37ec839f4cf9889fe51d2f9ccc27e1daf560cfbf62e897dac1f05a83f13f585ff592766a87f2ae7431e5f3938693f902f5f3db125f5097b5f6d1fc3f80fffc595bd9647c436eebf86b83e777dccbf423e30fc05fc23f728be0aae1453fcef0e8cf5bc81e9f9ce9d81d19f7db0887731bfa1fa0716c917d713e1a381f640fe2200c6f89c123335fec11e5d3ec1fcbb6c880ddc6f09613fae3745bcbf5c23a6fb11ee9e628a1f6e0686bdc9f8c2f3560f4cc8fa42df42e1f47cce23b103ff588d885d8cc739e4e5711df1cf928e7b1ef4d59f2b86bd3ff88a69ff3bfabf27fc8194e708fdd7b7750bfba1e08f7de171d05f6f89693fe8d2518cf12b8914e3fe671a2bc67a33c3f57d9f63bd3c81ff0f566f9090ed417b8355042dd926f668be7707f60cc4d7bd454cf6e90e4cfb27a78a319e8e60bf819a1f15bbc4b41fa53825b6697de99a98c13f32291f7f3cb3113f3517609df6938ff6c1c604fb2d03072c266cb0870e2cc27bdc1f7a200ef07e88680dbcba0127f54fc7c50885f1b7028b1a603d68ae18f1567945eca0fee93ab10b7f9e527d8309fc53511293ff61d23efd0937b17e16a3fe1311e1617c6dc03ebd7f6b142aa6f5193adfa7f70f2d0bc5f4be9f8562c46f4b4b31eadf1c0f8cfb3bfbc4b49edca8f339fc7fd61353fbb8d4973f15f12af6efb86097de9f10e8609fd6c76a93788afb390cf967337a5ecb3b2136f03c9106f9cc94ffd04ec136ed3f691fc12afe5dd860212fac0727c4f43c63ffa018f1e348fa0b5f57d71f1d121be000f2d655fb340d6cd8789e9e6560c7c6fef039dab77a4009f3f913621bfeae88c12a5e0b77c1e20c3c7f760616f682f177a618e37d26fbefeae950ec5f70213f43d7e9f98a436213f325ed8c58d57f09b618c60b0ef91a62c0c7fdd71aecd1f35fc118ecabfaa68a61cfcb98d8c07aeab21c18f25e2ac6f81a9a8a69bd604b31fcc368381fe557a7c426ee1fa56bc401d62734924730a6fbf71bc453c44fc9fac0d84f3a22a6f9da488e27be29e4837818c74d7b0cfbe2b76067eca07e3bc413ecafe077c453dcff0ed1ff4cd13edcdf9c2ac6fc6739273669fd59578cf866590f8cf5934431cd5fad81315f51f9491e21fa83a5f60bb9f04f16a3e717e6f7609721be5930628ef83d84be2d31be20de827d59be85f9447faa989e5f730646fc3e1918f100fc811550bceec2dec46c16fd21843e6ddb477d39ea6baf0226c9b017d1ddb17fbe3f00fb36bd9f20510cfbec6bc5a8cf02fdd516d343bc0f05f6e988f01ce303f4eb583af61b32f4d7d5fe50ecc7f2c02eedc72be02f9cd58c4bea0bfed2f11dd427b414d37eb55d621ff74334e2600cfb9cf7c416e2a94ac66fbe98fd43ff2eec6b754318f37fc89f319d49798c0ae200f773dc00ec7a26d623d19f983741bc1da2bdabf014f2f306467fb58919fc6f78a718f61c2e06863d8c15431e09f4c9023d80fe609f7c66d1fbf26603c3ffa2ff723ec6fd388d835d7a3e2182feb898b1617ed682c5f511efd60363fc5b12d3f3af4b3e30ce3f548cf155833df16086fa56ebc4e41f12c8d79dd1f3361ac66357c5e32c020bff20ed25d48803dcdf6118ff5d3ec6fe130fe3adebd2fb6f4af807d71b633f7131239e60bc5bac117307feb7578cf979780416232ee25dbabea831fcc7dec0f06f9d62da7f3f534cf7cb86e3b83fdf9c0c2ce593413e6e60405e0dfca567d07c3f25f64cdc0f8d62621fef6b8bd0ded5eb6130de8d15437eac20d651bfd19cd885bfeb4d620fe3f3f26c60d8eb9562d88777a818cfb76b437eac178c7ac5b85feed1f5025aff0fc0feea8175593fd8bfcf6dac67e6b06f2100ec474c8f884ddabfbf436c613d7f7e4eec429f11eaebfb33dcdfef526207f14c78404ceba5c95c31d6179717c4f4fc7f7f3830eebf9b8a69fcde1c18f39f47c590cf08e3a71f503cd8d0f544ff407f392636683f205d2fe0985fe7b0d760f5c60d292fb437e00cf134837c0297617e5a633c10f30bdadf9a129bb09786f27b547e84fa88f903eca77b2466a87f9c13bb189f029f989e879e4703a33fdc0f8cfe76aa18f75b6b4b31d6ff23c83b08283e891a628ae7d30d623bc0fe14d91f82b1e8be88df5cb0e820d8bf612ba678f1162c4640ecdfb92466684f98100768ef721d1c8ca17fbf504cfb696e0686bf8815c3be7c3eb0b47ff78298e24ff784d840fc54487d0713f5be29ed1ceceae82fa39298d3f3991958d83bd64f8a81b15e7a4f1c60fd2ab0c06a7c4ac6c4747fa5bf020713bc6f218c14537f710796d77b0806463cbc476c423fe923b1057fe6a23e53d1df315f5c80450082fdeba88ff0560e9ed748c12ed5972503e3f9075c6fead1f352f988d847bc18a17e531171c05f9e13bb182f5a4b31e21977172cda0379ec134f210fef4831e9bb524cfde16c60ec679c0c8cf967ab98d62f55f916e495417fb3d51b8fe4f16bb0ba9f34ca88e97e4f3e07fb63f8bba2279e219ed61e89c9dff5b0d799b802ecf15231e9f77a603c5f3a1f18f1b53d30d62b2f880df21fdbc4b43e559d29c6fcb6098919da5b4aff1be8ab3712c8fac2fef4d5802819f2d23d03f655437fba4ffbcfca8ad8c4fa42b44fece37979bf24a6feacf960517f59df513030e29b07627a3f0dbf548cfc613930f46d0c8cf7178c07c67cb71918f1da0931f587f89ed809f0bc24da63e8f43cdec804331bfb2947c8bf9adf61bf171d0f683ff27297d840fdd9a162f26ff381319f381d18cf235903637f583830ee1f6d0e0c7d537d039b9e573d528cf6b50fc40ec6b7624cece17c8efe610afde3799b0b621bf7573562753f42eb8929bea81db05aef282c6207eb9b55a718f17b7a48cc613fd995621c5f40bea6b802d6cbf381f17c0f1b18fb99a281b19f3b1818ef3be815d37adb01b1057b633bc40efa03e3c4d43f92e5c0b85ffd404cf2f3c603e3fd85b07f6b785f21fa8ba5d6033bb4cf12fac3fb955a627a3fd1f29198de27c542c5e4cfb481e10f1f0686beee06c6fabe3f30ee479f2a863f60aa3c6a7fb646ec06523f0cfdcf5ebd4147fabb0db031c17a878bf6db16c7fc4d83be6d650ffc9e98f6f38f2c629d9ec798113b687fa611fb182fea6860c45f8c38c0fe9f6a3930c627f42f5bf5ff68446cc27ea31d62da9fa99d10dbb037776760ac5f6e13933de4d4de80deaf96233e71747adf6a09fd3b063d0fcfe07f1d9f9e874e88037a7f6c76443cc5feb3ee9e98f499dd10dbb41e1511d3fb4afb8b8131fe978ad15f96470363beb43930f627ef0d8ce7298281317f381b18eba79e62ecff9f4f88e9f9f7d1c0589fd78a81f1fe059bd8a3fed610933c33d49f09778ee75dd05f991a9f02b49f79a49f11fc0f13335ec4df31313d6f54c35e5830e5188f2bc5b4fee612eb18afd2ab81b1fee113dbf43cd73531c96fe10c8cf5854b627abff77231309e67b215e3fa9d3e30ecf77160599eb63130f60fa9fa32f893e68cd8837fca1e07c67e45f477ae5bb41e8ceb7315ff8cb68967747d9398f643658cd8a4f7291803e3feedd5c028bf524cefef3c24b651fe3225e690cf68aa98fcb93730d68fba8131df581f18ebfff1c0b81f1329c67cb75d2a467cef1e13bb9057aeae4ff6e763bc70751bf2f2ab81f1bc774d4cebcd1ee4ef5a3ad637fc86d8c2fd2e0df6e02a797b53620bfbcbbc09b18df58d648798de7f93dac40cfd73c9885d92df9662f2ff9e62f4cfd1e6c08827f9c098cf2f897dd8cb08faf184be703ff18098f69f791e31ad97f1f581116fb68ae1cffd3d628ef8397506c6f8d22946fb7a83d8c3feb251a298fc573c30e2c781e15f468b81b1df8c0d8cfdcbaa3d1ee2a36c441c90fe511fdf1ba3fe09eabb5a0fc0fb2443627ade9bdd2ac6f95e3c30e2a166608c5f77c41ec6f3f86c60dc8fdb23a6f7f7f70bc5249fd1c0e86fbe62f20733c5b06fc688031acfd15f8319c77a3c9f11d3f3507c3a30eebf28f6c0de39b18ffd4a1ec69f401f63bfa60ffdafc233c407b06f616e909787fa0871d3f33829b14febd7fec0787e6c3630decfae8e07f00f413e30ec411b18eba13b03633d241c18fb034e14a3bff8e38161bfa381d1dee5c0d8ffbc3d30f67fec0e8cf8ea6160f44f6360ac37ad0d8ce711dc81a1dfd381f1fc653d30faaba7989e971af2c3dfcc0779d0f35ee703a3ff0fe5613c3e6b060ec023ed23fdbbd287deff9de943efef30b1117f45626fc9f7a1f7779756da735f913ed5fc0fe5fbd0fbbb4b7ce48dfc51300a47f351345a8c62415f4a8938f3f37c4f291d65a37c548cca51f579be0fbdbfbbc447b5d075336a47dda81f2d470fa3c7d1da687db431da14bf3fa5adcff45e0fc7b6473ba3ddd1de687f74303a1c1d8d8e47272ff37de8fddd253e3a151a3e1b9d8f2e4697a3abd1f5e866743bba1bdd8fc6a38938a2d2f433bd9fd291d9481f192373648d6c911c7150d398c69fe7fbd0fbbb4b5c73354f245f0bb4509b6b91b6d0622dd1522dd372ad90c756a9fc54ef94afd26aadd15aad7b967a6da93d688f4ff93ef4feee12d7d6b4756d43dbd4b6b46d6d47dbd5f644dad70eb443ed483b16c7904e3ed3fb9afcfd543bd3ceb50bed52bba2b4fa7eaddd68b7da9dcaf752efdabd361669f2cbdbaeea337e9ebe79e6549b69faea9c67dfbe93e79d26ae1942eba66669b6e6b011d3ce9ab38631c657ef11623e0bc4519158f899de453e361f1db1882d582cf2c4e273c112993f6519cb59a1f2bdd43b2bb531ab58cdde890760ed2aadf4b7fa7cf67bf7d999bd3867b93ae7d9b717797e9bc4d9037b646b6c9d6db04db6c5b6577a139adb61bb6c8fedb3037174950e3fd5bbcc77c48ed9093b15e94ce43963e732ef05bb6457ec9adda87ccff5ce6ed91dbb672b29cb1e2fe53d65abff1da8218e9acc623673c4d4ffb3639c71ce5df1e96963eee3280f78c8e73ce20b1ef384a75f2a61f4ec93673ce7052f79f5a9249efaad2cb7e60d6f79c77bbee40ffc91af7dea179477c05fbece37f826dfe2db7ce797ebf4557ae7bb7c8feff3037ec88ff8b1d23b3fe1a7fc8c9ff30b7174952e3fd5bbcc77c5aff90dbfe57722dd53ce319ff0299f719d1b2adf73bd735348d5e2b6f8eb28298b89bef874c54cdfe5e2d37585665dffb36381f80cc5e7dc8ddc051d8ddd44fc4ddd4c9e957fa984e75a5df553b7704bf73b7a776bb7715bb7737b77e93e087e5cf56ce5139e7b07e473d7c439ebee86bbe96efd729dbe4aefeeb6bbe3eeba7beebe7be01eba47eeb14c27eea97be69ebb17e2e82a7da67799efcabd766fdc5bf7cebd77c72badbb13bc99874f57ef3352f99eebdd3584844cd75abd0fda1b416e220064c20ec4999ed09ae77a2bad399f1df3bdc00bbdb9c7bd48e9c75b78b1fc4cbcf46b253cd7aa9789a3b95778e5b7f5ee49bbf06aaf41bff6dacfcf79fecdebc439fd2fd7e60fe8dd5b7a0f223d7a6bdebab7e16d7a5bdeb6b7e3ed7a7bdebe77e01dcaa30fded1a77a97f98ebd13ef54a633681d9af7cebd8bd1a177a9f23de9ddbbf2ae9fbca477f3a966bea3b55b71f44efcbb7ffeeb374b10b1d7ea8ef850c2d49b79abdf8c6feb1ddf3ce19b3ccbb33fbdd217f4eefc6e7af747feeae920be7a018beffb811ffa733ff2177eec277eea677e2e8e6b7ef1a9de65be7274e4577eed4b0fefb7a2a70bcdfb9ddf8b5f97fe83caf7a477ff511bfb6bfeba481be2dbe6a75af3b7c4afdbfe8ef8bbfbb966fd3d7f5f1c39f00fbfaef79725f847e2f3d83f194a38f5cffc73f1dbc56bf42eaf76e95f7d5fefbeb066ffc6bff5effcfb5faed3d7e97d2c343bf1a7ab7d8df2e94dcbb77d271805abbd57abdd459e389e07fe677a1fcbdf83200ce64174d6040bf1391fbe87411c242adf93de03e18d834c7ecb83222883eaa54c9919d44113b441f7a5a84ce412e373b07c29fb6f95103c048fc15ab0aece093682cd602bd80e3e8bbebea4d36037d813b9f7bfaff7e020380c8e380f8e7f97b82e38094e83b3e03cb8082e83abe03ab8096e83bbe07ef54449300d66811e18e20cf353bdcb7ca78115d881138e424dfc534913bfb09087aecaf777addb845ee8731e06bf5c6abf7fe26118ce458ac245188bcf244cc32cccc3222cc32aacc3266cc5b779d87daa77ca370ffb70193e848fe11aa54741ebe146b8298f767fa7deb571b8156eff7299fd0989873b42af4f290a77c3bd703f3c78f16b197e367f7f96ef283c0e4fc2d3f04ca4d3f03cbc082fc3abe7f93ed669df5d125a09af5fa49bf05668edfa9374f7d97d99e7f9eec3713809a7e12cd443233405bfc8f7a1f777977890bb97df4fa1f5d9f8fe03f93ef4feee12131edbfa7efad27e9bd7e7fbd0fb3b4c1ffbeb3ed23f943ef4feef4c1f7aff77a60fbdff3bd387deff9de943efffcef45cefa11d3a1fe98f4ff64bbdafb43e1f7da43f3d41f3cff42eb4feaa79ffef955eb796f1be4a7edb55bfb57eb35ab3a943e733bdbfe6b9badf2bbdee59c1f755f2dbaecae44efa2f26a9f92fe9bdfeca3378bf6b5a3d0bf6cfb4e99f2bf9ad57e5736dcee67ceecebdb93f0fe6e17c1e9c85f13c0accf96295ff0b7a3f7df1e4ddef9f56cf82fd336dfae74a7eeb557f42eff484d59f93cae1a9b1dfa7e4375ef5a7f4be368f55d2c62f3f3f49c9177f7d6769f52cd8f336cdd37936cfe7c5bcfc620b7ea04ddf2cf935f9bf2cd51fbcaa28a592a97efaeda7f46e0c4fddadf63bbefc7c99befceb3b4bab67c19eb769decc5bf1b79bf75f6cc10fb4e99b25bf26fd94fc3ebdea974a79a9776119afd0bb7cc28a92367efa9c2fe70ff3c7f9da7c7dbe31df9c6fcdb745793bf39da7b3df693aa4a7c628cd77e77bf37dd52eb4607e303f9c1fcd8f9f7e41cb65bba9b53f56b22ce9647e3a3f9b9fcf2fe697f3abf9f5b36f37f3dbf99d92eedbdaf354cafc7e3e9e4fe6d3f9ecb9def12cc4f7f52e9fb0a20429cc77b431df9beb7343fc35e7d6dc9e3b7c2f1aad7efd0dd2253d354629d22216f1c88dbc55fbe8375ffc0b58fdf40b3e65bba9b53f56f22a6f144673378fa268218ec551f2ec5bba3af693f2fbe4aa4a475126cacea3222aa3ea49ef4f4fc17c4feff2092b4adaf8e933aaa346fc6da32eeaa365f4103daaa3ef3c5dd253632f52b416ad3fb52fda8836a32d377ad9626a37b5f6c74a5ee58db6a31d21addd684ba6bda76fac5a1dfb49f97d72d5e7a544fbd14174e8ee28bdbf7c4af4db7aa727b364d2c64f9fd151742cfe9e44a7d199f83c771dd18e8ba773df6d3a1a9e369329ba947fafbc50fca51644d7d14d742b5ba97eb98beea3b1fc855afb6325af64164da269348bf4c890bf9bcfbe59ab634aba6f6bcff352223b7216a385f633719d3f924f5ec9a48d9f3e176cc117eec25bf88b60112ee68b68b158c48be4e9ec779a0a7a6a8cd2225d648b7c512c4af19d5ab0a816f5a291ad54bfb48b6ed1cb5fa8b53f56f24a668be5e261f1b8585bac2f36169b8bad67dfb6173b8b5d25ddb7b5475c674fa6fdc5c1e250d4e26871fc537a1f2f4efea4b47a16ec9f69d3b74bd6fe2139bea63d3fa3777ac2eacf49e6f0d4d87fb4641149fdb2f6fc8cdec3f09367717ef7d4c9a7c67eaf92df7855a1f7c5d7d357f4bef3d9d338bf773a944f8dfd5e25bff1aadfb953fbe5fb71da6b9eb4f97d129e05fbbd4a7eeb557f46efaf79cee6f74aaf7b76e87d95fcb6ab7efdee3bdd811ff4be38fdd86ff3ae4a7ee3555f1bd73dd3fb2fdfe7f991de9c5eaff7b3d5f9d0fbe27c71b1b85c5c2dae17378bdbc5dde27e315e4c16d3c56ca12f8c85f9cb5bf5a6b4b016f6c2097f8ff79dfc6c7ab5de63d9cfa1f7588b59cc6357242ff6e3201619e2285ec4719cc4699cfdf256bd29c5795cc4655cc5f5afaec93f98a4dee3266e567a979f42efabcfcff42edf00477aefe23e5ec60ff163bc16afc71bf166bc156fc73bf16ebc17efc707bfbc556f4af1617c141fc727f1697cf6abebf2f3e94b6fe77cf69e4ea5f773d2fb39e9fdfc1bfbebb4f822be8cafe2ebf826be8defe2fb781c4fe2693c8bf5d888cdd8fad56d7e4b8aedd849468996b08427eeefebedb571e289e427411226f3244a16499c24499a64499e143fb5af524bcaa44aeaa449daa44bfa64993c248fc95ab29e6c249bc956426f2e4a7692dd642fd9273a480e93a3e4f8a966c98948a7bef40ec959729e5c2497c9d5b3e3cf723c3f978e5e3fbd47fac5f79be436b94b7ef22d74c9389924d36496e88991988995d889f3761da4a3544b0e53963e7be7c8f33a0f9a3a49ddd4a33c7efaa6f77eadf49e86e93c8dd2451aa7499a8a21384bf3b448cbb47abdded3fa49ef6993b66997f6674dba4c1fd2c7742d5d4f37d2cd742bdd4e77d25daaf95ebaffaced4267e9a1177e2291a354ea353d49c57c213d4bcfbf9e439d4b74f124b7e7dfa3bbf432bdfafcbd86afd0ce757a93dea677e97d3a4e27e9349da57a6aa4666aa5f61bf5ee64426a99f6dc6e9fd759694a9cc332b28dcccdbcb7e93df3b3200bb37916658b4c045e5992a55996e5599195af1fdfb3ea49ef599d35599b75599f2db307f7387bccd6b2f56c23dbccb6b2ed8c7c63b69bed65fbd94176a8ea921d65c72f6b979d64727ee8dad9996cf5f927c79fe550e73e97d3e7dfb38bec32bbcaae7f544ed94d769bdd65f7d9389b64d36c96e9e2af91999995d99993fe70799fa77c947fa6e74f3967ead79ce76eeead5e2d9987f93c8ff2451ee7499ee6599ee7c56bf49e977995d77993b77997f7499c2ff387fc315fcbd7f38dd78feff9e693def3ad7c3bdfc977f3bd7c3f3f386bf2c3fc48fc3dce4ff2d3fc2c27dde517f9a5f87b9593cc823cbfc96f5f48e22ebfcf653bf3493e157f67d18b77c63fcff174eeb7f59eebb9919bf90fc718b99d3bc5a8d00a56f0c22dbcc22f02f12d2ce645542c8af8ad5a2f92222d5ecc74bee4e78bbc288a72d5f2a25abd35b7105eb6688ab6107229fab9552c8b87959c5ea3f7e2b1582bd68b8d62b3d8cafb62bbd829768bbd62bf38280e5fefe78ba327bd17c7c549717ad61467c57971213e2f8babe25a7cde14b7c55d4163abbf5fac2cf84ee9b29814d34f64312b747c437f2f8c97fdfd798ea773bfadf7282dccc22a7ed833174e392ab59295bc744baff4cba00ccb7919958b322e93327dabde475a9995f9b7f52ecf2a4aa1f7b22a85c6cba66ccbaeeca35d19df9c944b56950fafbb9a362e1fcbb572bddc2885decbad72bbdc2977cbbd72bf3c287f40efe533bd97c7e549795a9e95e7e5457979d69457e57579c398f8765bde95a4f7725c4ec4df6929adb3d4cbcfde215d9a25f5cbd22ec575aa51f5fce88b1c4fe77e5bef15ab78e5563f3c36567e15546135afa26a51c55552a55556e55551955555d5d59b9efeafe41cb8eaaa176fbcfeb2deab6525345b3d566be2efba8803aeaa8d6ab3926fc54f9d6abbda796d7faf76abbd6abf3aa80eaba3eab83aa94eabb3eabcbaa82eababd78fefd5f593deab9beab6baabeeab7135a9a6d5acd22ba3322babb22ba71ed574e59ad5bc766baff657e45dd7c1ca6657dff1b70eeb794efdb98eea457251c775f274fc798ee7e7d22fa936aed33afdec7b56e775517ff67efaefa5baaaebbaa9dbbaabfb7a593fd48ff55abd5e6f9471bd596fd56f7abb6abd53ef66fbf55ebdffe5fa2b4dad5a5b1fd4221eaa8f5691607d5c9fd4a7f5597d5e5fd497f5557d5ddfd4b7f55dfd8ad98a18df9b7a5c4fea693dabf5daa8cddaaaedda69468dd6b0d78fef0d7fd27be3365ee337411336f3266a16c24c92b3a6499bacc99ba2f96199bf87d4544ddd344ddb744ddf2c9b87e6b1596bd69b8d66b3d96ab69bdf6e1eaf8d9bdd66afd96f0e9ac3e6a8396e4e9ad3e6ac396f2e9acbe6eaf57ebe79d6df9b9be6b6b96bee9b713369a6cdacd11ba3311babb11ba71db5bfbccd3f935ad6f2d66dbdd66f83366ce76dd42edab84ddab4cddabc7d4504fdbe9218df37dab2addaba6ddab6eddabe5db60fed63bbd6aeb71b3fb76ed36eb65bed76bbd3eeb67bed7e7bd01eb647ed717bd29eb667ed79fb1373e75f9fdacbf6aabd6e6fdadbf6aebd171a1fb79376dace5abd355ab3fdedd6205fb34efbc37ab75ba71b755ac73adeb99dd7f95dd085ddbc8bba451777c9af6ef3cfa52eedb22eef8aaeecaaaeee9aaeedbaaeef96dd43f7f8abebf6b7a79fd27bb7d6ad771bdd66b725d276b7d3ed767b22ed7707dd6177d41dbfb14ebf2c7527dd6977d69d7717dd6577d55d7737dd6d77d7fd1effe7911f4bafde57f9fc3eec47faedd3abf7d73ddf77f1917ef714deacfcf737fe7d719fd59fbddfa61b77936edacd3afded65bdd7f46dad6b6b4f7aefe4dad9bf61bf4da77766677576e7f47fac6f7b7d7fef71febf60bf4da7f7ac337adebbfd9bee84fedaf49d79dcabdf5ff7dccfffb9fb6dfad13ceca6bd2fb41ef4613fefa37ef1abebf473e93bfb6d5efdfebae77aff53f7dbf4719ff4699f89de9ef785d07cd9577dfd766fff3befb779aef73f73bf8dbbd3b3bee9dbbeebfb7ed93ff48ffd9aa0a65f77dfb83aff5ef7dbbc46effdc693deffc4fd36fd66bf25faf776bfd3eff67bfd7e7fd01ff647fd7167895fd7ff8ed8fefdedb77995de4f9ef4fe27eeb7e94f45cfdeeecffaf3fea2bfecaffaebfe467cbbedefc4aff7fdf847cbfb34fdaefb6dfac993deffc4fd36fd54f8f459aff7466ff6566ff7ce72b4d4966cc997eed2ebabb7eafd3defb7f9d6fbeb96fe93deffc4fd367db90c96616f2ce722454badb7968b65bc4c96e9321311de9bd6e8dfeb7e9bd7bcbfeeb9deffc4fd3642eff9b2103dbc143dfe6a29c42ffabd213ecb65bd6c96ed5bf4fe5ef7dbbce6fd75cff5fe27eeb7e9ab65b7ec455f5f8ad1dd593e2c1f976be2dfbaf8bed1f3e5e6afaedf8fa6d7edb7f9fefbeb5ee8fd0fdc6fb314d1fc727bb92334bf2bfabab1dc5b8efa9be5fef26079d8fbfde9dbaff09f4d7fd77e9be77aff13f7db2c8ffaf5e5f1f26479ba3c13ba7e10e3faf9f26279b9bc5a5e2f6f7ebf7b347fd77e9b177aff23f7db08cdcf97b7cbbbe5fd72bc9c2ca7cbd9525f1a4b7369fd7e5aff6efa29bdffa9fb6dfa78692f9d87d183f6c01ef883fbe03df80f41ffe66765de617ab5de1fe47ae9c7be8b3f24fdc4fbeb7e799d3fd2dbd34fbdbfee63bfcd6f9f7e4aef1ffb6d7efbf4eaf7d7bdd0fbc77e9b779ffe89e7263ef6dbbcfff4f17e9bd7a78ffd36dfd6fbc77e9b1fd4fb6fbcdfe6b9de3ff6dbfc4c7a8ffb6d7ee4ff2bf4b1dfe667d27bdd6ff3faff8fd8c77e9b9f4bef75bfcd6bffbf811ffb6d7e34bdeffd36affdff847eecb7f9d1f49ef7dbfc485cf7b1dfe6fda7bfebfd362ff4feb1dfe6dda78ff7dbbc2e7decb7f9b7bedfe65fb5df867dfd0efcd7efc77decb7f903d22b9f83a6fd36b6e0fa23fde9297442fbf9fe3a68fe23fdf149ae7b3dd7fb47faf7a40fbdff3bd387deff9de943efffcef4a1f77f67fad0fbbf333de9fddbab7f7f727a2e8f5f5d97557a98fff32dfed0fb3bd47bf4cfb7f8b9decf1af5fbd3b72fa5b36695befdfddbbfbcf64aff99f452ef9fd6f03552f8fa2fcf3f5fdbf687c53fdfe21fd7fbf3b67cedfb975afde5dfdea3de5f53b31f69edd7dafc55bdc7ff7c8bbfae77fc7b7dfbbede9aafebfda91fa85f3ffff6cfa72febfddb52f8bc6ddf93cb7b6afbb7f5fed25abfd6be4fcffb9ede5f8e0ccfa5f0a56fff89f46dbd7fbb2edfd3fb4bbffebab63f24ff74dbbfd7dfbfdce2cf47c0af9fffbd11eff9394fe5fe67bdfff7fafb97a5f069db7ed4cf7fbded0fe93fdfe29fd1fb97dbf7add1fc6bd2f9f2157f0fbd7fcf0f7edecad7b6fd21fbe75bfc363fffb5ef5f93d59772bc573fffedd1eb7b16fda5df5edbf687fc3febe75f7af0e7bafffaa8f5f5ef4fa57d6d7c7f9eefebdffecef4507c590a5f9fc77dbd8f7ede921f99c7fde7db8e7902e60acff7db7c7ad67fd6d7fe442bca9fc8537de9d777b76e53bfb984e48bbf66f8a7f48efd759f9ef5def5fef7a5f7a6f7ff448bfffbffffdffff57f00df5408b5</data>
+ </image>
+ <image name="image2">
+ <data format="PNG" length="89163">89504e470d0a1a0a0000000d4948445200000124000001470806000000089931180000200049444154789cec9d779854d5f9f83f77faecccd6d9de2bbbb02c6de94529d22d20224d3416921863126389311a4d4cf9fe8c51634c2c08280a224ab5d061e9bd2edb7bef33bb3b3b3bfddedf1fcb2ebb80a04844713ecfc3c3ec2de79c7bceb9ef3de73deffb1ec164324978f0e0c1c3f700d9f52e80070f1e3c74e211481e3c78f8dea0f82617171717b3ff7811378d1a464cb80f151515d4d5d53178f0e0ab2e40454505c78f1f479224dadadaf0f6f606203d3d9da8a8a8af9dce993367282e2ec6e57261b7dbd1e97428140ac68d1b874ea7bbe2fde6ba324e9fcdc6e2923172f0000ab24e516eb23174c8102a2a2a18366cd8553fa3070f1ebe1edf688474f2e449fef2bba7d874f0181697487676365f7cf1c5b72a80288ab85c2edadbdb59b264092e970b97cb85245d59b5258a52d7759de9949696b272e5ca4ba6d3fdfa0bd99b91c1a1438770ba5c141516b061fd3aec2e279224e176bbbfd5337af0e0e1ebf18d464800e306aac83db89f8ac1fd7abcdcb5458778efc3cf303914f4bb6932b78d1d4a79412eab97fd97d8e8280aaa2d0c9a7e2fb36fead523bd989818626262b0582c7cf1c517dc75d75d5de7aaf2f7b17ce597343b95f41f3b95db6f1a4c516e16ab97be49446424529f5bf9c92d69e8d472060c18c08001033879f224a5a5a55de9949494f0fc53bf2625211e63e4cdcc1a91c8fa958b319a6d08720da3ef98478ccecd7f977f8c5aa365dacc39bcf1c61b6465e5306dee03e8743a76eddac5c8912371b437b079c37a8e6495814cc1e4c95318336af8d5d6bd070f1e2ee0228164b7db319bcd3d460582201010100040f4c0c9c42b2c7c76f834bd7462d7359fbff30186090f70774813afbfb78dbe51d1585a5b39546563f2a2050c359fe4d5652b987dd39fbe76e13e7f6705c153163127b08e57966e61404c34cdcdcd1ca977f3fccf17921a15825675f9419ec562e150792b537e3e9f3b6343d02804264c9a8aa5ad9d7653211fbebd8a57ffef51468c1c85c1602021218169d3a6a1542ae99796465b5b1b393939001c5afd21274ddedcb7e8617c54223a9d17004ea713a3d1f8b59fcb83871f335e5e5ee8f57a0441b8e85c0f81d4dede4e5656162d2d2d2814e74fc9e572d2d3d3019029bcb8e3c13b78f6d95538bbe98e8e54b7f0c7f47822fc7a23b019477b0300a911fe0c4b8ea2d5e485ade51300b2b2b2282a2ac2c7c787b163c77e65c18fd5b6f2a7f404c27c9291c42f71589b00e81f6d605872344ad9c50f74299243fdb8b96f2c2a99406b632d27b6ada1dce98d562e5253ba07a5e257e8f57abcbdbd51abd5f8f8f8a0d56ad16ab5b4b5b575a5b3a7a09ef45b0612171d8ea25b65daedf62ea1e5c18387cbe372b9e8dfbf3f414141179deb21906a6b6bb1582c0c1d3a141f1f9faf4c501b94cea4115b78764d06b70e0e0520d64bc1e9aa3602dcd5b89d2a640a6f7058910bc2b9975706744cf19c4e2756ab15b55a7dd982c768e59cae6ac3cfd184e8f24290eb01234a99f0b58511804226a03a77bdb1b98da3790dfcf695e731341ce0f8e17d5f3b9d148386fc927ac68c70e1ad1441129129b4e8f5facb0a560f1e3c9c272b2b8bfcfcfc2b0b249bcd86bfbfff570a23a5528946a30160d0d85b19b2ea576834b100cc983795a51fbc4e066e22068c22323692d2bc26b45a2dd031edeb5cedead4f75cc885ab6177cc9dcc7befbfc64e5cc40dbd99f0e830da5aaabbd2bc1472b9bcc779994c86979757d7df017e3afa477af1e65f5e2020280287a00740ad56a352a93a2a45a1e851eecefb27ce9ec5ca359ff1f73fbd8052a960d2a4c98c193df22bcbe2c183878b898e8ea6aaaaea92e784ee96dad9d9d9389d4efaf7ef7fc98bdbdbdb71b95cf8f8f820ba5d988d8d086a2f7c7c7c703b6d34b7b4e21205b47a6ff45a354e8703abd58a9f9f1fa22862329930180c974cfb52e75d4e1b2de7d2f4d27ba33b97a6cd66c3d7d7f792e9381c0e2c160bfefefe40c768acadadadeb6f4974d36e6ea1cde644aed222ba1c041a02b0582cc8e572bcbcbcb0dbed5d79b8dd6e9a9b9b31180c4892487b5b2b16ab0310d0ebf578797db570f4e0c1c3c598cd660e1e3cc8a449932e3af78d0492070f1e3c7c5b2e27903c96da1e3c78f8dee011481e3c78f8dee011481e3c78f8dee011481e3c78f8dee011481e3c78f8def08d7dd94451a4b2b2928282029c4ee7ffa24c1e3c78f881121414449f3e7d2e6b2b7839beb140aaacace4e4c99368b55a54aacb5b5aff5091c964a8544a9c4e97c7d3ff06a4a36d9d7c8d80123f6a743a2f4449c266b55eb1ae3a6cf8b4188d46b2b2b2ae3a24d1371648757575787979a1d1e8106fd01675bb45cc6ded28154ae40ad5f52e8e876b8ccd6647a15421bb8473a787f304040452df508f8402e10aae5a4e971b8dd68bb10306b063c78eabcef31b0ba44e060c1c844673e359294b92445555253b77ee60e4c8512425f5fa5ab1993cfc3070bb5cecde9dc1a8d1237a38907bb898ccccd37879e918383015994c86288a4892d4e3ffcedf8d8d0d1416e6137c09ffb46fc255b788c3e94490c9bf55e6df472451c466b375fc96241c4e27a2285ee12e0f3f141c763b6e51c42dba713b3ced7a399a5b5ae89f96865c2ec7e5ea505f7cd53f41902108321c0ec7b7caf3aa0552a774bcd19044b16b2adafd2be0e1c6a0b32d255142c233f2bd2cd7a17aae7ecc2a7d7538d81f329224d15d83279d7bced292124451243e210180f2b2321c0e07894949df28fd9aea6afcfcfdbb5621eccd45e4b7e808f65270e2e861b45a0dc83524a60e20d270e558e000d5d555040418ba223178f86a3afa6c479b76b6b2dd6667cf9e0c944a05220a22935249083720ff06216e6e442ef57a3b1c768e1f3f467afa90ff499e573f423a377ab8d190ba09daee23a4bd7b77e3743a898d8b03e0e0c1fd984cc62e01f57559bbf613264e9a4a6262220025bbd673409d4e8a9f96a54b163363e64c5a1a4a3892d3c8138b6ebb42613b3acda79face6b6db6e272636ee9b3ff08f8cae18ecdddab9b9a599fffee775ee9a3d076b730519478bf8cd4fe7e0e7d3f1d190441004e02ae453e74bfdc3d49f5f2c91567db482f7df5fc6134f3ecdd8b1e3af798e572d90a41b7884d4f9581d83a5f35fd31ec2eadc795174d158799a8f566ca045f266e4d4db18d3af174e63153b3e5b476655333e8600a62cb81f63f66936ac5f477e7e3e83070f61debcbbd99323d167bc1f2a59c7686beebc7b68accae2d917dfc575df188e646c66dfb15c548189dc7dcf1cc2b40a962e598c416ca68c30442f039b37aea7b4a498c143863267eefceb56773f043adbb747ff9524828282993b6f01ceb66a7ef3e4ff91979bca81cd6b080932608e1acb9cb1bda9c9ddcba6ad876813fcb863e102fa860722d91bd8fad93ace96b521f38e263144ce1d33eee48d57ff41b48f8c62453c13274da660ef1a720a4a41aea1f788f14c183100536d251b57be4b787020b95556fa8f9d86b26a3fc70b1a881c349999b70c46afbe7e7ada0ba7b41faf5ac9ebafbf8ad168e4ef7f7b118031636ebea6795ebd40122524f1461548e747489dcf2949125b367f49457939000505f98c1a3d0647bb954d4b3ec4efe67b19af2e62e9ca8d24053d405d713ec78bab187fdb6c4203fc08542b09eedd87f88404a64c9946ff0103b1d41cc5e41b807760248ea622dacc662a2acaa9ca398ade3f9efc0307d97fac94e15366d196b385f7966ee7e9872773e2c47122864d63def82128942af2f6c43375fa6df4eddbf7866c936b498f299b78be9d6d763b1515e5b4541d47a10dc66cb6b02dbb9ac79eb897b1b11158ebabd9f4e956126e7f9018eb41562ef99c3f3e399fac2f37915903b74c9ec8e9ed4bc8c909e2f6db6772e0c46934737fce5de929f8fbab90a50d262c2a1e7b7b035f6cda4294af1f4a591b5bcf94f1db2717705bdf6cfedf3b6f337bd123dcddaf8ed7de5ecfe8d42874d161d7b1aeceffdeb1632b1f7df421be7efef8fafa01b074c93b040606d1ab57f235cbf35b08a41b53d9db73e4d74da92d4a4c9c3485fbee7b0080359faec668326277b93956ddcc9f47a6a22301fb87bfc36e311119124c884ecde1fdfb090b0e24d902e9a9b17879e9080a0a26d060e0cce73b09f1551212aaa3bc51a4a0208f0f972f43e16560eea239e41fdf85d647c7e0d4644a9536b6bcbb0a519c0892c4f4c149448506031d41d3838382310404de906d722de958a6eeecbfe7b7d06aa8afe7c3e5cb40e1c56df7ccc14732931c61604cbf5e280428a8b5536d75f2507a321a2902d3aadfe376dec5c92a13711151a426a760aa1947edb1b388a2884ead64fad01482cf05066c38bb9b3d3935083281eccc8358a78f41e1ed4d52988191694958db42d0481b99322819859084dbf1114e7bdbf56dcf6e1269c284498c1d3be12b57d9ae15572f90e0069eb2493d7e774cd9a4733a9bce295bc7df0210a294915b672155590e9237086a7c22a2b8f3278f6031d572f2d84e567eb496412f3e86127088126e670b7966075eba04fc1532ca2489fe0306f1e4537fe82a8bf58c8c7c8b9346b38df6fa42145e715df9ab84f365519c4b5394a4ab5173fca8b8b06d3b7f474446f6a8fbcccc332800391d533c8d0cb4a244b9d146a43d0b992a0c100851cba86cb163b65868afcfe95aec110065b7fcb6ec3ccef85f3ec350839d96eaecaefc65804c92902401a12b3fe15c3ae20df98e5d8e6fa1d41611a51bef6bdcb3a39e7fce4ea1d4f9cc9d7f2b1472c68e1fc4eafffe1fde7207510346e263f0a3aca480f5ebd622c865381d2e12fb0c419444862786b2f1d38f38bd4b893a2008bf81539024b14bc9dabd4e93d392c82ecae4ed7ffd3f64929bb1b72fea28cbb972745e3b32299435ab3e20376d0077dd35fbbbafb41f1062b7295b67fd89920817d4bdd4ad9e01028202e8d73b84e5fffe3b4a572be9b7cc45a6503078647f72d77ec91bff29c6d4d4446850d025db283d3582ad1fbcc371430079d5766e95c41e795c985fe707ff7abe63d743187ee310b6478f1ea5b9b999e4943494ca1bcfad4292246a6b6b3879f23883060d263c3c025114696969469224fcfc3a86e0adad2db8dd6efcfcfc71dadb68a86fc2851c9f0003be3a2d0e9b95c6c6064409049902df80207cbc54d85a8d34b698a92f2ea4aca4989be6df8f41a5c06ab56236b7121c1c72be2ca28bd66623ad6ded084a2d4121c1a86502353535041802509ff325b4b51a696836a3d6687adcefe1629c4e27a74f9f64d8b0e1b8dd1d2fbbcbe5a2a1a19eb0b0f0aeeb6c361b2d2dcd848474ecaa234922d6b6668ca656dc28308404a3532b41745258584863432d678e1f45e697cea27b6fa1baba9a909010e4f20ea5b4cddc44bdd18c4ca9c5e572111ce88f4c26ebca4314456a6b6b080f8f00a0a6a61a8321b06be389eb4176f659f47a1d5aadaec768f2abfeafadada17fbf54ce9ecd64ca94295f99eee542d87e8b55b61f970ec9dbbb632796ce67d6ebbdbbae57a8748445eaba27824aad213c22aa47daa228a2d2fb11aef7232c2c82bec347a3507498e4abd56ad4eaa00bea5486b75f20de7e5d09238a122121213dcaa2d2fb11a1f7eb71ccc3a5e9a89f9e06af3299ac4b2874a252a9080a0aee714ca3f3235cd7d518e794e20a4a4bcb389b791aa57f3453a68d401445424343bbe5072a9d3f913aff8bcad33d8fd0d0b0aedf9d82f07ab667427c1c955595d8aced5dc6c23241e8500d9cb3639024a9cbad243c3c9480808b9ff19bf02d04d28f4b8774cd1104e40ac50d5987df672eb9ecff2d193f6112e3279cffdadf286d1a14144452523c32d9d70b9ba65028ae9febc88d6c87d4691076ad3bae87ebcfa594da1e2e4da7201204a1abae04414014c54b8e90ae05572d90cce6566437a0732d80ddee40a95462369bafb8bbae871f16d2b9d5ab8686862efd8e874ba3d128f0f5d5238a629770eafcdd29943a7f5f2ba174d502a9a5c5d865c771a3a156ab19397218cdcd2d3435d55fefe278b8c624c4c7626abe71fbefb52238c81f499290cbe55d23a4eec2087a0a28a552f9adf3bc6a81346eeccde8f5fa6f5d801f12a2c381a3ba1a4743038252892a2c0c55602082e74bebe106c462b1f498ae41c70853e8e698d779fec2ebae164f84aaaf81e472d19e998971d52ac4921204b91c51107000ca4183085fb810758867b9ddc38d45774173a1cee8429dd2d7557c5f098f40ba02a2dd4ecba64db42e5e8c77efde68e7cf47eeeb8b2449381b1b31eddd4bc1b3cf12f3d453e8131210ae51c378f070bd51a954389d4ee472790f13894e01d4190da3f3d8b588c079d52964e614d2ab4f1f0cbaf3865be6d61672b3b3b1b9dc28d47a12525208f6d6909d9d4d4343030a85029fa060e21312d0c9cfbfb8355595141717222167f498315dc7edd61672cf666176298949482022c8bf471ce482dc2cea1a8c2057121811435c44082ab984a9be8aa2e2729c0a6f52fba6e0ab5523890eca8bf2a96a68c53b309ce4c41854328193274fd2dede8e24b9b0db45060f1e8cafaf77571e9663c7687de30d82c68d4333610282db8d60b3814c862a2e0e4d4808ca0d1b287ae92592fef847745151d86c56b2ce9cc6d4d2429fd434c2c33b0cee8a8b8b292f2f47a954a2f5f621b14f2a3e0a1936731d595945d85011151b4b44880179b7e72c2ac8a3b2b212bf80c02ea3d5768b91cc33b938dd22080a2212528809f645762e864f4dde09aa5b5da40f19daa3dd9a1aeb292c28c4e91651ebfde995928c8fca455e6e3e8dc6561064f8044690101b894c7470ead4a90eff2fd1812468193e6c304ae5f96ee3b059282f2aa0ce644690ab481f3410b5baa34f389d4e0e1d3ad4f5f50c4b4a263ad01f5343150505e588805cad272e298550bfef772c27b3d94c7171f1658d866f34ec767b9730ba506774a14ee9ba2bb533b6ace1486e23bf5e784bd7b1bafa46bed8ba139d9786f6961a34a7c6f1bb45d379ebadb770bbdd242626129ed287d0b87874ddd42ed939396cd9b2957dfbf673e0e081aee3793b3fe6ed8c0a42556d103e829f2eb88350bff3ab5ebbf61ea2c9d884cc65a6dae2cdcf1fba97787f896d9f2ee370b580ce514b76e3c33c34350d53de41967eb40d41aec025c2e479bf664c8a3f67cf9ea5b1b11173e931be3cdcc25b4bfec3807302497438302e5b869fb737dab434845ebda0be1e8e1c011f1f849414e44e2701e1e198d6afa7e6cb2f897ff041cc6d16bedcb4956d3bb6f3b39ffd8c050b1600b066cd1a4e9c38c1d0a143f10f8b2034a50f3ec0ee8f97b2a9d84684af1229ab2f736e9f4c4cd0f978e5070f1f65cfeeddb4592cac5cb91280764b23878e1ec1ed1271b41ba9dd7682bf3ef5003a2f0d7653216ffe77298773f2d9b2756b8f762b2a2967f3f65d786995b4981a894d9fc1fdb7f5263be72c2565b588ce764a1b9ccc9b3b8fd484108e1d3b86cbe5c294b5857db549ac5dd90fbf73024974dac83db299353bf2f0f55122ba45faa6f6ee1248edededfcee77bf63f6ec0e779681fe418407f8505f5fce81c3879109022dcd8d68c2d2f9fdc3b3aeb62b7e27949494f08f7ffc830f3ffcf07a17e53b43a1505c341dfb2a9dd285baa5abcef36a6f9c30aa1fff5afa197413486191513cfce8af09f2d3539e9dc1137f5e058ba603307bf66cc68e1d7bc9b4d2870ca757ea0072721fec717cc7673b19fff04b4c09aae5d77ff99cdaea9184fa45769d9f3ee32e82fdbdc156c36f1eff0bb515a5e8ad6ace665732efd95709a9dfccd36fefe4a1a9691cdebe0f55782f1e9a33851d6bde63dfcec38c4999c2c2850b01895dcbff4d9dbf847ff8795d90bda2022927076d4c0cc29933101b0b8989e074825e8fe8e3836bc50a5cab57a32d2aa2f5c4091cb366e1e7ebc7a25ffc0ac7255671264d9ac4fdf7dfdfe3d8fa6d2758f8a7971912ade1d997d6535a54414c50afaef393a7de4a62721f5e7ff5e5ae630181f1fce297bf422993d158b893879e5e8bcbe94212ad6cfdf4731489a39017575c947fafdea92424f7c14fa7e448c63a16afdac883338771db8cb9c86502d6a642fef4e21bd454d6317a700a8f3efa2820f2d10b85b8c7dc8e5273fe8360359bd9f3f926fa2e789e59fda270dbcd28543da35c060707f3d8638f75fd2d4912c9a9c3494e1d8542267078cb52fef3c959e0bb1748dbb66d43a9543276ec580a0a0a3874e8100b172ee45faffe93041f385ad24c50f248eeba7dc2f9f28b4e4e6cfd982c7b3449615a4eedd88046e74da91126cc79809b7a07e1b256b3eafd95e4d558484cbf89dba7dc447bee3a76d60e64ee48272b57ae2076f81cfafa7b7368f72e5266ddc3a677ff4b8cd6c1b1d21602128732eb8e4944fa5f5f93934e01f35dda215db5c2a3e8d43142533b8233ad5cb9928a8a0a741a1521fe7a24473b0547f613dafb2600bc7d7c59b67409bffded13bcf5d16754355bb15aad2c59b204003f5f6f027cbcbaa61b9d1cafb33122ca17af9054445b3d6e6b538ff31141bec80591ca9c9348ca007401113459dd34da25528375f8448dc05a7b0c80d30d36e20c5e187c03d004c460ab3fd3958ebda584a345c5f44bee43b8eff94e602b2b4361b1202b2b831d3be0e597213f1f5252904242702d5f8ee32f7fc17dec184aa311b1a2029bc98452a92034c80fb5b2e7ea9b4ea7e7f3cf3fe3b7bf798c97dffa80e2c63600120cde9c2d28a7b2a4809aac0d38db6a7adc1764f0c3dbab67e794c914e46567f3e82f7ecacf9ffc17436f9f8e4aad206fef9764b77b3176cc4034ca8b57fffcf45a0c3e5e382dcd949c394d78da3804418ee872f2d717ffc4c38f3e8d511b4eef41a95df7586a8fb0abccc9d401f16895e7bb4c9bddc5a67da7c9fcf4df3cf6c453ac39908fcd2d72f0e04132323210048176ab8d277efb184ffefe8f6cd87b0a9b53442153b06dcb661efdf9fdbcfcde2e26ce9f795139bf0bb2b3b3c9cfcf07a0bebe9e83070f02b075e71e325549ccba630c3947b69273261b00abc5c4d6d56fb3ee581d692971545756b2fa782511432731b4af172b172f0720e3ddc5e4da83983a6108c507b7b27367166e85826deb36517b3a93ecc36bf930ab84acf262b61fc82550296347c61e4e08b1cc9a7113a599199c3e7aeabad449771c0e470f01d45d81fdbf9ab25db5403a6e8ee5e18726023073e6cc2e3d89d362e2e0e71fb0314be4e19f7638d83df29b2778f9d57ff1c4af7f42f5899d6c5cb71b8d46c3bc79f32e5f38014424a05322f71458a2db4555f621de5fbd8b41b74c2235259cceab3aef4390773d68a7e5b5800442c7a34b9244657611f54d7292d3d35176178a828068b3416e2e525e1e92d188248a482e1788226834087239b2ce3c65b2cbc62a9d3d7f216fbcf52ecf3cfd6bbccdf92c5bbc11807b1e7b10e3894d2c5db79732b3beabcc5722393999bffefd255ef8ed3c4e6cdb8bb926972f33f6d3ee50d0589243535313d90585d82f18a939cc0d6cfff47d8e9982f9c503e3800e05e6638f3dce8b7f7c026d6b0d855945e7eac7cd996d875045a41219197ef15e663e218c9ef3288fff643ceb16afa0c568263d3d9d912347a2d3e9797bd987fcf1853f72ff1d8358f1e6fbd4d43400307efc78fefaff5ee1dee903d9bd71d7d77adeff151dc692e763faa8950a668e1940dae0f168d5726c6db500e41cd9cf9a8c0226dc3e9b7e4911c86502837b4572f390fef41e3889e6ea13006cca2c67dc90de0c193916ff607f1a2b4fe113348cf0b6fdac39632639653c8ee395d4e4ee4416371d1fb980522167c6e8fea4a58f43efa5c5da5a755deaa23b6ab5bac7aa5af7d1d0a50c25af85a1e9550ba45ffe723ef1860e3b24ad568b5c2ec76931b167e347acde57cd829f3f404a6887a35d60800f0101fe040645e0efef8db5b50e4110f0f2f2ba6c1e4342b5ec2b6da6ad261341138cdccbd0e37c7dc151967db08ee061b732e7d631e894720c5e7282d40299b5169a4bf6a10deb08463e30444b51a385c6e626da1b4bd0860c0040745ac829ce443224911eefd7237d4d5c1c36ad16b1b919a2a3e189272026063efa08f6ed4379d75da87ff73b548181380501a2a2d0f87fb573a19f8f8ec0407ffc0242080d0fc362aa04202471144ffcf1affc7afe18d2faa4a0ea362dfd2a5c6e1b0e64f8f8fa1193d81b675b3da25b49725418325b15870e1ea4a1a181b3f9053d0492bdb9864d1fbdc78e22899f3e721fe17a1592e8a0dde542abd713121e8dde4b89c3dad2918fa59add0555f4eedd8bb00ba6105a85c06dbd0dc4450613129980dbd98c243a51a954a8542a643281b050033e3efe44c5f60267336ea70dbbd3862857e2e3eb4f546c02b6e6ebf3f279cb059aed6edaec36daaa4f761d97c904bc9572044171ee43d8517f318949f48bf166dfde7d18cd36244942ab90a196cb10642aa043a8457829a830dab05b5a715a2cc85506bc342a0624585976ba0e29fe21926a8e929d7184d4a9a91d16cf42f73c65c0f5779276b95c97d519414f3ba4ebaad4fe64c93b444444307ffe7cd6af5fcfb061c368ac2ee3d99717e31dd79fcf3f584c4e6c0cf7df7f3f3bb76de5e891c358db9ab1083ecc987233369b8df5ebd73377ee5c366ddac4e6cd9bc9cacae2c9279fe4965b6e61f2e4c98c9b31997f2f7b9d130a1b7169e3098b08ec5186d7df788bf5472a99aad2f34ad61eeebdf75ec223c2e9db379a0f5efe331a572b5366fc0a802193c771e0fdf5bcf2ffce22537b33f3be8ead7ead2dcd141ccf2461dab3782b7aca67754404527a3a6d2525f887864240007cfc31bcf106848723a854c8a3a371faf9d1ac52a1193c18959f1f0d0d0dbcf6da6becdebd1b5f5f5f4a4b4b79fcf1c73971f2243b766cc76135d36a93187b7b87ceacbdddc2dbefbc455571215169e3e99518464d4d0d870f1f66c68c192c5dba94bd7bf772f2e4499e7cf249eeb9e71ec28315bcbd641d2e9783767323c3a6cdc037aa17d31f48653a50535343515111774f9f0ac0c71f7fccb469d338b27f3f2ffc6725710387b3f2cd7f3168407f6e9b3e86b5abd651545489d3d68ad33b8a5e691dab49f5f90534b5bae9df7720ea735fc503070ea0d168e897da8b416347b0e4e5bf22591b891f361e2fbd0fc78f1fc7e1703060e040de59bc9896a606cc2df5c40db919df005f72ceec63dd67fb1124176ded1626ccba3e71c047a4c5f2eec71bf8ebdf1a6931355e31b89d212a9979f72c64f587cb7877959a48bf4bbf8033674de4b575ebc8d923e0520772d3b02128b41a02faf6c29e5948f8c038928a455edb2ab028c9f7da3fd835e27ad8215d753ca4c4c444fcfdfd898d8da5b2b21283c180d3e120bfb0088552895c009d4e477c7c3cb53535343535214a123aff60c24383500a12959595c4c4c4505d5d4d5d5d1d2e970b85424168682861616138ec6d949794612489c525000020004944415475cb09090f27d0cfbbc79421272707abdd8952de712c2e2e0e9dce0b737303d5d5f5b8e55a62e2a2d1ab5548a293baea0a9a9adbd1fa06121511825226e072d8a9ada844131143a0e662f9dc7cfc3895bffc25d16d6de8131391353581c90432194446e2743aa92c2ba36adc3806bcf002fad0506c361b797979389d4e044140a3d190929242b3c9446d5d6d47b811bd3f919111782965b85c2e8a8a0a71ba2442c22309f4d363b3d9686a6a22323292a2a2225a5a3ae22f29140a626363f1d22a28292ec7e976835c4578740cfe3a4d57fd381c0ecacaca483ab74d53595919e1e1e1349b4c945556a2542a9101fefefe448487505951414bab054990e11b144a6860002ab980b5b5997a532bfe6111f8a83a86e48d8d8dc86432fcfdfdb1595aa828afc4e616088a8826c44f4f73b3095114f1f7f7a7b8a808bbdd862428088a8822c857475b4b239555f588928842e34d544c147ad5776f12e7b699a9acacc26c1791ab7dd02a5cc4c6c6525050404c4c0c2a958af2f2727c7c7c50a954d4d4d4909090405b6315b56d023e7a350e9b95c8c848ec763b15151524262622bada292f2dc76c73a3f70f24222c18a520616ea9a7acb19dd8d858e42de554363a49ea9584204061612191919168341a2a2b2bf1f2f2222020e03baf93eed8ed765c2ed765ed90ba4fe3542a1576bb9dcf3efbecaae3215db5409a3a75ea8fc275c4ed70d0b86b1735afbe4a80d1888f528952a1409424ec4e27759284a95f3ffa3dfb2cde5151d764e9d38387ef0366b3b94b2f74a1cee8522324994c86d3e9fc5602c963a97d05e42a1541b7dc822a2282ea2fbea0b9b818c162c12d93e1f0f646dbbf3f83eebc13afc0c02b27e6c1c30f88ee764817ea8c3af9ded821fd9890c9e5f8f7ed8b6f4a0ad6ba3aac4d4d080a055e2121a8fdfc90799c6b3ddc807c5d0173ad1c6bc12390be11824c863630108d9f1f08028252e9f15df370c3d2e9c7d6a927828be321759fb25dd755b61f139228e23299b0e5e662cbcec6515787a054a2888e46d3bb37bae464e45aed9513f2e0e107844aa5baa252bbbb30eabcfedbe0114857401245ec454518df7d17674e0e9ac848b4a1a188eded5876eca069c306bc264c2062de3c143f0225bf871f0fdded90ba2ffb7f952b896784f41de06a6aa2e1b5d75037351138670ecae464847391f10c361b6d9999546ddf4e391073df7dc8afe3b6351e3c5c4bae95a2fa9b70d502e95f6f2f67ecad3319957c7eeff1d2e24296bcf336669b0b95dec09439f7313e2d8ad75e7b8decec6cbcbdbd891b34845977cd264c7d5e11bc7bc756d6adf984967627cbde7bafeb787de909162f5e41bd5dcdcdd3673175f4c01ebe54cbdf7d8be39939c8946a12078fe7eee9633168444eecdbc4da2ff6605707b3f0a78b1810138cd352c7ba8f567038a78af094212c9c3f8b609d92975f7e999a9a1adc362315b54efef67f7f25392906e8181d1957ae44999747c0fdf7231f3102a1ae0e4a4a40a542484a423f6c18918d8d14ad5f4f7d7c3ca1e3c7636c6ae43fafbdcce9b3d9fcec178f762d6fae5cb9922d5bb610181848506c3c7317fd8c588d828a33db7877c5262c8237236e99ce949bd3d175f3435bf5e17becd8be8dc8b85e3cfffcf31d75539dc5ebff7e9f76871b5192933e710e774f1c805a214774d9d9fccedfc9286ce6a5575eebd16ea74f1c61d5aa8fb1ba44f48668eebce73efa87c307ef7dc8999c5224414e70e210e6ce9c825e6ee795575ec1e170e0b2d4627687f2faab2fa2d77758d84b9288b1aa888d6b3e25abb40641e5cd1f7eff3bfcfc3ab68c6a6b6be391471e21f0dc0ae44df3ee65d28014724e64b072d5164401e45a0313672c60d2e0d8abed8adf09454545ac5cb992e79e7bee7a17e53b43a954e272b97ae8872e6787742d8c23af5a200d8976f1deebcb18f59f67ba8e697d839836f741122203293ff505afff6b31e3dffd33c5c5c54c9f3e9dd1a347a350a9d1a97a163c3c2e99bb7ef2087f79fe991ec7f7beff0eaaa1f7f3cb90325e59b38be4d83852e3ce1b8bc5a78f65fcf499086d25fcf51f2bc88b09a777888c5d5fee60e0ecc788ae59cfdbcbf7f3e67333c9fef2138e356a5878ffbd1cdeb29a4f36a5f2c85d693cf4d043b8dd6ef2b72ee7cd5d2d489af3ee232ea391f62fbe202c2404b9cb85a0d34172323435414000524c0c626e2eaad252bc8b8a68dabe9dc0e1c3517be99970c77c1a2d1fd0d0d0d0955e55551583070f66fefcf9c8150a74e784f2fb6f7c48e2dc47991023f2dfb53944844633bc6f68d77dc9fd87a3f20de5d38f96771df30b8ce1e1c79e442397d15a7984a7febe84db47bd84ca5b43d1d1cfd858e14f71f6b18bdacd3b3896bb7ef23091813a8eef5ccdb27f2fe7f5971e66daac054c17251cad15fcebdfcb38753488dba7ddc4134f3c01481c7bff4f7c621a84243b1f37d9616961d7faa598c2a6f1d482deb8cc8de875e7e31ab9dd6e9a9a9a78e5955700d0e8f5a8650a7af51dce6f9f1e845a2ee3ec81b52c5ff21e9306bf70d9fef6bfa0baba1a994c46686828adadad34343490909040765616de2a68343bd0f806111b1586c562212f2faf43085797d0ecd6e1ad5560ac2947ae54d26687b0d82442fd3488ae764a8a8a696d77e11d1842547828eed6326aac06e282448a4b8ad107c6e2af56d2505b8b6f4c3c950579e8e56e1adb9ca87d0289890aefea1fd70b87c3d1a53ffa3a41fedd6ef71552bc32572d90544a0d4ea1c35bfdf0e1c324252511620820c4d0610adfa8d1e3ea36da3b7dea040ea79bd8defde89b128fe87672e4c811468f1e4d527c0ce12181a8553d83846fcface3d7bfe845bc6f3cf6775fc466aa856e0269f4c01400da6a4d2057e0066a4d362a9a1ddc3f281e59f36dd4ad7c1d98c99eec7a7aa7a49192924c716e0a6772f60069f8f9f9e1769a385dd644afc1a984879d0fced69e9f8fa2a909854281f0c517d0d00073e7c28409489284ebf8711ccf3d87b87f3f4a970b775e1ed686067c62631935a43fbbb67c7651bde5e6e6b063c74e4263931934a82f4a85405d6b3ba302fd3104a9692e5c8ea5be17705e200d4c4b4125ebd9d82a951e9c2d6cddb683daf25c22d306a35028692e3bcbdaad054c9b349e6579bb2fca3f3e321808c6edb2a355e9700a6604999a001f399b376fa2aa241b8b3290a0c868e4723906830197ad92ed596d4c7cb02f9a6ed6ec6d6d36b66e3acaf0070691b1c744dfa12308962b292a2ac2e572111a1a4a5b9b999d3bb623d7f8d26fc860e2420ce8bd7c292d3e4be6a96314141491947ed3e5badaff8c4f3ef904ad56cb4f7ffa5332333359b16205fffdef7f79f2a9a7183a641032b79542a396477ff1335474841e29cd3ac8da351bf14d9b8ab7bb89a58bdf66d2a409d45416e39d3c83e71f9e4ae9812ff8f78643e8d4326c327f662f78108369237fff329a57ee55f1da8b8f63b8eb1566451af878c97b3cf0cfd779e69967e89b9a824ae6a2c8a8e2a1071f62f4c0b8eb522f9d28954adc6ef725ed902ee54a725d9d6b3fdb96c5b4d9777515aa3b2d6527f8f8939d4c3eb7cffcc4e9771019138bd958c99a15cbd973a8c393fc4a4ab0269744a0528e4ce987245a41b25f748dc3dcc8d6b59fa00f4f2636211ebb0436097c1572e4ca40246747c812934b422797a192ab10e45e482e53571ae6b2022aeb5a494e1a844f377f36775b1b82d58a50580867cec0ba75505c0ce7f444e28e1d88c78e81cb851c705b2cb8ed1797b19361a36f266d403a368b911d1b56f2d9b6b300ccba7504eb572ce5f5775672363fbbe359bf069224e176bb693335804c85db6e2463f71e7c7ba5d32b2ee262cffc6ed465efe7cb9d67b86dcedd5dc744b71baba515bbd58e4c7e5e1756777c2f0daa70d2c2237a4443704a70d668a3a9a18de6f263bcfbee7a5acdd6aea1bc4aad61d6fcfb70bb9d54e7ede7edc5eb68305aba95dd89d9d4804c797927ebef1ab952cdc0e90b78e6b9df13a832d35051004051d629567cbc918001d3993b75246aa51c43527fe6fdec37fc74d10272f775446f58b7763b03c7dfc1ef9f7e9c508d8db3478ee213331ea16417674f379018164c41511b65b539b4680611ab91235728e937652ecf3cfb7b227d9cd496645fcf2a00aecf8697573d42ba69c1834c181c0fc0f0e1c3019044370d85c759fceec7848cba833b6e4e0660e284b12864026e5b0bff79fd0db28eed63f2a8246ebae9f25fc628ad9cb27607beaa6604b93782bc67c7b5b719c958f7217babb5fc64d19d4406e9b0560978cba1d6e6446b2943ae8d06204223c76877d1ee68c7ed3021d7469c2bb38bec82525a051f060d8ced593906034e402c2b436630c082059094049595a056a3b8fb6ec8cc44fafc73448703fcfc505c2682c1f021831931743082dbc6e76b56b267d717cc9bda8f1133ef2328ad8c366b03993995c89457de8e589244c22322b867e14f68ad1fcec2875fc27c5b1cf9c7f670b0ee2807367584e77d6bc52ae6dc3d1bff733a29d1eda4266b1f6f2cfd824133eee19641e11d5f39b99cdb6ebf03fbb811bcf0e23fa92c380bfda2105ded6c3f944f4c9f2442437b4643500a303c2e9cbbe6ce234caa61c1432f606fbf83c4c4c473659478e8fefbd02804cc0d853cf4cbbf636e9e48b0c18bd4be7d49ebdb97d4a4485e7e6723dc37f68acf7cad91036e51c22dba713b5acf3f975c6040981eb92a00994209920d00d1da4275431b7d0302502b3bec73e2033484ea5594794522b93b3e7235ed2efafb6b506b7d507ae9713b4de8b5c318e85bc5bf72d3989cf8337c0f9ea2b6a582909b9f472e08c8659d79fa235368e06b7e94fe97742ef9ff20ec90c2d44e1aaa2ad0c7c551515181c160a0ada19cbffffd15da4306322a3a80c6ca72fc1213a9aeada5a5a909476b2d26a389c4c137e376bba9a8a820363696aaaa2a4a4a4a686e6ee6f8f1e3848585111e1ece94e189acfbf200ad860a7cc212f10e0aeb5186ed9f2ce68d0d39dcffcb07919a6bb11abc080ff2263e44cfe75bf613deb09dc4111d3e35e306c7f1e6910af6eede4745511171431601e0686ba220731fa1bd6713ebdb7385ccab572faa6262709494a0183d1aeeb907cacae08517a0572f648f3f8ef2b7bf453c7386f69a1a64fdfaa10d0ac266b3919b9b4b75753500999999f4e9d38786262375753548b656ca8a0b098d1905804ce58ba8d460ca2e22282a81a0d878dadbdb696a6a222a2a8ac2c242b2b3b3311a8d1c3f7e9cf8f878944a1b99f975e8e402c692fd0445a4a28f4ce3e13fbdc94f9c22f5f5f534353531f7b6e9782b649496961211114155ce61fefce21b040f9d44ac9f82faaa4ac2c37c395b58896873623396e072cbf135748440315765515863226dd26cfccee9341a1a1a90c964e8bd544c1c1ecfc113678873e5e01d148742a9ee70a43ee75c9b5b5080dce5a0a9f4285e7e11a8d41aeaeaca28ad6a41a780bcac9344c40dbcda6ef8ade815e4cdaefc2af61e3946d6c12fba8e0b82702ea679cf1166fcc031fc6cce38dedbb012bdfa1e9ca288ec5ce890eed74eed17cbcea3d9a86c75981a9b89ee3b0db54e49cc200d27379d64f653cf31e1ec676c3c58cbcf7f1d71d93caf27d7c30e49fef4d34fbfd0f947434303a228121a1afa953754575763b3d9c83c7d9ad6d656faf6ed4b464606818181349b6d1cce2ac45fafa0a6b4c3437dc080019c3c72843d193bc92bae2061e844a64d1d8d4274b173e74e5253533978f0209b376f26202080c2c242743a1d09090904262652736c27997572a6dd3e99b484b01ec1ef3fdf79088db796f6ba0af2f3f348484820242a06df003d398776532dc570ff3db7e0e7a5c1372e11554b05474fe711d27b0c774e19884a26e068b7535bd14cdaad9388d2f7144832b51aa720603a72041f970bb9c381f0c927083939086565088d8d90994973410165a9a9443ffc303ed1d1984c26de7fff7d9c4e2776bb9deaea6a860e1d4a515e2e3bb66e21272f1f9fb821dc3d771ade2a39369b95756b5653dae462faedb731a05718c6a6268e1f3f4e7272321b376ee4d4a953f8fafa7679a2ebd4f0c5ba8d649ecda2bc59c5bc87e613131280d64b875eaf47a3d1e07038183d6a14324160dbb66d1d9eec65b514d4d4a39339292f2e441445927bc57170d70e0e1e3a4251a58941b74ce3a651fdd1c865b4d49ab0ca750cb8793881da8eefd7993367b0582c44c4c4e01d16c1a9ed5f72aab49de9f3e792121b4a415e1e8d8d8d040707b369fd3a4e9c3c4159a39be9f3e7d1273e949ab25cb67eb995ec9c2c1cfa78ee796016feda6fbfc9e037253cd487d6aa524e659742f0105213c2484b4bc364323160c000b45a2d66b399f8f878fcfdfd419031f5ce05f4f2b572bcb895f8d870fc7dbc494e4ec6ed7663b7db494f4f273a2d89c6dce39cc8a92269e838264d48c74ba9044d002a8d37136f19466c989b365d22336f1e8e2080c964a27ffffee8743acc6633d1d1d15d410faf17369badc776dadd43da76d25da7d4395acacfcfef1a255f0a87c341656525090909179d134a4b4b25bbdd8ec160e80a99e1f1f63f8fc364a2f4a597e0d34f89f2f747ab5275849e0490c968349bc95328087ee619e26fbb0df935d8bdd38387ef039d1b457e5d5b24b95cfeedbdfdad562b3a9dee9a0558bad150fafa12f5ab5f511d16c6d90d1bd0592c78a9d5b84411a3d58a233191c8071e2072c2048f30f27043a15028baec902e156ee47f6287141414844c26f3c4f1f90a04990c4d6828318b16113a73262d3939b4555420a854c42426a28f8b431b1888ec1a6c92e7c1c3f789eb6287742d6c076e74044140a1d5a2888a42171575bd8be3c1c37742a71d52e74a1bd04318414f01a5bc063304456b6b2b369b0d83c170e5ab7fe488763bf6f272ec3535082a15eae86854c1c19ed191871b924e2174a9806c9d5ccbe06c008af6f6768f0ee93248928464b3d176e810a6d5aba1be1eb9568b284958ed76e47dfa1076efbd78c5c77b622379b8a1e86e87f47582fc5f0b434a4560602072b9dca343fa0a44ab95e64f3ec1f2d147f80d1b86f6ce3b91f9f874581a1b8d983232287ee105229f7802bf7efd3c42c9c30dc337b543525c839982e26a13d977e414fd070f26cce7bc33a5c9d8c89143876877b85069fde837742851fe5e1c3e7c98caca4a140a0586c868faf5efdfc345a3b8309fb3674e230a0a66cc3cbf8ba9b5ad91a3070e6274a8e8dd7f008991c13dec904e1e3d4859652d28544424f4a16f520c1a85485d4511a7cfe4e050053062e41002f55a24d146eea91314563511109ec0e081bd51cb0476edda456b6b2b92e4c46a15993869228186f396d26dfbf7d3b66409a177de896aec5884b6b6ae5d4794c1c184cc9a8572dd3a4a5e7a89c43fff199fc444da2d160eeccba0bea18961234675d95b646666929393835aad461f6060e0f091042865588c651c3c748676494dafd4be24c684a1e8f69c674e1ea3a0a080c090706ebeb963b760736b2dfbf61ec5ee12415092d86f08bda303919f73ed2839b693a22607b74ceeb9fc5a5355c1a99327b1bb44b47e21a40f1d4c80dac9f1a3c7a9ae332209320ce189f4ef93844cb491919181dbed4612ed48828e695327a2569fb7d7b25b5ac9397382f23a138252c32de3c7a1d576f40987c3c1e79f7fdee5e3143f68082911c1d4551671e2640e22a0d4f8d177d01062827a6ec1fd7dc3683472f6ecd92b7a17dc48389dceafd419fdcf76aeedf472fea61af29ca3db58fed1f61ec78ccd6d9cce2da6b1a989dc135b58fac1260056ac58c1912347301a8db4b6b5e1ba6064575e59cda9b379bcfccf7ff6cc63eb4a3ed99b4de9990c3e5cb3835a634f3fb193392554d737505b9ac907efada0b0a41abbb196ed6b3f64776619d97b3f61d5f65c009a32f7b062fd16f20bf2d9fed92af69eedf0716b6969c168345276740b6fbeb99aca3a4b57faa2dd4ef38a15f80705a18a8f47888d859010a8af079b0da2a3112222f03518f02a2da576cb1644978b769b8d539979bcf7c10a0e1d3ad495dee6cd9bd9b2650b46a39196d6565ce71a75c78a656c3d91475df959d66f3b44595d7bcf7a282861dfc163bcfdf6db5dc75c4e2bb58d4d188d466a4a4ff3e6dbcbb1da3aeac7d694cd9bcb3fe3a57fbe7a51bb55d519c92a2ca3a1b19ee37b36b26aed5e909c34359b686c6aa2a1ba98d51fade0c4e91c4451c4643261341a29dcb59237976760b39fb7c4753bad9c3df4196bb79fa0b1a989da8a62dcdd2c75ad562bafbefa2a46a311a3d148bbdd812889b45bcdd49d2b7bf6c90cdefb60dd45e5fcbe515959c93befbc73bd8bf19d723943c84e2e0cd8f66d51b4b7b7e3e5e5f58d75482387f6e5f5f7b6c3cf6ec566b3a1542a898888e0a1458bf0d76b29cdcee0a91757c3af66013076ec58c68cb909a54a8552d1f10076bb1d8d4643fa90a124f749e3e8d1233df2d8fae57ea63cfe0ae3021b79f48faba9af19458421a6ebfc6db7df8ebfb717627b0d8f3df9371a6babf0b62bc9ceaf65ee9f7f8fa161178fbfb2955fce18c8be9d47f0894ee2bebba7b27ded728e64ece7967e773063c60c24c9cde625260678a9098c0cea4adf565a0af9f968a3a2100e1f86c040e8d70f468c40f2f2425228702e5b866bf972b49595b49c3881dd68c42fc0c0030f2dc2dcd67651bd0d193284d9b3672357a8509f8bedf4e5be2c7ef2a797498fd6f2ccdf5651515c4642689fae7b264f994a7c4212affef3a5ae63be01d1cc9bbf0097dd4663e16e76fc2303b7abc3276bc3ca2f09ee37065569c945f9a7f44e21293919bd46ce918cf5bcbb7a3bc282b14c98782b0e9b95b68602f27297636a6ac5c7c787850b1722894e96161c61cc9c6928b5e777af6d6f31b36bc356fa3ff03c93124350c844d41a2f9c4e675707f5f3f363f6ecd908820c955a8d42262321692051b169b81d0e8eed5cc907dbaabf49d7bb666cd8b001954ac5d4a953c9cece66d7ae5d3cf2c823fce9f9e7480e5471b2b405df84612c9c732bd0f1f239ed6d1cf86c05f9249214ace2c0e71fe317184449a393b177ff8ce983a3b0998a786fc98714d6b71337603477dd31197bdec76c2c19c4a2092e162f7e8bd89b1f6270a02fbb376f62d04f1e66f53fff46bc2f9c2a6fc53b269df977df4e7cc8f51d355ece0ee9429d52f763df0659606020dedededf38b1ac4307894bef980eac5dbb96eaea6a346a2501de5a5cd666ceecde41cca08900048584f2e9271ff3dcb3cff2dfe56b28ad3763b3d958b1620500de3a2f7c741a64b29e6538d3646750a81e8da117a2bd11d16eea713ec84f8f4c725274e200a883f0098ac66417313a249202b4e84206616f3a0340b6d14e94af063fbd2f6a9f08ecc69cae74eca6224e959631a0575f42bdbb4d472a2a50582c08a5a5b07b37bcfa2ae4e6426c2cf8fbe37cff7d1cafbe8a989d8da2b515777535f6e666140a39017ede282fd809d73f2090ddbb3378ee0f7fe09537979153d50c405aa48143a772c8c93c49e5d9cf71b5d7f7b8cfcf478f97a6e792aa4c90539897c7ef9ffa2d8f3fff168326df8252297036e373cae506460def874a71f14746af55e3abd3606bae23e7c811e2874c411064882e27affcf31f3cf1f49f69560793d43fa5eb1e73d5010ed6c2a4d43834ddd26c77bad97a248b93abdfe40fcffe8115db4f6373ba3976ec18070e1c4026932157aa78e18fcff1dcf37f66f5b6c358ec2ee43239193b77f2fb277fc51b2bf73076d6d48bcaf95d505a5a4a454505d0e1ba91959505c091939954858ee4e19ffe7ff6ce3c3e8beaecfbdf99b9f72577f610b20708093b610701117041014510c1bab6b5add5c7b74fdbb7cf6bf7a74fadb55a5bad6b55140454f61dc20e26ec842d21210949c8bee7ded79979ffb8212180d6ad6afbf0fb7cf211cfdc73ce99333367ae739ddff5bbe6d25892cfb9d3e17297bd998d4b5f65574588c9a307d3ded6cace1a3f4366dcc7ed3765b27a5158af2aef8db768b2e6f0d0c23b683b93cfee9da7102cb11cdeba95bac2b334947dc4aad23aced6565250d44c6fbdc8d113a7a98a19c50f1e9d4767f551ce1c3ff1b58cc9e5f0fbfd3d26a06b39b0bff4259b46a3f95c335b852e97c71eb91180850b179272919fe3b73791f7fe9becaa8be4f1ef8627a4277ef4135e79fd4d7ef7ab1fe1283bcc86d5bb301a8d7cfbdbdffec4360c82804f514109200812083d39538a1ca4e2d86e16ad39c0c4593319d43f014900498080a282ea4310c3fe0cbd2810525514550135842084bff4aaaa5075a682e64e2dd9a3737bf86ed0e9907d3e2829412d2b0befb8190ca88100280a625212525414a2202000aa560b9fc0eb9a7fdffdbcf9ce7b3cf3875f932435f1ce1b2b01b8efc78fa1ad3dcafafd67680ec583f0e96470070d1ac44b2fbfce8bbf7f82431bb6e2a82d62f3aebd3436da293ab887fafa7a0e1c2fc423f77c50bced35ac5df226a542363f7ce886f0f8e8f5fcf297bfe6a5177e8fc5d5484961f1c5f19139baf530e6f4c1f44e49ec2169220096d8646effdecff9efff730f5bde5d8abdc3c1b871e3b8f1c61b319b2dbcb578397f7afe4ffce72337b3f2ad2534d68705eb6ebbed365e7af52d1e5f3899edefafff54d7fbcf429871dcedb2306825e68ced4f7affd1e8f55a02de709fcf1d3bc0fa03179836f32efaa5c4210a0263faf662dcc03ea4f59f8cbb2d2c27b3b3bc8929c333c919321a5b422cf6a63344448f203d709025a73df4cb99857ab892c6a26de8b2678765713422778dc9223d6b1426939980bbe16b198bcba1d3e97aecaa5dcb1aba7c32fa3276ea3fb70fe97b8fcca29759dfa32ce06c63c7eaa56c2ff5f3e077bf454a64d8e4341a34489284566fc262312007ddd7aaf22a8c4e32b2afbc1d47ed094463021a53cf648c0d45f92c7a3f8f0137cf63e6e470eef958938678bdc0c93a27ed65fb30268d0160446f23658d2e5ada5b71355760ec9d0b80127471aefa149ab81c8626f734918de9e9782d1664972bac14f9e31f877d487fff3be4e5a1993103fd534fa18f8f27288aa8a9a9183e21fdb15e27a1d34a481a0311361bb2df09802d7108dffbcf9ff3e8ac116467f5411f9dfc0fc72614f2e20cc82088586c5108b20f416363dcc891a42768696e6ec6e7f3d1617770f974e46baf61ed927739e58ce1d1efcc235223a2287e9c8100b20a7a8319835e420d85fd5141670d872e3491d3af1f09d69e13a5512b30233b129bc580c16a43108270796b02988c1a044183d5168d063faa12c017f4e20929208844d82251029fee79f8b2112909b4f942387c5e1c170e74775b10d0890257ca85f51930940939b16cddbc85c64e37aaaaa2e98ad21781b0d5d0cfaaa5a4c185c7de82bfb313c9d00ba3416260bf202b4ed5a2642c6040c7714eef3bc9e0e97d3eb1cdaf13972c9eaf9c87f4797c488b5f41dacaaf00002000494441547e91e4e4641e7ae82156ac58c1f8f1e3696ba8e1f7afbd4f446a0ecb5f7d812399197cef7bdf63fb962d1c2cc8c7eb7142440af3a64dc1ebf5b262c50a1e78e001366cd8c0c68d1b292b2be3f1c71fe7d65b6fe58e3beee0a6f97378f1bdbf701c999cd1b7919cdc7342faebebef9277b21e97464be9fef57ce73bdf21352585dc51fdf9e0f95f21a93273eefd0f0046ccb88dc3ef7cc89f9e3e8929ba37f31f0a4f48de4e0795a7ce93337b0166a9e718e87bf7469c3001475515b111619d68de7e3bfc171f8f2049887a3d7eab95769309f3d8b1e82322686e6ee699679ee1c8912358ad564a4a4a78eaa9a7387aec18dbb66ec1ef7511d458b96d6ed84274bbddfced6f7fa5a1a686ecb133c8e997485d5d1d050505cc9b378f575f7d95fcfc7cce9c39c3e38f3fce238f3c42722f1d2fbff601fe801f9fd7cd4df7dc832d29931b33b2b811686c6ca4a8a8881953c2bb72efbdf71eb366cde250c1619e5fb29eb481c378e3b93f3072442e73eebc8955ef7d40e9b90b04031ef489031834222c09d25c5e852ba065d4b061175f18d8bf7f3f7abd9e11c3063162fa4dbcfbecaff17bec0cba6906666b04870f1fc6eff73372e4485e7ef965da5b9b71bb1d0cbae936a2e3a2387b623f1faeda8daa0609a822b31e78e0333d7b5f16268eeacfdf97aee4bf7f5b8fc717c2a00f7f600d0643d70ba6d3e990240951144948cf66de7d0fb1f18345bcb57c3399f11a7417c5fa0441407ff1fcbbbe359bbf2e5fcb2ff728186232b865e268340603714386632869242d379d9c3a132f6e8be0c9ccf073a5d7ebaf6af3ebc6e52cedaf8a8724b4b4b4a8977848c5c5c59f3ada7fd8b061444646121717475b5b1b56ab9550284443632392a44114c2839c9090406747074e97135505bd3982e8481b92a0d2d6d6465c5c1c1d1d1d747676765d5864642451515184823e5a9b5b082822b6a868ac66438f25435d6d2dfe908ce6e28b121f1f8f5eafc3eb76d2d161471175c4c5c762d06a5055197b7b2b4e4f009dd14a6c8c0d49109043413adbdad045c561d55dfd10388a8bb9f0c41324353612919c8ce47281db0d8200b1b1f802012e3437d376fbed0c7bea298cd1d1048341eaebebbbd2c85c72f8bbdd6e3a3b3b515505adc142744c347a494096659a9a1a09c910191d8dd56420180ce2743a898989a1a9a9098fc7d3353ef1f1f1e8b422cdcdadc88a02a286a8d8382c7a6dd783130a85686969213131ac21d5d2d2427474346e978b96b676341a0901309bcd4447db686b6dc3e3f5832060b24612196141230a043c6eec6e2f96a8688c17fd470e87035114319bcd04fd1eda5adb092810111d8bcd6cc0e376a3280a168b85a6a62682c10008121151314498f5f83c4edadaeca8a8485a2331713118345ffd0ba804bdb4b5b5e30baa085a233a51263e3e9e868606e2e2e2d06834b4b6b662341ad16834747474d0ab572f7cce763a7d603468090502c4c4c4100c06696b6ba357af5ea8b29fd69656bc0105832582e8c8082401bc1e3bad4e3f7171f1889e16da9c328989890842f8031213138356aba5adad2d4c0df99ad53402814057b2c84f23f2afd3e9f0fbfd5f28da5fe8e8e8e89ad63ecb84f4bf457e4491653a8e1fe7c2b3cf62adae264292d0eb74c88a822710a045a3c1377122c37ff6330c51ff58e9f13aaee35f054ea7b3cb52fb341692288a5f5c7ec4e974e2f7fbc30254d771154449223a3717cdef7f4fd3ce9d349797a37476a24a124a4c0ca62143c8b9e596eb93d175fcdbe1cac9e8d2bfffa93c24b7db8dd168bc1ecbf6091024095b5616d63e7df0b7b7e3b7db11341a0c5151e8acd6ebe122d7f16f094992be721ed2f558b64f80cbedc7ee0c20f798fdf5608e0701ec5e01bcdd3b443a8d40548401bdee7af4ff75fcebc3eff7a3d1683eb51ed29722f2ff6504c4fdbb62c38e32761d6d44ba94455600151505214cc2110564554015401504744290c7ee1ac8b0fe1faf497e1dd7f1af02bd5edf23e21fbe023da4eb3ea48f478b3d4046766ffaf68d05554555411454a22d5a5c7e05874fc662d2a2d5883438821c3d5e85cbf7c5bf12d7711ddf045ce2267e953c24d1e572f179d9daffeed068445caa48a347a5d6ad50e3927186a06f6f0b7abd845f51498f37921863a0cd2b135485abc25faee33afe5521cbf2c73ab12fe1f209e94bd343fa3c13d2732fbecef8dbe670f365e97ecf979fe3f5575fc51394d118acdc34e741668ecde2e9a79fa6b4b494e8e86832468c62eebcf9f4be2c6ff9ce6d5b58b5e2039adb1dac5cbdbaabbcaee4235e79f3433a031ac6de7a37774d1d8be5b2f3de7aed6f149e2945d468481a7c030fccb9957893c2811d6b58b3ed10415d24f3bffb1813fa27e1efbcc0b225ef5158de4442e6501e78f03e5222f53cfbecb334343410743672aec6c75ffefa67066487af499204dadc2aeeb60013324d68048126bb1f111051c98c35609060ddf116ced47990033282104e3e595b7a82356b3652d9d882de1ac3af7ef1ff3871f4102b57ad21a882253685bbee7d80d1fde2bbae273f3f9f952b57a22821daebcbc91c7e17bf7dea51ec75a779e5b5c5d4d965068e9bcabcd937136bea368fd7ad7c9f9d7bf3419488eb3b9cf977cf26c12cf0ecb3cfe2f17808745ea0d61ec99b6f3c475c6cd812f679bdfce5b967283878909977cee5bbdf0de7a93b75f2388bde788da327cfb0e89dc55de96ccaf6afe59d35bb700455f4d1fd5878df3de466752f4dcf1fdcc2e2955b69f72b686de9ccbbf75e46e72450796a0faf2e5a8d172353eeba8fdb6f188a51fbf593fe000ee4efe7fdf7dea5acaa9625ef2ded524df574d6b369c5871c28aac4eb0ff2831f3e4e9fde31ac79eb2f1cac72a22a0afd6f98c7f7ef99844e2b51f7d1dff8d03996813a17a74f1ce3c73ffef1d77c65615cee88fe3cbfd1ebf5ff9087f465eb21494f3df5d46f2e75e6b3e4651b981862c9d2fddc396b4ad73159d4939e338c7977cd22d366e795d73633f7aee9ac58b1823973e6f0c8238f3072d0406cba9e13a0a43793337c0cdbb66ce2befbeeeb2adff0fc6f90a63dc6772745b164d551b2fa0f2021ba3b33ac6a8ee7aed977306564066b96aea077523a96909db51fae66ccb77fc194840bbcb6be95d9530753b8f22df6db2379f4a17b683fb78f13f5518c1ddc9bdcdc5c6eba690a89a116ca3c714c9a7a13311743244e94b650ee92680d4a0cec6560749a99166790cc7803bd6c7ae26d7a769f6a65dbe106ec761f1a39c00d036389121dac5dfe06fa91f7f2c4c3f319373c074b441421ad9511e32630fbd629041a4f91b7ab84e9378deeba9edebd7b875511c68da6e5d85e84d10f73434e0cbb5ef93d8dfd67f3e4ec01ecd8918f644ea75f6af7123ba0b571cbadb770f3c4211cdeb919a74b62f4a8418c1b378ea9536fc2d65244a56904d3260dc7a4bff8d0080211f1a928820697a3931b6e08c7b4095a03fd068da2203f9f9ba6dc485c5c58fde0f5e7ff4ccaf47bf8de82db283ab20baf5fc3b021fdbbfaf0cecbaf61c99dc2630fcda5a6f8231a9afd0c1f98cefa97fe48ccdca7787094c85babce3062e84022addd1a5a5f27449d91812326b03d6f2bb367cdc46c0e870e1dfef0793e9207f08b271f65cac45124f64aa0bea68ef7566ce27bbf7b8ed9636378e5d595ccba7d2a5a2dac7ae97dd2478f26686fe36c7131d3a6dd44d5d942ea9d106b95385f7a9a93a78b696877131917875e123878a00077cb054e1597d3ec0c618b8c4427ca34d79671ecd809eada839c2f2b2139b93765656578bd5e6c361b4d4d4d545555111f1f8fdfd3cea9a347292eabc41592b0d9ac383a3b3856b08fd6a67aaa9d5ae222f5b4d55770fcf8092a6a9a3046c560d16b397bf62c756567a8ac6dc4a1887434d6e10f19b09ab5b436d753595d8fd16c4223893df2ae5dc943ba328eed8be665139d4e27adadad9f39964df607104c61dafbeeddbb6969692136d2c2d0ac542c66136a5046bc781c60d7ce1d2c5bf60187ce54e095c3d223dbb66d03202da537fd3392d06a7bceb07bcb3ab8353785c49cf1849c75041c4d3d8e8fc849272632020d02aaa4074947932340bd33c4f8ec5e240fbf958e737b012828ef243b258ab4b454a292b2e8ac08c72e198d46f41a2f47cf37d26f705f7ac7774f78a2282248127a51a4cd25b3bab093fde75ca082c7272387142c5a117f9b074fbd1d42328228d0d6e1e1a3bd27f1d71d61f987eba80b9a4010c94c8aa35f4a2f8c7a034a4801634f62a946a3c1643221fb2a39d26466ce2d614b6d47711b370de94d5ce610b41a0177d3b91ee70de99742626c147a49838a04fa70e883c9644227b4b3eb6c27374cccc26ad6f6686bd8c07ec446f6ec437c4c1443b233301b7bc6294e9b369a8a823cde7e6739ada14832060cc4ed7693979707c0e4c9c3693a55c03befbe47b55d47d6f06104422a072b1ddc313295a44137e26d2e25e8e9a9d8f07522a9573c03fba562d0f574c6aed97492487f05ef7ff02185171c84342662622319d2378a358b5ee7f5459bc9b9612a925643c051cc61319db4c87834a280aaf839fdd14696ae584f657d3b75a70eb164c972f61f3ec2a60f17b1616f1900fff3fb3fb06ccb5e8a0af7f3dadfdfa1a8b406775b336bdf7a8575fb8f5398bf8e5ffdfc67f87c3e56ac58c1be7dfb00282c2c64f1e2b0aac0a9cdcbd95670843385f9bcb1682595175a292d2de5c9a77ecbaec327a96ab6636faa67cda2d7d8b0ef18f95bdfe3ed0ff301f8e0830ff8ddcbef50587c8ec68e4ef256af60ebdec3f8fc4e0eedf8800fb716215c1136029fcc43fa52e4473eaf0f69f5aef3dcb530ac75141313d315d303d0517e90252b3e62f682f0f159f3163076c20d44995536bfbf989dfb4a114591d8d8d86bd67d099d2195288d84a88940557ca006aefa8ddfd1c4c6151f624b1b489f7e190454f0ab60d54848da68d450f805b0cb2a26494427e91024236ac8de5587bdb29cba4617fdb273b15c26af214a02b146898746d918956aa4b42188c7078aa272f45c27874a3b9830208a7139511090d18ae1af885f8512878cac8dc21228e3efafadc1ebedeefbf9235bd979b4819977df7ecdeb3e9fb701fde05be8777159d61e5289d44a889219505115cf55e7847c2ef2b7aca24d8e66d4b8915de5cd270ed3aa4691939289fe0bf0a564a7039f1441624234a2df8dcfab204952d73d945d2e3c82995ef17168822e3c6e05e5e2b8c76825444d64b8dfea174bb5fc55e0bc57a6d96b24dae061ddb20f283e5b831a0ae173f931c6f4a6970d5c761faa0a8d870ed3ab5f2c96f8b0c57a6c4f1eef6f39c2e85b1770cbd81c0e1d2d46179dca0f1f7f8229e38770604b58d940a3d331feb6bb79ecc92789d17b69afafa0a9a59313e5ed3cf61f4ff2f0fce944fc034bf29da51b385352415d7d1d857b37d0d15c0b40af3efd99f7d0775970e300eced9d9c3edfc1f7ffe3491efdf6428ee6752b2be48c9dcc830fdcc7b461039834388eb2aa72ca2b5b3973e434a366dcd815cef3551223c5d8d8586c36db672646ce79ec71a68f480560c89021d86c369450900b2777f3fccb1f3268e67dcc181736db268e1fc3ec59b39979e71c12e32c949f3a8056ab65c488119fd8465f8b8652bb8f80eb02a226124163ed71dcd3d1c0c6656f73c29dc8238fcc2531da8855236093a0c6e5c76f2f45630df721c3aca1d91bc0e57311f2b5a03187ad0f450e70baac02a72e9a51c3537b7640800883445d5b00bb2b44ac49c2a895f0f8659a1c326b0fb5d1620f71c7c4649213cda817a5308d92c0f49c34ee9a3593bbe6df4f75f17ee4500039e0a574ff2a5e5971943b1ffd0163b3ae9e9043be2696edabe1ae99b95d65fdad1acaed3e42de665415247ddc15e7b8d8bfee5d369c09f0c80f1fa67f52d83255426e761d2f2336238dccf42f965566edde334c9d36857be62f203eda40edb9e3180c067273c3fddc52709631e3c672cffcf96424c7535574108d00e9260d67ed3e02aef348fa7804c9f885faf1552037dec2dc3b6e66d65df390429db43554d2d4eea4b4c9c3c3f7dfcb7ddffe3e55c77722075cec2ef6911d15432f6bd8ba374a41daec1eb45a11047087140c7a0d069d16ad29122518fe106a44819c381392d686286940f51352548280cd20a135c72248e13ab502f86595502848d0dbdad54f8fa8e7ee050b79f407ffc9dfdf7891a183b20048b2ea4889085bb84145252408441834682db128b2b3ebfc81f166cc5a0904819cc9b7a1d6957378efdb5469c632352beaebd143d26ab59fcbd412da6a283f1bd6cc292929c1e974d25055ca6f7ef7676a8528a2251f6545a701a8387f9e7dfbf7b16b471e4d2d9d24660e24140a71e64c583fa6bcbc9c9d3b77d2dcdcccf6eddb292f2f07e0d6c98358bb661b9b57ad262a358bc8849ebeadf54b5ee1a575a718342493fab327b1777692981049bfe44856afdec2b6356b1934391c5373e3b81c2e5454b179e3162acb2f90332e1c051f70b5517e229fe421334836f734dd55c0a297687683dd2b3339cb48ac59e2fd83ed94340519de3792ca260f2bf7d6e3f4a9200aa8404c9485712333c8dbb59b9d5bd79290311c51d2527468273ffeed1b983332a1bd86aaf31500141515e1f787e53e6a0faea1d3368ce149095dfdb863da7076edc867ebfaf5c89299defd06e0f178387b362c3297bf7109bf7d633b5943fbd35e514473632300ce860a2aab6bc91a3091e88b9b01f5f5f5d4d4d4100c06d9bf7f3f67ce9ca1acac8c9d3b77e2f17868686860fbf6ed343636525050406161210063b253395278929ddbb7d26e771393d807bfdfdf256a36a25f1267ce9e65c78e3c1a9a5a894fce46afd330755c16cb97ad67e38a1524660fc71cf9f1f22c5f35aaababd9be7d3b4d4d4decd9b3a76b3c67df9ccb91c24276efd84248b4608b4d22d26ca09745c7866d3bd9b17935f16943087454d02a28585286a2bdf80e654f98c913f3c6b169c5323e3a59c1c87ec9b43636b26ed3164e1e29206b54587d5210848b81e2ddef5e7ca499ac38134b566f61c7a6d5b89d0e0086a7c4527afe3c5b76eca4f0e0ceaedfcf9d348423a7caa8a9a9e17c69115e4f58a154ecaa1b7a455be8136564f9da2de4ad594ae6b06e313ce9b234d95a6b2a0bc75859bd663763e6df824912d1ebf55fb91e92f4f8e38fffc6e974a2d7eb696b6bfbd44eedfaba3a6459a67ffffe14161612131383c72f53ddd24972bc0d677b2ba150880103065076b698a2d3a7686e7390336e3ad3a68c44a3ca1c3f7e9cacac2c4e9f3e4d616121696969b4b6b6121515455a5a1ad1997d70579ea6ce17c1ad33a6d23fada7c8ffc1531524f48e035727cdcd4d646666129b9844747c348de54578cc592c98339108a31e6b4a3a56b993ca0bcda40c9ec48cc903d08a02417f08875d66f0f449245e3121159e6b416b341265d1911625116bd560d68bd8cc5a12a37564f532d22b52c78682263aed7e2c5689f18362494b8ac31c1b4fd5c9e3d43af4cc5a703769f1919caf69c2276a88d60bb4b7b6603299484f4fe7c89123a4a6a6a2d3e968ad6a276e442e391989e82ecaa144f5c9426e38c7f90e81b1936f62cca014fc5e0fc5c5c5f4eddb97e3c5d558626ce8022e5a9a9be9d5ab17f1f1f1f81c3e421a0b43268e22d618feda565757e372b988898961dbb66d288a82cd66a3bdbd9dc18307d3dadacadebd7b494a4ac2eff723491203060c20b37f2aedd51554373ae9973b89c993462029414e9e3c49bf7efd48eb978cbbb186caba0e52078f63eab471588d3aa2d333e8283d4eb31ccfac595348ef15dd43b1e1eb44595919050505a4a4a4e0743a31994cf4eddb97c88c2c5a4a4e5156ef21f7c6698ccecd21d266a657bc89cab3a53479cccc5e3817b9a6920bb5d58cb9753a31fa30a3393a3a86f1d36693647471c12e326ef248aca297caca1a22d28633e7ae49983522a15088418306613018906599cccc4c7aa7a510d72b82da92b378238672f2f811162e984f7a7a2f02edadd4b63888489bc0b00119f4eddb97e401fdf1d59ea3e4fc051c3ee89f9d83c56cc46c36939d1d56fc3458cdc4255aa92d2dc1212571cf7d3388b518916599f4f4741212c21f3e41101043c5ec3c9fc08f16dc8249af2510085cd358b9720977e9bf972ca82fe2d4168a8b8b5583c180cd66a3a4a4e47ab4ff65787bc3594cd1d1982d26fcbe202d2e1911b863b8959547ece497ba48b642d1b936fc4e2f7171023fbd379bd1fde3ff61ddd7f1af8f96ba3a3adadbc9183808ed3f817f367bf66c962e5dfa95bc67bb77efe2fdb75e2577c1cf78e896e1e835d2d713edff797948ff1b202b323e7f109351c6e957f106551cde10ab8f7470a62e803b2053da1044a395d0471ad1ea83a87c39cebdebf8e6232e2989b8a4a47f5afd2fbcf00246e357e3731b3c7808093f7f9ae4f4d42ecbfcebe02169be8cf8937f570cc9b471b8a40d7b47584c4c002c2a78ecd0c71afe0b7b9a74a8a8441b0df48ed27f72a5d7711d9f129999995f595bb1b1b157ed7a5f5ab27f9579d9342e970bbfdf4f6464e417aeecdf0d6306a7306670cad7dd8debb88eaf055746fac33f9f87a4713a9d3d3484afa31b278a1ac83fde80d72f8737432e0d91205cf6ffe1687f411088b369b9796c1a89f1111f5be7755cc7bf0a2e77587f1a3da42f03d77d489f8003271aa9772a2426da2e968423fe050164046400414415047c2185fcf266b2325cd727a4ebf8b7c0e5fea3af4c0fe9ba0fe9e3a120a08fb412911885acaaa80a98b402b9e9166adafdd476f8e8976841ab15395aeda6baa193ebe223d7f1ef029d4ef7d5eb21b95c2e028100369bed1ffffa326cdb7d8051374c2035aa3bf6abb5b9893dbb76e0f405d15b62183b790a99711676eddac5f9f3e7d1e974c467f461ccd8714469bbd7a52545a73972e800b2a0e5a1871fee2a773b1ad99bb78366bf81dcb163199099d4239163fe9e1d9455d620680da40fc865d4e0be18352a7515451c3c54884f1fcff49b279310614695bd9c38b09fa2aa66e2d27298343e17a324b07efdfa702610c58fcba330f7eebb4948083bf72449a0d5a3e06bf69364d3100c29b8bc60d488b87d410ca2409c59c3891a1767aa9d78024a17c7c6d3d9c2b143055436b4a133d99873e74ceaaacf73f0d011fcb28a2d3e95099326107f19f7a9b4b49443870ea1aa2aa1a087e4d401dc72f364827e3bfbb7e771a153217b682eb903fb76a524023875ec1027ce9c4511b5f4ee339031b983d02a01d6af5f4f201040957d0464030bee9d8bc512be5fc160801d5b375159758111a3c732664c387f5d6d4d35fbf7eca4b9cdceb7ee7fa02b02dedd50c68e7d87e9f0ca44f6eac3b8b1234988bc2cad76d379f6ec3f4c8bcb8f252e9d71e3c69018a5c3d15ec7eebc9d74aa56c64ebc817ec93db9645f27ce979fe340fe3edcbe10dfbaff014ca6f0d8e4e5e5d1d8d888aa04707b656ebb75061919615f62cbb963e4edc9e7d6bbefeb1e9bfa831ceae84d922e4853431d93264dba667b757575141717337dfaf44fd5bfb56bd73263c60c4a4a4a3871e204aaaa10f07be99f93cba48963d8bd7b37e3c68da3beb68603f97b717b83dc77ff035d41c257221008b074e9d2aeadfc88ac914ccded7fcd6c3b4057d69caf527e44743a9d5da4a6cf82e6b27cde7977738f32872740833d80c56ac5597b8437df5e078407b6a1a101abd58ac960e04aca466b878366bb8fb717bdd3a3bc78d362b69574a2b49e61f9ea5dd4b7fa7a1c3fdfe4406b34a30bb5b2f2bd659c2bafc5d75ac78e35ef53d4a6d259b28d255bc2ecdbe6e33bf820ef106eaf9ba3bb56b3ab309c8dd46c3663b55a51ea4fb366f57e1adbbb63ce2449c0158446a74c9f38033387449314ad43142035dac0d0342b175a3c6c3dda446da38b40207c0343be4e0eed59cd9e538d98ad1168551fa0d2d0e1c11100b351c3b96379ac5ab3bfc7f5e8743aac562b6683868addabd974a81d80aa5d1fb0ee682da2eb029b366ce64c95a3c779954d4e548d1ea3e865e7fa95141c2c461004ac562b56ab9540c547acd8781297b73b805a91156a9b3b3978ec24bb77efeebe876e1fcd9d3e16bfb78ca6a6ee60e695efbdc7c99a160c7a95bddbd772e0c0911e7d58bf620587ce55a1d38b1cdebf995dbb3e4209f8285cbf983d557e428dc758b6369f36c7d5f1885f173a1c6eda5d2116bdbb1897cbd5556e341ab15aadd056c1e6b53b38dfe00520e8ac65cbee8ff8d9ef5ea2a5a5a5ebf767567fc8d9ba7a8a4b4ad8b469d3c7b6575555c5eacbe475fe11162d5a442010e87a2e8c92cca9bcd5ec3e69efeaa720087438dcb439832c7a77094ea7f363eb0b04022c5ebcb8ebb9301b74887cfc7b7f6982f94a13455eca05f5592b1c3e6c007f5b5200ccc56eb7633299484e4ae4a1fb176231eaa92c8ae6bf9e5e0584e544060d1ac4f8f113309a2d98a5b063cce170101919c9889123e99f33803dbb77f46863d3b623ccfee58b8c8beee4f1fff72e6d0d0da4c6756f85ceba7d0616930ed955cf47079fa1b3a589fa808692f3ad3cf4875f636b4de5c9df6f86f923d9b3a79084ccbedc33f736f2d62ca570df5e6e1f398fa953a7a22a41d6359533e4e601c4a774c789899248008976a74a6953005481e23a2f13fa44901a634405761c6fa6aabc9da05f2636120451a0a3a98d7d5b3f22f707bf6454621466b311ad56c7b02183183e74303a4966fb7a3f79870e033775b597919141464606cef63a0a366e60dac2b0b4cb868d054c7ae0c7dc312082df3ff70e5567cf929b39b6ebbc29936fc0a8d742b093f3157fa1beba0ce38d43b8fdf6db51151f6f9dd8c70d73a762b6755bb35a9d9e7be7cf4710c296ed25f4c9cc24f5db697cb47f6f8f7b21bb9cc40d1ccda86149949dabc4e757906519a7d349646424b2db4574d220468e1c487d75255e9f82df1f64c7ee932cf8d32286682a78f467cb71b48f23de96f8999eb57f16060e1c4876ce00766edfd6a37ce2c489a86a885d1fb4d1674c246939a9c8411f07f7e4630fc5909ed32dbba204da58536261de8df1345e68475515dcf626362c5f843fe546e68e8b67c5d2a59ca872e221924bb648eb85e32c59bc9aea163789836ee05b77df468229c4be2d4b59bbb388a88c91b4768427c9ecec6cb2b3b369aa3ecbbeed7b9930337cef57ad5a4576763603070e203b2787dd3bb777f52be8aee4c517963266ce427a39ceb1f64035136fbd1d93c9c4f8f1e301304744e073b4f1e7bffe9956a71741d433e1cefb993d7e003a8d8856abed5ab27d553c2451a7d37daed9ede8de8fc8b9e14e00b66cd9425353133aad06ab494fc0d9c4c12d5bc81e3f0b80b48c3ee4e56de3d9679ee66f6f2fa7a4a603bfdfcf9a356b00301af4980cbaab420a4a3a830c8c3661b065a204dabb02132fc1663140c8cf99fc1d88a644a21233b0c33e9a10000020004944415407153a822a19117a8c31830876862da432479044b38e0853043a7302417b59573dded6739caebec0b0aca12498bb07559404ac7a899bfa18c98ad5b1f58c93f34d4142b2caf1f24e2aea5d4c19184db25942717ad10a2aa20876bfcc9ee36739f8c19bfce17f7ecb7b5b8f130829980c3a8c7a2d9db5659c397692ecb133ae39b68da7d7d064c9e5d68cf032fa4c4780ec68233a7322a200214fcfbcef11660392a0507df2201d9d2192b3bb83961d170e71a225c48dd9fdb05cb64c164501abc584f6ca6cbd3a2d169301e90a3376ca1d9338be6939fff3cc5fa8714af41b9283cbe562ddbab0157cc3cde339b77f137ff8c3f31437f819386a084115ca9d4186c49a304466217b1b50435f4fdaec6bc1a0d76136eaafa9f2e9b7d7515476923e7d469061d3d25c798ac3274b1939e37612acdd4bd58eb2dd84d233b0c524200a022d75e52c7dfdaf341a073073e2108e6fddcdb97603df79fc874ccde89ef8d7bdf832ee987edc32750445fb7770f654092db5f56c5b7f80dbbfff5f3c32d98855db7345507b7a1dded8b14c4e09079997979723cbf235af43634ce1b63149bcf7dc9f797fc356a2d206d037d14a4b4b0b7ffad39ff8d39ffec4813367d199adccbcf32e66df713bd3c6a6b1e4a545783de1762f858e5ccec4bed2817d79d9679530ba164497cb457b7bfb67aecc9e3899efdc1b1617bbf7de7b494e0ee7a3f775d4b261c95b14fad2f8eefd1300f8eef71fe32f2fbdcc7ffffaa7284da56cdfb80ba3d1c8c397f98bae058b24e0921554c58320e840e8e9345342014a0f6d63e9b622a6ce99494e9f18b442383adaa3a8a8b20b410adf3cb324105055426a08d40082145e67abaac2f9b355b4b9f4648f1cdc635214448158a3c8f0443d71660d4a48402b4a48025437f9585dd082cdace55bb76560b3e810544010108184943ecc7fe297fcf78f1792b76c197e6fd8ec77379e63d9e2a504d226b160e6a0abae5955026c5b798891336fe9f213592501b7aca22ae1005cc4abc997f5c5052c5eb98b9c9b66326964eac56b9329fce80cdad834923353be9059bdeabd4d4cbce7515e7ae169d22d414e1d388acd66e3c1071f0460e38aed0c9e7e0f7f79e15986261938ba273f9c195712705eba87a201f866a8457e125455a5f14203e72bbd0c99341a4201ce7eb48aed67ec14ed5c455555155bf2f268f1fa38bebf8eec640b71b161a990b307f6b0af52e5d6693710653552d2eea17742045969c9f41edc1d2ab1a3ac057b4d1945e71ac9ea9f426a6f2b9dbe10cd21951b72924819762b3a7337375055fcec587b827173667caa301541d49036fa768cd51f71b4dacf84a9a3d16b2412131379eeb9e778eeb9e7983e2a17c5d5c9fe754bd97df028c5951db4d416801a04c23ca4cbfd43d7e21c5d5ef66504d78a97d69c9ff5617d68fe74e24c3d5f8c80a3994def2fa1a05ecb830fcfa777447889a0d34b48a28846d262d00a2872f053b5312ec5c4aed236ecd5c7114d0968cc3d99a4b52777f3d687fb183d7b21378f1b844e1489336b88d70b145e70d056b20b53ea380046259928a977d2dcda82b3a10c53725833480938a9a83c813e6e0883124d57f5c1a09338521de07cb39fac782d920007cb9c1437046874c8149e77d2ee0a6232eb5055408548a3c4cdfda3d0e8b4680dda7021e06e2ce39dd7dfa2236a100f2f98815573f50df4341670a82d9ae903bb973593322cec3fd786bba98c6050451fdd3328d15e79943716ad2169fc1dccbd752cc68b564fd05dcfc9aa6a52d3069014f9c518e46e9f8ca8d3224922821a4409f5f40579fc32a2468b280948c828013f7a4920b79791ed67dbe8387f008d2d13c9f0cd27e02ab28f9aaa03786cc319956a411035640e9cc2c23b72311a8d4892844ea7430d3471c6231163ed43c4c57b3964fc14266548ac58b71dbb37408a494373bb8f16bb0b7b6541571b237a47d077d29dfce4273fe1473f7898f4e404cc1a810855a5b8c98da3aa00d9d7ed2b74d5eea2d09dcc2d033e5943ec729cdbbf0e47fa648626eb38b8ff3801e56aa773a7ddc5e1d266eefbe18f7878562eb6cb22553eed9cf0655286a45ffdea57bf319bcd88a2f899246c37af5b4b45450523468c60d9b265444545515d7d815f3dfb12ae6090aad347a9282f63cc98316c5ebf9eb7dffa3b9bb6e62147f765e65db3b11904162f5e4c6e6e2eab57afe685175ea0b4b494a3478fa2280ad9d9d944c59bd8b87431db0a4a183e791a378c1a88e1b265c7ef7eff0cf967ab09b4d7b06fc776323333494a4d22e86f65edf2e51c28eee09e87eea56f6224b12971941fddcfba8ddbf11892993fff7662cc5a3ced6decdbb88d8c3b1f2437a9277fa8f05c0b82de88c1a0252d5ac3f07423aa02450d7e222c5aee1a1d83592fb2645b0d2d6d3ecc56917183e2c8488a46157c2c7be75d36e41d62f4cc858c19dc87ad5b36f3d2d2f5c82137270fecc3e3f1909393c3a2458be8d3a70f7abd9ed3ebd670217e30b78c1f8ae9e2ee477c6a1c7bd67cc0c6ddc7e93d6014b74c1d83cfd9c1ead5ab193a7428afbdfa3aabf715a2b85b28d8bd139bcd46727232ad15151c3c56c2d09973e91f17b6080b0a0aa8a8a8203e3e9e9ffffce7ecdcb993d2d2520e1f3eccc89123292a2ae237bff90d4545459c3e7d9ac6c646c68c19435a9cc0a6b56bd9bc6d0f016b3ab7cebc1da31864f9f2e50c1f3e9c9458815d5b37b171eb6eec523cb7dd751729091144446958f9f69bec3a749e1b66cc60d4e03ee8ae31117f1dd8be7d3b7ff8c31f282e2ee6c48913b8dd6e860e1d4ad0ed61df872b89bbf3db8c4f8b4410252293fb3274c810860c19c2a1438778f0fefb3177d472b2ba927e936e262dd2404d4d0d0e6f88ef3efa280d27f2f8e8bc9fdba60da6fcc47ed66ddac5993a0d51561dd3a74f27253d8add1b56b366fd4676ee3b44469ffea4a524107255f2feb2951cad5469696ae19e7977a3d3e938b6f43d5a736ee29611595dcbecbcbc3c6eb9e516f2f3f379fae9a7292e2ee6e4c993b8dd6efa44fbf8fb8a23ccffdef7189b6166fffe6344f4caa0f8c421eebcf3ceae31d0a8413ace1d66f586ed9cac5168686ce69e797753505040555515a9a9616b5b14c5ab246cafd448822f2e612b747474744d9bc5c5c59f3ada7fc2840944444460b15870bbdde8f5fab0a3dae90c779eb0c967b55af17abdf8fd61853d8dce80c9684040c5e3f160b158f0783c78bddeae8b35180c984c26143988cbe54656050c4613862bb4b8ed9d9d8414b56bd7ce62b1a0d16808067c78bd3e5441c26cb1a095445455c1e771e30fca485a3d6693015110506419afc783643263b8c29ff2f686623411d198cc466cda7080adacc098be66f2cbdc9437f8c88ad7b262670dad2d2ee2e3047e726f36a3b2e2904301dc6e0f8a2a60305b3068257c5e2f6eafafcb3fa3d7eb31994cb85c2e4c2613a22812f0b809089a1e3e35559171bb5c041515bdc18841af4355147c3e1f66b319a7d3492018ecfabdc96442afd723078378fd7e7446333a297ccceff7a3aa2a3a9d0e87c3d1b5541704019bcd462814c2ed7677714d2eedf0287200b7cb43485191747a4c4623e265f7509583b8dd1e82b282a4d56332199104baeea1821896d4d57e7348b83e9f0f8fc7d375ad068301b3d98caa2878dd2e04a305e335264f87c381c964a2e2f8514ace9573d3bd0bb06a24028100c16010b3d98cdfeb22a048988d3a7c5e0ffea08c206ad1882a168b054509e171b909ca0a080216b3058d4624e8f7e2f10640d2a12a41226db6b00aa9db4548a3c3a4ebde8072381c582c160281c055d761d46b707983984d26043584c71740ab33e0f7798888e8fef0aa8a82dfebc6eb0f216a752872105b4444d7b588a2f8894eedcb99da3a9d0ebfdfffc5a2fddd6e378140a047273f0d2e4d46400fde436cccd5ca8446a3f11a51cb42d7f92693a98b03723944494b84ede34d7cdbc7c4dfe9f44674fa9eed098288d16ce5ca5e889284d96ae55a08c92a169d84cdaca5a9139a5d323e7f8808b39f83e77d9ca8f2b0efb41fd9a3a037e850a5b06cab200868b47a6c572c938c2613c66b5ce7e5f2123a9319dd15c70551c21271054f4c92bac6ddfa31fd97b45a2c5790d5f4faee3e5d2b7e5192a41ebfb90451d261b55dd5b3aebe0b92f6ea3e029246872df2caf3be1930180c180c57cbc40aa288c9faf1efc3a577a5ffe8b1f41fddbddba9d3e9baa49cf5460b9746d164b672e55d1745cd35c74b6730a3335ccd23d29bbbebbbb21f1f771d115dce771d16cbc57ee97a5e97208a18cc56ae6cf2924ed327f98ca0e7b6ff97c2d476381ce8f5fa6fcc57eb9b049b51e04c490d7aa3015f50c51752f106656a6b551c3e9578bd82aa91412b83aa106d91315e4f047c1dff26f8b4fca26f040fe97f036e1e9b4eae23d0ad702484ddd3e178b69ee3a5a2a297a057f4b559b2d7711dff6ab8c443fab86dfe2b976c5fc62e9be6f26c21d7d113aa0a724046be7277e2e25ca4225c2e898c46d7ad13731dd7f1af8e4020f099826bbf0c1ed2e7f621fd6fc0e6dd157c74aa05bde1a21f46b8384901888020a2100ec2550520e4e307b373189efdcd60225fc7757c1168b55a6459be4ab2f64a9fd2a5e39762e4be08340e8783cfcbd6fe7747bb33486adf44faf58b4155c3832f09101fa1c5e157e8f084b09975e8b422b5f600478e55e1f65fb790aee3df035f87b5af898e8efe5c1392d3e5466730f5e0948442415c4e178aaa22881a4c16739758f8251aba46a7c76436f588daf7f9bc783d1e5404a2a3bbd3e42872b8be902a60349930e87afabadc2e27fe401004019dc188c9a0470082011f1e8f1755d060b1f6dcf6f7054268b47acc6623a22060b7db2f9a9a2a8a02369bad2b83ae4623620f09543b6444016459c16610199d60e64c9d8ba0ac921e67c01554a9ab761390e9a2ef2b72088fc74d2028238812365b04c1803fdc2f5545d2e8305bcc682e63ddfafd7edcee706885aa2ae87406ac56cbc56d7f270119f406232643cffbe5f578f0fa7c2008682fa355381c8e8b6b7f155515888c8c44ba486d505515a7d3412010c0643277ed720603015c6e17a1904c545454577c9212f4e3747b90151549a3c76436f6083b51827e5cee8bb4008d0e93c9844612baeea18c88c96c46ff0ddaf6f7fbfd78dc2e1415a2a2a2ba96254ea7936030c8a5672222c28a4ea7430e05f17a3c044232e2c57b2a08024ad08d5bd6a2135482c1e0c78af20783417c3edfc7ee8a5e09bbdd4e4444c4d7365ef5f50d14159f4596e59e16927271a70d405511c4709935c24a4e76d6176a5373ad2dde4f8357df788b6153ee64cec4015d65559595bcf6ca2b041410345ac6def62d164c1bca1ffff8c7ae7ce49923463167ee3df4d6779b77fb76ef62d58a0fa9ae6b60ebb6bcaef20ba776f2d23b1bf1c902836fbc9305b74fc676d936d69277175154528e284264e628bebd7036bd2d0afb362e67ddde33a89281590f3fc1cdc3d2f1b694b1e89d6594d4b6139dd49ffb1efe3659f146de78e30d1a1a1af0775473b2dccbabafbfcce001e124921a8d48874bc5dd1e646a96058356a4b6cd8700e825817e0946045565dbf1664a9b7c080119511450e400e74f1f64f5baed34b677a23747f2cb5f3ec5b1c30759b57a2daa005a4b1c77cc7b801b877627a73c76ec182b57ae44554234569c2465c4029efdcdf769af3cca5fdef8800e4f88cce193583077268911ddf76df386b5eccd3f88200a5812b3b9f79eb9a446eb78fef9e771bbddf85ace71ae358a658b5f243e2e9c61d5eff3f2d20bcfb16f7f3e77ccbe8b279e780280a2a2d3bcfdc66b7c74f030ef7fb082acacf003767ae74adedb5c805f15514d492cfcd642c60deeee7bf1be8d2cddb00b8f2c211be2983bff3e260d4fe1dce1cdbcfcde361441c398190b993b6d3466fd37237ce4e8e1832c5fba845345a5ac5eb3a64b537ac992259497971370d65354d6c16ffee78f4c1c9b43d9f1fdacdbbc87a68e4eccb6387efed47f6130e8a9defd322b029318a07172e2e8217ef18b5f5cb3bdc2c24256ad5ac51ffff8c74fd5bf279f7c92975f7ef963e544fe59b834f9545656919696495454d44507f6a563d7fab7c2d9b367e9ecb47f62ddff081ab7db4d3018fcd4b3f625dc36ba177f7bf31de64c7cb6ab2cb6570a3ff8c92fc9e81d4365e17afeebd9b75930edaf381c0ebef39def70e38d375eb3aec123c692963d8c1f3ff1fd1ee53b172f2167de6fb93bb19a9ffea58071830731b47f7702c549b7cfe7a14763115c95fce8a7cf71fe6c36ba782d05fb8f33e73fff444afd0a7ebb6437370f7b98e3ebd750a74be3674f7d975dabde64edc6e3fcdf4726f0d39ffe145039baf255de3cecc518d35dbf280978149126bb823ba03234c9488b3d805612189a6a054160557e3d874e36110ca9d874612bd0ddd648deda0f499afe243f19df8fa0b3159d5e4f46ce70feefaf47926095d8b6ea6dd62ffd901b87fea4abbdf1e3c7337efc787cae4e5e7fea87a8e3c3c1b77b17bf4de48447f8bf23343cf3ca068e1c1bccac29dd11e783c74d67faacbb31c81d3cf7cc9f39bc379fc10fddc9ef7ef73b4065f7abbf64957d101a63f7975babd373cf83df2732210d67677736d4d4cc2cfecfcf9fa6e6c9c70885bad35e6f58bf8b81777e9b79e33278e9cf7fa5e4c4891e1352deb6fda44c9cc9fd378f60f1eb2f71f2f061c665c7b26bf90ac67fef056e311ce1c77fdbcfc4a1d9642647fd83a7ebab41bf0143f9e9af07f3f8f71fe9c1a179ecb1c70095a2bc0f7875cb592c4919389b6ad8bc6e1519b37ec24f47f709df539d165509b065633d231eb2e26d68c7e974a2aa218a0fefc369ca6054760ca78f1da1a2ce41558b1787231c0ee2f7b67268df411aed7e7af51940eee02ccc92cc858a531c3b518e2e2e8b9afa265455e5d8b16358ad56b2b2b2b870e102757575611da4b3473970aa024592481f3c8cc17dfbd0d9d2c4b1fcddd822acd4b707c8183402b1b598f27a0789d92319959d4075c5197c6206c3062460ef68e278e13926dc78031fedd98d3168a759b5d16fc8581445c16236a2d71b088542c8b27cf14fb9ecdfe1bf402080cbe5fcc2cb3cf1125bf7b39a85aeb6360c3161d1aacd9b37d3d8d848a4d5489fa41844015c2dade86392bb7ebfe2c30f78fef9bfb235ff04ae5098657c491b26313e86e4f8eee5c4251cb8e0614a760c11a9b9c89e4642ee961ec707a42760d04a781d0e14c98468b0d0e20ed1ec55199e1a414cf64db8abc3f143476a3d64f7b612171787a5573f3cb547bbea91fd2d1c28ada66fff741263bb0966921466a946e8243c7e8595c73b3850ee465154da1d017cfe10bd227428762ffe2607a2ac2088d06ef7919f7f8aa6c20d3cffe26b9c69935110488e8fa477b4152514c26377a08fee7dcdb175b69de070a3853b27868fef3def62625634e6842cb45a015f7b458fdf67a5c61161d413f4ba0986406bed5ef6063d556c2f6a65c2c80c2ca66eeb529224faa5276131f6244e46dbac6426c7a1d7f6b46266ce9942d1d60ff8fd337fa5ce1f41ffdc61b85c2ed6ae5d0bc0cdb74fe042c116fef0cc9f296991183c6e347e59e578839769393144668c25d8791ed9db79cd6bfe3a101f13495a62f4558a070072d0cef1f2526292d2e89b62a5a9ddc3c1fc13d41e5ec79f5f7c9d127b7833c36f3fc5195326bd23e291440145f1716cfb0a566e2bc0ed0b5073ac80156bb751d3d2467bd9aeaefa4faf5fc691f23abcce7a56addcc8d9d23a5cad4d6c78f71d8ed574d256b68b90376c6d6cd9b2852347c2fa53c5c5c55d2a19effefd0d2a9adb090602f84232322a959595fcf62f6f5054f7ffd93beff0b8aa3bfd7fee9d5e34551af5de6d49b65c71372e601b83316030184842484f36c96fb38464376537659390ec6e20951230e08a0bee55b6dc65d996dc8b6c15abf736bdddfbfb6364d902920dac17bc89dee799477aceccdc73efb967ce3de77bbeeffbf6d0d158cecf7efd7b8ed676e1e9bdca9f5e5f4d67572f974f95b36ddb4e9c2189da93eff24e493532b07cf97296979cc6e30f7e62665ea2cd66c366b37de81c82cdc77b79f2998780885ecb8d1996140ed250b99b37b79c63d9338f00b0ec99cff3e8e3cb1853904ce9bb2bd9b6f3344aa5928282f7b3dd6f852b2c635488880a7d84812c0f25e5cab28cb3ad967756be4342c178f2f2d209ca109441270a880a237238a229e30ecba80501a5a04410d4c861f7e0313aabaa686ef39353381ec32d9d5310051c7a914f8f373136594f4d7b089f5f4096e1e4d53e4acf763321c7c2dcb1b1886119d580d87f4086faa096e8b4628ae27cbcfcd22abcde08535f0af939bb7f03072efb78f4f1f7cb8fc8b2cc854d9bb1dc753f6903cb536758c6a010106eb0fc6fb0fe6f81afbf83dd1bd6e231a43175fad8c163351e2fa357e920377da8cae48745dbb53a34f1b94c9b34167dc84d575b643364e4c8910074d63622dad2983a7902168597f6e65ee481768f5288880a03b2e463608ff28e862ccbf437355177a989ac7133302b4502325c0fe971641453e070f1c71757e3f707a93f748aa45c1ba6d848d67bf9ee2dac2ab9c8ac454f30634c36c74e5fc31c97caa73fb58cbb674c1cac63f9fa7d9c3c7992b3e7af70a5f220eeee26dabafa3877bd972f7efe191e7b6421515137976af2c079dd3a035184fc3475f6a1898a265a674439909e92929ecee2258fb1f4c96770365d64d1e24778fab35fc6df7189803fc8d8c25c429eeb9cbedac6be2dc7b87bc91c34037d63d6bcf92c5938979109ef67147c1c103f6a96f693fff02526e747b6b733323230180c84833eae1edfc54bafef62f2a34f33b32832a52f2e1cc1d42953983a6336f10e138dd72a512a9583f1893f877cb38af3dd1e7c7d35886a1ba27a68aabdabbd8e0d2b9653afcee3334f3d40749406b35ac4aa14a8edf7e3e93a8fca920f40b649458b2b40bfb79f80a70d95391b88c87d9cafbe8a47ef6042e17b662c0218350aaa5afc74f405888f52a05389f4b843b4f685d955d94363979f69c50e12e20c4803bf358352607e7e22b3674c61e6bc45b4d59d420a070979fba9dcbd9ae57b6a78e2cb5fa028e5fdd48190a78135273a593cefe6605d685573a9cb4bc0dd822481423734ad20e0ea62cf3b6f70b859cfb35f7a92b4e8486792824e4acf56139b9e4646f2ff8c65bff7540d93ee1ac7ec39f760336b68afbf885aad263b3bd28e07ced4326a7401b366cf2121d64e4bf56954026445a938d3e9c1d75b8542178fa0bcf313476539446d431575010b33c747fa70944ae4fe826466cf9cc2ddf31fa4b9fa2452b09f03d702649b630775b4ec1603219f87be81cd1d49065110100501417173362aa8d53cf4d4333cf7fcf778f5e5979830ae30128b01148280202a236e128046006f4822180a1074350d1ee353cfff94657327e269aee47bdfff77ce5dae8b9c834e458c5e85421d834e29906cd2a05059893c0c24e2478cc3a15552b1f1fb5452ccecac9b0a02d9b6f76b617d9c103d1e0fbdbdbd1f9a87d27cee0427cb8e0170f2e4497a7a7aa8bf7689effcf0573484b5f85aab293f7a1880b3e7cfb171e306d6ae5e45635b3f1923c7130804387a34b29c3a7dfa346bd6aca1b1b191152b5670f6ec5900e6df3b9e4d2bd7b162f92a1c99f9d8e386fe1057bcf222bfdd7296c4781de5253be9ece82021de4e5e4634ab96af60ddaa4d4cb8773e00336716d3567b8d352bd65075ad85e2e93300f0f77572b5e2286963ef27ee3dbc0f1988d22a700604bc0199d9f90612cc4a561deba6a63bc48c51d1b4f4f8797b4f23bdee308222b2f360b799193f219b75ebd7b37ac57252464e45a15473f2d06ebef1a3d750c7d8693853c6b93367003876ec183e5f4414abf6e0067cb1e319197b53b972e1c2c91cdcb99b556faf41d25848cf8f88a395979703b06bddebfceb6b25c4275b397b600fd7ebea00e86fbac6f5fa66720a676019500ea8a9a9e1ead5ab040201366edcc8d1a34707dbbfbfbf9fbaba3a56ac58c1f5ebd7d9ba752b070e449423e78ccbe5d0c143ac59bd8af65e1f716923f07abd94959501307d741615a74eb266cd6aae377791945d8c46a362cecc2256bef6166fbfb18ab4a27198ac3797939f342e5fbecc8a152b68686860fdfaf583ed19f279b872680789773d4af280e679acc3c6e8e20cd6ad5bcfaa15cb492f9a4ea0eb1a7dca30c6b4a2c1ddd2ecbb16f08da7e67268cb2a761c3dc7c48274ba5bea797be55af697940ed6fdf8bcbb3876a48c03070fb26fef6e3a3b3a88b599189964e2e5d7dfe69d77d6e3ec8f48034dcc8ee7f2a58bac7a6703478f1c1e3cc6915367a96be9426b89c36ad1237293282d08020cfcbdf1ff0d28b576164c4ce4c08e83142f9c8a517733395afc0872d6b7138a679f7df687a228a2d3e9e8ececfcabe5470281005aad96f4f4746a6b6bb1dbed8464057e859adcf47844298446a3212b2b8bb6a626da5a5b08a364d494394c9d54804a90a9abab232d2d8d8686069a9b9b2928284096651c0e070909095852325039dbf06b13993b771a1989b621026ab5adfde4e66560142582c120191919581c7144c7c512eced40135fc4a279e3316ad4e8e35288d64a383d21b2c74c63e6f84c54a240380412060aa78f23e63d03526555072a9d1e6b948a648b805ea3c0a0164989d1126b56136b56126f55b3eb4407bdfd018c4691c905d1a424da31c6c4e36c69c4a770b060f10212ec263a7abd981c3124db2371249bcd46626222353535242626a252a970f58449193b8aac64c7a01097292513bdaf1ba76066d2f4e98cca8927e8f7d3dcdc4c4a4a0ad7dbfa49cd48c1aa55100a06494848c06eb713f44b68cdb1144c28c432b0b3d5d1d1412814c26ab572f6ec592c160b292929c8b24cfec040575555457e7e3e7abd9ea8a828b2b2b248ce4e4572f6e20e2a2998309d49130b50ca61eaebeb494b4b23312309a5df8dcb0739c5539836a5188356852d251da1a78970543af3ef9d4292c3fc3e65d04f0a2d2d2dd4d4d43072e448542a1576bb3dd2166108f85414ceba8bb881b89b42a7272a3a16676b337e652cf73fbc004f5d0d0d0df54cbe773656b502a552495c5c1ca326cd26cda6c429e9183da1089b4ec4e50ee0c899ce84d179646464e0c8ce46efefa3b3cf8da88922332b87684734b1493178bbbb50c58e6174e1488a0a4792901487560ae30d8924e44f676c610ea9a9a9b4d65fa3a7b79f5058c1b82973185590835eab22262666d0f5d66432919b1bd900d1e974e4e6e6a2d56a09b9abd85bade3338bee23ce6a401084c1f76fecea5557d760b3d9506bb4489234b864fca057381ca6bbbb8b58470c1d1ded1f5d7ea4b5b555be9187f461e447e6cf9fff67f32dfe56f0a72d9730d8ec18a274783c41da5d619065168c8ae29df23e8e56b970682576a14e210000200049444154eaaef712f2f8888e16f8d6d25c26e63a3ee9531fc6c780be8e0efa9d4ee2d3d387e4d5dde9a8acace0f72fbe48de9cc7f8ecc373316b3f9811be7bf75e3233b3304659deb3cbf6fe572010e0dab52a0a0bf2b970e1fc47971ff9a879487f0f90e4307d2e2fa24241af278cd71fa6df1be29d323f57da82485298d6be005a9d0285568b461744108633b5ff5e608e89c11c13f3df7ff00e435e5e3e3ffcc9cf88b25830de21396137a0f4783c1f290fe9ef0113f2ec9cbcd24d6f870741008b00261d8425189f20202602a89051212363d5418afdbd8a4bc318c69d850fd627bb33a0ecebebbb2d8e937f8b28ca89a7286798283b8c617c5c505aadd66181b63f8363a71a3870a2097f68601976a389065295e481dd0b194014888e52b0687a26290977be90fd3086712742f941d297c388e0d4c50e3ca286e4cc81016680bba35088042599901c91001544117720ccb9ab2d8cedf40c0f48c318c647c4700ce92f40104544a30e85c5485892912519a34664526614351d3e1aba7d8c488e42a914395ae34456a922b3a6610c63181f09cabebebe8f6481bb7eeb3ea6ce994d66f4cdccdbb69626b66dde44bf3780c6e4e0ee050bc98b33b165cb16ae5cb9825aad2621379f99b366117d0b57ea4cc5090e96ee4312d57cfd1bdf1c2c77f634b27de3265a7d3a26dd7d376372d386c875ecddbe89f355b5084a2dd96326337ddc480c4a89ba2b15ecdf5f86571bc7830f2d20d1128514f6707cdf2e2aaa9a89cf1acdbc3993d02b4456ae5c49676727b2e4a7df15e699cf7c9ac4c4481e964221d0e596f0b5fb49b7a9088424bcfe300a41c0ed0b625089d8740aca6b9d9caf73e20d48830e28aeae568e94eea5aaa11db5d1c6a79f7a9cba6b57d85f7a005f58c61a9fc5dc79734888ba999476eedc39f6efdf0fc804fc6ed2b38a7978f17c02be6e766ddc484db744d184c94c1e9b8fe616aa4ff991528e9f3c8324aa48c91fc38c29e350877dac5cb9129fcf872c790984f47ce1f39fc1648aa46a04027e36ad5f4355d535a6cc9835487caeabb9c6ae6d9b69eee8e6cb5ff91ab1b111b2b1b3e1029b771ea0d31dc29a3482d9b3a69268bb39bb76355d61fbae525afafd98e3b299357b26c9d11a7adbebd8b2710b3db289bbefbd879169099f6826f0adb872f13c257b76e2f406f9ca57bf3698c6d271a59ccd7b8fe30c426c463173674ec06e14a9bf7a9a929223381576163f723f493613a220e0acdf4f69670a699a204d0d757f71cbfb4e84b7ad8643c7ab481c3595bc7899b3475651e74ebe2dd6d81f16a2d56a253a3afa4373d984eeb3bcfac7f543ca7c610185259ea2d1a3b14ad779f977ab8188ff954aa562f4e8d164a5a6a07d4f87f4874574b644deddb46548f9e9f5af72aadf4caaa18b77369450dfee19f27e4f5847dec842f253f46c5fbd8a2b97eb70b7d5b377c33aba8d6998fb4ff1da86483674d391adbc7be40ad18e18ae9dd8c6f6a3cd00e4e6e6327af42812852e8e1fafa1cb7df3dc144a0157105a9c61526c1aee2fb2916c53a310212b464f716a14554d2e7696b7d2d4e2c4ef0f2108024177178776afa6a255a4707431d9c9d188a2407f508135219da29139f4d796b166d5ee21d763b7db193d7a3405f939782f1de16875e49e546d5d4e69bd4466b444c9ce9d54560d25a876f955a4e5e43122d3c189bd9b3874b012954a45414101a3478fc2e1aee6e0a90ebcb750016519420a234d1d7d83d9d600414944634d604f49295d5d5d83e52bde788bc6909afcfc342e94efe2e8e1a3b79e02eb56ada5aa2f405e7e0635170e50b2773f61bf97f2757fe26238816475332bd61fa4bd77a83df42709bf24608c4961ebf69d783c37fbd69f5e791d579483c2bc780eee5ec7c50b17f1763651b26e151dba14e2fca7796d7d0581602459b062ed26da7abba8aea966fffefdc8b24cd0efc31f0821cb12017fc46ec9ebf3230d70d1bc5e2f019f178fdb83d7174092220986a160008fc78dd71718d4ceba614904100a85f0fb235c46590ae3f37af0783cf80341a4810445afc78dcfebc1ed0b2249d2e0313d1e2fa1708491e1f7fb6f7e37dccbd163bb3877a61a7f5f3fe5affd96cd270f72c5f5d719bade4e7ce41852764e167b5655004498fe160b89f1b13cfae042b46a1535d6301b4a370f7e3e3ada4e42422251d668b48240381ca6adad8d848404468f2a222b3b8bcd1bd60ea96347e97916fde4cb8cb339d9fcad3fd0dbd60271373340ef9b3b13ad5a45d0d9c8a61d2770f675d322895435f4f0a57f9887a13b9aaf7e6f3b3c3395d2a39748cecc61fec279ec0a7673a9ac14a63dc9d8b16391c33ed69e39cac85959c425dfb4715228448282821e375c690be00bc854d479989c69c231600974bdc54d635d0f416f8818bb80280a74b7f77068771913bffc1d126d26ec313128952a8a46e6326a641e0a82f87b9ad97bea12b070b0be848404121212e8ebac63c3eb66162d9d0cc096bd95dcfdb9e7b937dfcc899fbf4a53d505c89b36f8bd995326a0522a907ddd9c3c7986aeb646349af14c9e3c1929ece2773b3630f5a1a9184c37b77ad56a350f3e701f5e773fed6dad83e5e969a9242727b37df3c621f7c2ac1208184c44dbade8f451084a3da150888e8e0ee2e3e331a90574da28a2ed36f43a03a2d2803f10a2e4e81596bdf42fe429aeb3f19bafe2ee9d0eb6c40fdbddfe57909f9b4b6e4e0e1bde5935a4dcac51201a2d44db44747a3382a8a1adb39ff3d51d7cf96b0b480ca6b0ee1beb082f9b8424f7b2f9ba8da7e63b68bede892c87e96daf63e3ca3711b2efe5e1f136d6ac58c1e99a0e74d6241efbec97189f66e5eb5ffb2a85a9d154b7f6214717f2a56797916197d9bbfe55361fadc19e52c4e58a83bcf9c6abbcf1c61b242525b168d1228e1c39c2b163c778fef9e769b850ca9b6b76d1d6e7233a6f0acf2e5d48dbf52bfcec07dfa1b87814c2c8c53c3b3b8bf25d6fb3ed4815b242c39cc7bfc04393f3f9c31ffe40d3a50ab4f1598cb8e771ac46032d9d1768734fa03a90486e620cd72e7641f1c77b4f44afd77b8bb2e05f8f03bb0e32eedea5001c3a7488aeae2e940a053a8d0a5fd775f66c789771f73c06c0c8a2622a2a2a78e50fbfe1c53ffc89caaa3602810025252500a8d5aa0f5412bce60a916bd6a236a620077b9143ce21efebb56aa4808bf25d9b509a52884dc9c21992e90b41b25183d69c4bc8790d805a7708874e8d516b44a98b21e4aa1b3c8ebbf532971a9a28ce1d83e316fa88288a58b40a1e1c61a0285ecb9e8b6e1abbc284c232c72ff770f17a3ff78c8a26c7a64176fb518b028228d01f943870fe1ae5efaee1f72ffe9c97d71dc41f0ca3512951ab1474549fe6c4b14ac6cc5efc816ddb74620dbd8ec9cc4d8ac4f5aef487c8326b50ea621184885ccaadd06954887290cb657be9ea95c91c75d32bacf7da112ef4094ccfcec178cb32591004745acdfb964f4aa502ad4635a87c790313678ee3ecfe6dfce195e5b4b864d27232f0783cecdb1791d418337934d5e50778f995d7b9d6e625b32087900c759e10f9162deaa80cc2fe76e4b0f703aff993804aa544a356bd8fca3261ea680e6e5cc16f5f59894f6d2636291e7748a63b28931aa5416b2d20e4aa06c2749ddf8b323b15534c2c8220d070f51c7ffafd6f08264fe7f17bc6717c7b09b52e33dffed79f302b47c58a5722722d2d9d3de8a62ce3972f7c0f55df156a2f9ca5ada1993dbbcef0e97f7e816f3d9484b7b7015996e9e9e9c1e58aa85678bd5ebabbbb0158f9abdf128a1fc19ce94554eedeccf5ab35f8fd7e1a1531dcfbc5eff1fc639370b534b267d7699efece2ff8ce67a6b0f2b791554b4f4f0f6d0977f10fdf7a9ea593b2989c18191caf361ca32fff8b44fba309d55cfaf86ec600c4dededec129e08781ba68214f2c8c484f2c59b284c4c4c853cfdb59c73bcb5fa7d1389a271f1c0dc0134f3ec5bffffc057ef0fd6f630c7470b8a4149d4ec7534f3df517ebb028057a4261a4503f82a80561a8434a38e8e7c2e1edac3fd6c4bc47ee272bd9825a88b0a39da13052a80741191103332b043c61894038802c79119411a6bd2c4b545735d2e3d391539c3bf40444b0ea1424991418d5022a4140a350a010a0b53bc8bb659da894224bef4dc366d640580601940264a665f1e4d7ff991f3ef739cab66e2430409e75369ee7cdb7d613357a3e8beece78df354b929f9d5bce31e9be19836536a5406f308c1cf6000282f87e6988fa330758b1f524e3ee5bccc4c2480c4c96429c3a5e85de914c7ceaff2c9f6acd8a1dcc5efa39fef3859f90162571aeac1c93c9c4b265cb00d8b4be84b1f396f0cb5ffe8c51c9464e951e421c68f7ae601829d417919111ee7ce3ba756b4a58f6f5eff2e20bff8ac6d942eda5cba804d089d01f0a23053b1194919dd453e5dde4c61a88b145180ff5e74e50d1aa64dac422342a0575ee10090e03715613a6d42202bde701d02845e6645b51ea1310d55a64c9852b28d32b0814c61b30674e47a9bba90611911f9190a59bcba8f236372a6f376d3d1273e64e262529425c1e116ba0283e120feb0fcab8940a0a128c98332613f25c19fcfedc1c1bb601ae5ee6d878bc0d1d34eeda4df69c020a4c1eb2753767ce1f173e720ce9e17bc61335f0c00d0402489284a7bb8955afbd42656f148f2e5980553da0df2c84f1fbfdf8bd3e04298042a14696e5c181f08615702814c2e3f11008040098916561676523ad978fa23426a0360de5885d3db685dfaf3dc2b4871ee3aefc14445922d6a426c1a0e0d895361a2b7662c99e0ec0e40c0b971b7aa86fa8a7a7e10a968c490084fdbd5cbb568e316102236287fed06540af5670ba31485d4780c278352a05ecbbd0c7d9263f9e904845753fd52d1e541ad5a0679b55af64eec868dcfe0001bf13955a078240eff573bcf85f7f2498348687e74f461d8e2832deb0b706705edf47a52b9ed9b73897ccceb3b3ef5c0b1db567090665f4b1d9489234d84e6d170ff05f2fbf4bf6ac07983b310fe5800e4ac0d9c0b9da3ad2d2479338b0c40c854204834164591eb038f70fb162be710f42a1d0e0fb00220adc81103e9f1b29e447401c720f05443cc1305e9f1b29e8431444d44a81bb524d6c3dd540f3f9fd68ec39287577865a244434ae3fa8df0988b8fc417c3e177228882088d88d2a52cd6a0e5f6ce5faf14d9833a7120eb471c9276235e7621cb02a2f9a3e8f858551ac5cbb99b63e3799660dcded2eea9adbe9aa398d21664ca40e4118e0bfdd9c9d99d40aec229ca8e9a0ed5209414f44a02d41aba4a1cf4b6b57071d5525839f9f96e1c036723a4f3ef9248f3e3097686b6446ad1c3c3658340accb2cca9da0eda2e1d406b291cfcbe5a1406678751591311bdf51cdc7b8db93966b247d948cbfff8d35714fff22ffff2c31b4ba58e8e8ebf9aedbf63cb66aed7d53176ec58d6ac5983d56aa5a9a9855fbdfc168150806b674f505b53c3c48913d9b56d1b6fbdf13abbf71d40933c8a450fdd875125b362c50ac68c19c3a64d9bf8cd6f7e434b4b0be5e5e588a2485e5e1eb6441bfbd7bec59e13f54cbee75e2615e7a0b9c554e017fff95bce37b4e36aa9e670e93e323333494c4d069c6c5fbb8a13b5219e7ae61152a24dd85313683e5fc6e6edfb916db92c5d3207b35689a7a797f292a3642d7e82c2d8a15a3d95551d28b47af43a1569360545293a44016a3a83d8cd6a168eb562d22959b1a791ce1e1f862891c90531a425d911d432ebdf5ccef603e798b1e469c6e4a5b07bef3e566e2f25e4ede374d911fc7e3ff9f9f9bcf9e69b646565a1d168b8b8630fdda9a3b87bdc4874034b2c474622e5dbd6b1f5d00532c74ce1de9963f1f4f7b069d326468d1ac56bafbfcd81b355f8ba9b3876a014abd54a727232dd75f59cbe544ff1c207c9b445e247656565d4d5d5111b1bcb0f7ef0038e1e3dcaf5ebd7292f2f67c284095cba74891ffff8c734343470fefc79dadada9838712299c93a4ab66c62c7dea32862f3997fff3c340458bb762dc5c5c5a425ea38ba7727db761d241095ca7d8b1f20c16ec4ec30b2e3ad57293dddcadc450b193322f503151a3f09ecdbb78f175e7881c6c6464e9f3e8dd7eb65d4a85124c7086c79671dbbf69fc09e379139b3a7111b6341a1f0b263cd4a0e5c74f2c4671ec3dc53c7c5fa3a46ccba87249386d6d656bc4199a79ef93caeab87395ced63febc71b45fab60d3e69db406cd3cfed92788376b3976ec18d3a74fc7683472e6cc19d2d3d3c9cbcf420cb5b161f57aceb59bb97ce9224f3df904297625a70eee67efa14aeadd76921c514c9e3c9994cc580e6d5bcfa6ad3b38547e8e11058548e1104d4d4d83bba67aa306516a67d3da751cbbd8c1e2679e2637d1ce850b17888f8f1f64e58bca283c172bb8eacfe6f1876761b41b69ecf112ed4847a952e1f5fab8a19fedf7fb077dd982c1e0a009c06d61fb373737cb379c122e5fbe3cccf6bf057fda7211b5d98ec1a8452b84e9724b280498536862d7b97e2a6a3de43994ec38da4c4fa79b9818817f5a9ac78461b6ffdf05ae55565257779da98b1e407b1b5c5bdf8b458b16b162c58a4fec777683ed8fa0a0b1a99eb8d878140a150d8df5d8ac56542a0d1d1d6de8f53a6459bc3d6cffdede5e944ae5dffce0f251100ccb189522513a356d7d413a7d213cbe3065d51e8ed7fa395f1fe07c8d13c9073abd064111263cec5cfb7783ace262b28afff7b6a11e7ffc71ee046769b55a4d4242127a9d1e9fcf8fdd66c76c36e1767bd1eb0d582c667a7afe676e2337a0b4582c68349adbe2cbfdb7069b41a0e27c1d2aad067f48261096f18524ae5f97710564625432b2228cac8cf8d7da8d1246f59d91f4378cfffb58ba74e9277d0a00a8d51a445131e862abd71bf0f922f136ad5687db7dfb764e9577aa0cc19d80f9533299521c4466e82073630e34582a44ca5422588cc3fa52c3f8db82dbeda6a9a901bb3d1ab55a43734b1306bd1e9dce406f6f37a24244a5bc3dfd5ee9f3f90806831fbb19ddff05b85c011a5b9c04c3b72cc3845bff0a43ca0d5a057ab5128deacedfda1ec630fe5a88a2883dda8ec56cc6e3f1613418888e8ec6e5f2a054a971c444d3d5d5735bea52f6f4f4a0502806ad94877113bb0ed572e2720f7ac38dd15f4606420042847c1b96411a90200978dc7ce1813cc6e60f6b280de36f073a9d0e954a4528148ef8149a2c83b65e468311a7d37ddbea1a8e21fd05f4b94324a43bc8ce8e8ee409c9a01021c1a2a6d71ba6d31dc416a541a35650dfede7f8c93abc81e1a0f630feb6e0f379696e69c66c32a3d16869ef6843a554613018713afb0985436835b727f4f39163486d1ddd886a1d7af54d3a82dfefa3b3a3839024232ad4d8a2a3316894747474e076bb1145118dc180d56a1b625ae8ecefa7a7a71b1048494d1d2c0f057d74b677109044cc361b26bd7608bda4abb33d12501315e8a3cc584c4614828ccfeda4bba70f495413e38846ab5222cb61fababb707afca8f55144dbcc28048196969601e2a244282493909080561b9911a954223d0181eaee102a05842509935a647ca68eee4617a1b04caa5d4bb737444da70f5f481ea45c84827efababb71fb03880a1509f171783d6e7a7a7a9064506af4d8edb62179552e976b9016204b61b4fa28621dd148e1205d1ded78833246b3054b946108dda1afb787be7e2720a03598b05a4c8848b4b4b4442841b284248b2425250c32b82549a2a3bd15b7c78bd56ac36a8d242c7abd1eba3a3af007832427a70ceef2847c2e3a3a7b084a322a8d01abcd82f6162a4ad8e7a6a3ab87405842a9d663b559d1aa4442412f9ded9d04652556bb0da3eece110374bb5c747777120ecb2425df64b707dc7d7474f7119641ad3361b39a500fdc27bfab97f6ce2e6213926fb68db79b9ea0169d28e3f379898e8efeb375dec9087a5d7476f7120c4ba834067c8148826d381c46a7d3603245e1f3055088220e47346eb70f499648888fa3bbfb36edb2f97c3e42a1d0875eb2bdb9fc75b2ef5ac893f3c60e9635d4d7f3c73fbe0ca248580a3162da129e5d34895ffce217b4b5b591989848dae8312c5afc1071b70c64c78e1e66e386f55cba728dd2011f3080da13db7869f54104c2a48d5fc0a71e9a8bcd70536e77ed9ab55cada943144228a3f3f9fcd34b4836c9946c58cece93f5289098f9f8d7583c291b77d3795e7de31d1abbdc18ed893cfae92f52946464eddab59184b6f62a8e5d70f1f26b7f60d4c8742042aeedf5cbb87b83cccb8fc2a45550dbe145008c1a91e80403c16098ed27dba8eef4a3088411450129e4a3ea54291b771cc5e5f5a0d219f9cef3dfe6d4c9936cdab20d5121202b74cc5af4140beeca1ebc9e0b172ef0eebbef228503349c3f8663cca7f8af1f7f818ecb87f8d5ebdb0886423872c6b36ce923a4dc22fdb17bd74ecaca4f218a324254128f3dfa18d909465e7ffd753c1e0feea6d39c69b6b376e54bc43a22034fc0efe7d597ff48e98143ccbf6f21ffeffffd3f00ae5cbecc1bafbdc2defd0758b77e0379797900946f5bc5fa836711942adcb299a54f3cc18c7137cfbd62ef46ded95386a4d4e096f42c7ae471ee9998c5a543eff2bbf5c7d028c2e4cf7c94650ba612a5bb33626ca72b2b58bb7a2565272bd8ba751b310382fd25abffc8ceb34da89522fd8283af7cfe698a721209fbfb39b46505cfffdb7fb172d3b641a3d39add2fb141b8877c451f27cb8ef0a31ffde893bcac41dcc8feff4b0f801b9f09793ad8b77913a51557090b2088464c160b23f373d1eb0da8d56a24494614456c363b3e5f84c2628a32dfde5db61b31a40f3b539a3f399d97de5e3564407224a4f0d57ffa67921d56eaceece0db3f5bc9b38b26e1f7fb79e6996706b347df8bd1e3269139a298af7ff9f343ca4b56af67dcb21fb328b6817ffc65290de38bb1dd42a998b36829cfc45ac153cf37bff573eaaf15a38d5173f2c4251efbd62f496c7997efafdecfe249d99cd8b69d7e7326cf7dfe5e4ad6ff891d3b4e51f4b9197cfdeb5f0764ca56ff0ebfc34f94e36696baa810f04a22ad7d125d6e891c87966b6d5e540a81c2a4286460cda1262ace77100ac95834410441c0d5d946c9b6cd643ff04f3c322e9d90bb1b95464376e1589e1b3d816883c8ee8dcbd9b37e230bee7a6eb0be8913273271e244bcce5e7ef3ed2fa19f731f00fb57ae2679d6e7f8cc18353ffbcd462a2b6b48993d62f07b63a7ddc3fc450fa309f7f2c2cfff83d365658cfdf4437cef7bdf036476bdf4cf0881d1a80c3773cd546a354f3cf365acb129f4f7dc24eba665e5f28ffff263ea5bbe3884707d60ff710a1f78862593d279e93f5ea4e6f2952103d2914327499bbe90a7ee19cb9b7ffc0d57ce9e67e6a824f66fd8ca9cafbcc86c6d05dffc8f63dc33a190a85b14153e49e4158ce6b91f14f1c5cf7d7a8845f5818315dcfd0f3f627e9682ef7cffd7b4d43752981d47f5b91354348bb8a29207db4696fc6cdfdbc75dcf987135f710080490e51015a5dbe935e63273743c15470f72b6aa1983239d39f36611ad51b076f52a120c32979a5d58520b9935751c369d44f5c5e31c2abb8826b6006f772d4f3df118e5e5e5582c160a0a0aa8aeaea6aeae8ed9b367e3ee6f62df8e7db4f405492d9ac09431f9f4b6b7b07fdb46ac16139ef8092c189f4a5b750587cbce13505999b9601ed931660e1e3c88bbe92abd8291c4e2b944d7ee64cbe9469efd87e7284c88e2d2e1d51c387a0e806030406767277abd1ea552455f5f1fa2428156a3c5ebf5100e87512a6f8f2ebf68369b898e8e46a1f8707628bd4df5e862231d72ddba75343535613268498db5220ad0db588b36e666faf81bafbfc6f7bfff6f6cd8779cfea084d7ebe5adb7de02c0116d25ce6e42f11e4ac1f1462fd3b36c18934613f6b611f2740e793f3b291a8d4a81a7b30d4934a0d059e8f484e8f0c914254661cd9e8ea7f13800a79abd64c71a89b647637064e06d3e35789c90af95e3d7eac8c9ce20de7673fb52a110512a1544eb14486199f595bd9ca8f1204932ad3d3edcde2069d13a04a78f40bb1351921044e876fa3974f834d7f62ee7fb3f7a81532d3e2404e2ed26622d06a46080fe8e36b48ef7a7ce0338bbcaa9ecb2b2785264703c5cef6652a6057d4c264aa580bfa776c8e73312ec18b56afcce5efcbe106af3cd4135e0bec6becb5d4c2b4e1f3233512814a427c562788f279725ca40729c1db56a687f58fcf83c2a37fe897f7afedfa8f79928983896fefe7e56ac5801c082876753b37f3dcf7fe7079c6b15193b631281b04c65ab8fbb736c98522610ecab25ecebffc06bfe2460b79a487458de476559fce86c76fee1e77cf33bbf2068cd202d2f0b6f572b65870e9136662ab94937f978be9e0aaa4c19c49a6251880292e4e5e8e637d874f8123aad9aba6307d9b8f31861ad9efa8a1dacdb1c71655ebe6215bbaa5d38acb067eb462e5eaca1bfbd95ad6faea24936a3ee29e3ed3ffd8e40204069692967065c8eaf5ebdcaae5dbb0038b5e60d6abd0a622c329bd76da3baba958686067ef9e6461ac346622d06dcad4d6c7e6b35cd9209a1f324afbdb11f88d0667eb7eb34aa282b16838aa3679bc8ce4e273bde8642a1216fe25cd20b23bcbb4020803fe045a3897050bd3e0fa6a8c8c3cde7f761b5bedf12fea342d4ebf51f29a0bded3c7cee0b11f98c2953a660b7479e7ae1a08faac31b59beab8ecf7de961003ef7d56ff2cd6f7d9b07174ce6e4f6b56cda7c1cb55acdac59b3fe621d7e5946230a88a21ae470e4750b6449a2bbe1226fbeb5818c09d31839228db00c21798038286a91a508cbde2fc92805015110110425b23c207225cbb45daaa2b92d446ef10474b7744e411488d58b7c7abc99e2641d8d9d6182c148d251c5d57e769deaa438d3c4fd53125122a31222d3e3900c1d0a0b3993ef67e1780b2fffc71b783c91f308f9dd1cdbbe9223d7553cfdf4bdefbb665996a858b385b8198b49d044060b9f24a311040461e02924bf5f38cbddd5c8a6d5ab08c78ce4eebb8b07afadf670192e4d22d919d9834eb81f05578e9f26ba603a4f3fbe18abeca4fe5a0b7abd9ebbefbe1b80ea53e731a48f63d9e38f90a0f35173b91179a0ddb58280286a06cefbc3c9dc7c12b8527e8ef4a9f7f199c7e6436f076d8dad5caad84e595b342393a308fabcb47774e00f87a9de5f497a8e156b9c0980a35b37b0fad075162e59c6c491a91cbb50872d2e91c71f5dc284c993397738223fa251abb87fde1cee7ff829ccda30ceceebb4753bb9d0e2e4d9658f70ffe28731de222b1d216ecbc8f2cdf67be5dd528e1f2ca5f4f049ae5f2e23ec8bc41f73b33258b2f8016614a5d0d5ebe44abb9bcf2c5bc2e2c73fc595e3374510674e9bc0c27be7509414853b2ca15508a806babfa83444d419009d4e4f7c5c220a850a51148989767023e5c56c32130edfbe8d1cd1e7f3e172b93ea2f53d640000200049444154b41ed2e7bef979c664448277f1f1f168b55ac27e37e70e6ce2f76b8f31ef53cf3031370180dcac540a0a4652387a3cb10e0bed0d975028148392257f0e85360d956d2ebcdd55881a3ba26628fbb8b7f90aabdf7c1b67ec783eb5743e56bd0aab46c4ae12b8daedc5d55a89c65e04c0089b86c63e1fbdae3efcce2634d6c892470efb385f7d197f54221346bc8783268041a3e04c838f962e3f4966255aa5484b6f80a69e10a517fba969f5323ac74a7cac8101923d4695c87d23e2b96b4c21c59366d1d37619590a1174757364d39bac3fdec5335ffb3c398ef7e77e059cd5ac3feb62f19cbcc1b2e2680d67dbddf8fb1b9124501a87b69bbfb785cd2b5fe79c379e2f7c612989e6487c490af472e07c0df119e964249afe625bff773872a999d185798c193701539486ded66b28954a121222f7b8bcaa85bcdc0cc68c1d4f8cdd4a57e3255422e45bd49c6873e1e9bc80c29084a8baf3294a65575a99367e14a3274c468507676723a1f6763c9de7f9c3af7f455555156b376ca0d9d9c5a1fa3019a684411bf6c4a478f478a96b688a04870581505822149690827e0431320317058178830a51a14510154008510005e00fcb4801cfe0e0a317c1150ce30ffaf1f7de9c1d5b4c261effe2d7f9f14f7ec1f2d77e4b417e644562d52ab00dcc7c4501441902611929e843b845c227c9a84633a052303ed5c6b5e60eea7b3c48528896aac3745c3f0d30441902201008e2f146e246e1707888dae6ff148acf7ef6b33fbc11d4eeeaeafaabd9fe4dd7aed0d1de4e666626070f1ec46030d072fd1adffacebfe236c66357fae96a6b25272787b2e3e594ecd94df9b1c3d4b53a193ffd3e52e34d949696929191415959191b376ea4b4b47490399c94948421d4c2dadda7a8397302657c21d3a74ec074cbb2e3773fff01cb4bae32ba3095c6cbe7898b8b23c6aaa7a3f10a25c72f72e5543959339630313f9e18bd8fd2b24a2e5fb848736b2f93172c2123568fb7a79d7d1b56609ef834b346c60eb9d6caaa0e64958e90a0c4a617294ad1d2eb0e5371dd438f4f66e6480b822cf1cefe469adbbde80d02930a634877e808381bd955769133652588b1139833b598e3fbb7f2dc4f5e26363707a9bb89502040525212252525c4c5c5a152a9b8ba7339479ca92cb96732465d644614ade967fdee13d45e3c835b6967daacd968051f656565a4a5a5b1fe8d97f8d9f2fd1416e7d0597305c340e25acff58becd97b88bc998f332623a29573f9f2655a5b5b319bcdbcfdf6db949494505d5d4d5f5f1f595959d4d7d7b36ad52a4a4a4af0f97c78bd5e72727250f7d6b0fbe425aa2f9da5beddc3b829f7101fade7e0c183646464a0eabbcefe8a0b545fb9484d5317a326cd6744460c2a5f23ab779ea0a6b28ca8cc494c9b5888fe0e714b3d7dfa34ebd6ad63efdebd83acf5b4b43442cd17d85d5145cd8513343b354c9b750f13e62ce4c10716b260c1020e1e3cc8f3cf3d47bcdcceb1aa5a928be7921d6fe0dab56bf4f905befad442766cdd42976c664286911315673877a98aeaaa4b14debd8c51d931bcf3ce3bcc9b370f93c9cc9e3d7b484b4b6344562a6d5527d97bba86866b973851718e654f3e85c6d9c4c11367a86968a2f2e449142a3d73e7cec51c6c65ebb10bb4d55773baa28294d474fafbfb3973e60cf7df7f3f006ad94fcbd54a4acf5473e94429d1450f30635c16a5a5a5381c0e0a0a0a00888937d170ee1ca72acf73f14c397bf694d3e5d6523ca69850384c7b472b46a3115966e07f030222bdbddd180c3ac2e1dbc3f6577cf7bbdffda1d96c46a1507c28f911a3d188dd6e27292989eeee6eec763ba24a8bd11ec798826c2c5106ac562b292929b8fbfa080603184d36c64e9dc5843139a8c4886a5d6262223d3d9160e0c48913b1582c242424e07038b0a464601583e81cd9cc9a3989d458f390ed6e6750c1d8b185c45ba2d0ebf5a4a6a662b23b884d4c44274844678c63fecc51e8d52ab48e44122d7a141a2305e3a671d7a8149482802c8b688d0e8aee2ac2fa9e1f4a6555072a9d1eab51456294805214306844f212f5d8a354183522f15635fb2abae8ed0f60348a4c2e882639c18e393609d1ef456b4b67de7db389b518f0040552b3b2c84b4b20ca60c0e170101b1b4b57571771717128954a82010dd9e34691166f1f34343026a613a396509a13993c750a23d21d48e1104ea7332279eb1328281a494a8c15835e4f525212168b0529acc4169fc2c8e23c4c03bb9a2e970b854281d96ca6a5a5859494140a0a0a309bcd646565110a85e8eded65fcf8f1c4c7c7131313434a4a0a8919e91814026a838d31774d67ece81c54824c5f5f1f898989c4a7a560d6a8506acd148e9fca5de347a0d3a8b0256762c68f313e9fb9774f20ce6e7c9f42e32785fefe7e5c2e1713264c203a3a9af8f87812121248ce4a472b4b684cb14c9a713705b929a86f59cac7c4c490939343e3852a1aeb1b98326f366675646328353595fce2c964c699406361c4a81124c698512ad464144d66d6b402b40a1187c3416666266ab51aabd54a666626d1b1b124a425a395656c69e3397ef4304b1f7b94a4d414ac46031abd85ecd13398503c32f21bc9ccc6a69291156aac318964646662319b4849492139391900b5414f425a321a646cc985cc9f3719b34e8dc5622123236330dd43a98f26273305510ed3dfd9c4f17375a8130ab86b54361aad1e9d5e8f56a3231c0ea352a930e80d8442a1416e9bdf1fb83df2233d3d3d830bc08b172f0ecb8fdc82d7365fc2186d272a4a4f9f2b40874b420a4bdc5b64645d791f47ab5cd8d4615a9bfb917d7eec76f8d6d25c260ecb8ffc5dc0ddd787d7ebc51a1b8be27f61907df6d967f9f5af7ffdb1d3ba021e2767cf9fa7fcf415ee9d3d13639485502844381cfeb3af4020707be447fc7e3fa150e88ef5fafe24210a613aba9c044212fd5e09b72f8cd31b62cd1117755d61348a102e5f10a3514434a8d11b4288c270a6f6df0b0c663306f3eddb617a2f7efdeb5f7f22942eb5cec8987113e8ec76fef71fbecd50767777238a22c30eb6efc7a4910eced6f4120ebab029c1160572148425c8b68b03014235b2604046c6ac81b4986192f2306e0f3e31c2bb20200a8a4f844ea6349bcd68b5da612edb07202fc3415ec6f0f26b18c3f8b8a01c66f90f6318c3b85320fafd7edc6ef787ce431ac63086318cdb8d8f1c43da555ac6f8295348b1de0c8677b6b751baaf04973f88c66067e28c9964c418d9b76f1fb5b5b5a8d56a62d23398387112d681945059f271b6f224672fd4200b025131e9dc75d778e22d1ade7efbed41d9cccc711319939b3dc486fbe88112aed636202835a48e1cc3f8822c744a99a69a0b941d3f8d5f13c39cb93388351990c35ece941de6425d3b31a9f94c9b548c4e21b065cb167a7b7b91253f2eb7c4c30f3f446cec4db6763818e072c5612aaf341008c3bdf7de4b62421ccece664e9d28a7a1bd1bbdd9c1c30fde74a0753b9decdbbb93ce3e37a2cac0d86933c94f8aa6e2d4492a2b2bd1e97444c538983c7b0e8e018a86b7a79d433bd663cf9dc0d8b137f98100c78f1ee2fcf973c425a672df7d117e9b2c87696fbcca91c3c7716266d63db348b24551575dc5f1e3e5f8c36072243365da141cb71092cf9e3dcbb163c7d0ebf5e82d56a6de3b9f58b582befa8bec3b52417f40c69a98c3e409c5449b86ea39d79e2de3f8b96b780221264f994a6e7606dd6d751cdc7f887e4c4cbb7b3a69b136827ded9c2a3b46755b1f0a9d95f1d366931d6ff8c03ad4e17676ee3c802f184616d48c183f9de2ec78948a3b2335e0063a3a3a3871e2040b162cf8a44fe56f1aa2d96c262626e64373d9daab0eb3fccded43cafa3d7e9a7bbde8f406fa1aca79edf58895f6bbefbe4b5353137abd1e9d5ac3ad0c06599690140a343a3d3ab5c8e9a33bd8be23c2b779fdf5d707f21cf4a8954adedb45afb5f4a1506b51063b58f7d62aae5e6bc2d7d944c986359cef08d17d71176fef88b86f765496b066d7319c2e27e525ebd9773a4228d5e974e8f57a828d6758bfe100addd812175b49cdfc1cadd67d0e80da80820484182ee4e0eee59cfb14b1d68757a1421d790ef788321ea3a5ce8f40684fecbbcf2f23bf87c3739497abd1e9d568b62e08aa4909faaf307f8ee7faee3d0a143ef6beba6b66eaaeb5b0779630081fe6e0e6f5ac9c9e620dedafdbcb5f534be80446b8f9b1e9f84562d72e5c46ed66f1c7abcb2b232cacaca220392563b782f56bdb19c0b6dbd689501766d79878a8ab343bee7ac3dc09b5b8e2029d468146184908f90c749f9a6b7385aefc7577f84b7369fc0e90971e2d85136ed3d4048a9a6f57a256faf5807c0eae56f72a175681d3232a24687de6040196ce5d597ff84d77be7b8dbde404b4b0b2b57aefca44fe36f1e1f3986543c7a24bf79f308f030fdfdfde8743a921213f8ccd34f62d469a8bd10cdb77ffa0ef004004545454c993215adde805e212049124ea71393c94451d144d2d39cb87a5b69aabe486f4fa443ea743aa64c994294c98cc11885ea3d23d2030be713a5d71076b770e4f8bfd3d3d14a7350c9a59a0e3ef5d3ef63e94ce51bffbe031e1b476969058ef44c1e5bb280dd1bdfa6f2c001ee1bbb843973e6204b4136bf5cc3a8b92389491eaa65b375f94652167c8ee9c5b968346aa20c7a5aaa2e72ece029a67de57b14c75930e887ce2e2d66334f2f7b1c935e8bb7eb221bbff84bc2a1884b6f6e6e2ed3a74d47a5d511a58c5c50774b353b77573169c1fbb96d00f7dc730fa96969fcea859f0f96f5f4f473ea4c1d4b7ff61d328367f8f4b7b711583c8e5185058c2a2a44a390d8bb25c8ce63c781a19cc18c8c0ca64d9b864aa3c334a0f313723a491853c0a45c23672ed4e1f3df348d34994cec58be1163ee4ca6cd988451a7c568d0e3eaeee4d0b14b2c7de19fc8932ff2d96f6fc4b3682261af175d949d3113efa2a9b2973de7428375c48f1ec1a43c53a40e9f84c992c882050e5c7dbd74541f66ebc15348d2c7933ab17af56ab45a2d0f3ef82067ce9c61d7ae5d3cf7dc73fce337bf4141bc91b30dbde852c6f1ecd38f009187a7d7d545e9c637a9558d24335ac1bef56f119798484d9b8fe94bbec492e959b8da2ef0c797dfa2aed3474ae164962e7980d095b75973650c5f5f10e6c517ff83b4b95f678ac3c2ee4def32e52bffc8eb3ffc2ed97615e79bfad12414f399a79690fb3fa4fbfc5f84e8f7fb075d4b3f0c4e1d384cfed445006cdfbe9db6b636d42a25517a0d01673b653bb79337f9010052d233d9b56b073ffbe94f78e9b5955c69e8c1eff7b361c306044140218a6cdcb89e1ffff84794d779289e361e00477c02bffbcd4bfcfb4f7fc22beb76d3e3f20d39078b5107213f170eef45d4c7638d4fa32f20d11394c9306bd0451712e8b90840555f9078a30693de84da1047b0efeae071bc9d559cbd5ecfe89c22e20c436514f656b57075e75a7ef6931ff1ebe59b69eef6d2e90972e0c4190eacf8233ffdffec9d779c15d5f9ffdf536e6fdbfbc22eb0f4de948ea0228846b0f7126362621213f3f59b68f28d89311a8d25b6a868502c6005a52848ef1d1676d90adb77efb67befeeed65667e7f5c585821164230bfc8fbf5e2f55a66eecc397366e6cc39cf793ecff3c89f786fdda16ec7c89288c36224ea77b169c97bf41c762192ce4046560efbf6efe3b1c71ee1e917e6b1b7b28558c8c5e7ef2f22f7e2b90ccc3cf50368b59830eabbabf2fd318da6a04adf0423a6d461443bca418b6236ea311b7474345450b47b3ffdc6cdec765c6a7a06e5e5e53cfed8a33cf9ec8bec288da74b9e367b021bdf9dc7437f7e169766a3d780deb8dd6e3ef9243eca5d5fe3e1c8faa53cf3c4a33c356f21658d9d8455a8f62b0c4c32614a1e84e2ab0635ccc0e1fd117db53cfde73ff2cef23d4c9e1d17e05e70e90436bdf71a0f3dfa5cbc8c81bd110491ea238779f4918778e8f1f90c983201bde1ec244a686e6ea6a5a505887bb057575703507ab81affc0593cf89bbb09d4eda3b2289efedad3dac087afbfc8aef6042ebb602c016f27fb7c66a6dcf8536eb97a0ccbde7c1d80e57fff07d1dc09dcf7d3db8854ed65c3e77bd127f7e6d0ba4fa9d95341b0a584e5154e4a1a0eb3af36464fa344f9e16a3c7d2ee6c1dffc18cd758892bd7bcf4a1bfca721ba5c2e3a3b3bbbc583f93ab8d22771e7f5e701f1742d3939390084dc0d2c7bfb35f6067a70d74d1301f8c18f7ecc33cfbdc81f7f7f1f8ab39455cbd6613299b8fdf6dbbbce77fb6db7f3b7bf3dcbb8de76b67eb61680bf3ef33c8ffff5affcef3dd7b2e5e38fa93952dfad0e6a2c42f9ce55bcbdb28869736633a0770a3a01740204550d4df12148716f72b32410d134625a0cb408c25125b3a6a9549554d3ee33d07ff4d093640d0eb38509d7fd843ffdf61e9c85dba83c548e2c4066fe406ebaf7ffb8effbb3f864fe8293da27e26b67dde2b7585a2a72c7ad176232ea9873d5d5bcf0d2abfcf991dfd3c711e2dd051fe129fe940f7636d256b881eddbb6b163c70e8a6bea897dc5fd9000a30801554353bc089285630a6c7f73258b16bc4d287722375c36b4db71332e99c54bafcee7b1c7fec4983c03afbf149f062e5eb88a59dfff252f3efd30498a9bd27d45a4a6a672d34d370160950486ccba99877ef73fe8dd55ecdcb01591b8f0d3afa8688a1f241320b27bdb7e62963cfefcd473fcf0ea49ac78eb2300962c5ac5cc3b7ec18b4ffd9124c54dc9de78bc9d810307f2f4df5ee0d9bfdcc79ee59f120e9ddd295b5c451febfabf5127317b580f52b206a033e85122f100f6d5457b59b3bf9929175e444e9a034110189d97ccb0bc745272c710f61e06606b8387f10333c9ed35006b5a0a7e773936c7207aabfb5970284ccffe7390761fa1b57835e681b3308a223a5964f6b05c5232fb63305a8885db4e59d7ff7644bbdd4e5a5ada37b621dd71fdc5a49abb7fc9229d2d2c5fb4802df532b7dd711d598ef84b6f304848a2882ce931e94554e5b89d4653a3f82221c2aa86284a18f5129a1297cd1b8d32082246831189185d72faa3d417aee3b5f73630e67bd73363fc10f4a248aa4526cd20b0afb693f6d275987b8c03606cb699d2462fad6dad789b2a30e7c447616ac44b65d57e0ca943199c75f2f4f5927e0924da8cc83a19491240d348b5c85cd43f119d5e87dea807bad72b16f2b26dc57bacd8efe69a3b6e65404e2aa220a0d349c8b28824ea31197468d10886a441dc7ad5349212ac489284244988a27092bdec8b388c12f97699ed551eda4b5663ca1a8d2019f03757b0e095d768b50fe48e1b2fed9a921d43d649e8741282286336e851a3f17be10b2ac87a3da224226811d458775bda05bded64275b907432b25e024dc5ac131898626063851b57c5060c2983107466c2511545909064095927a084035f2843ea2a231a0bd0115140103119f408aa7a3ccfd4bf992459a03518c313f4d351753c52a920084743b5746fbbde4346327d7806cb3efe8446970f4d8b87b489cb46448e557ca05dcf817a2f3e4f3321970bd9948dd12831b05f842585d5d0eb1a8674ec63df86830cbbb0f79796f95d433e5d6fd0579e7992dcdc5ceebcf34e162e5cc8a44993687336f0f45b4b7164f761de937fa6a0772feeb9e71e562d5dc6e6cd1b0906fd58b20670edac0b0906832c5cb890db6eb99a8d2b97b266dd6e624a04737a1faebc26be92f4f2b3cf505f574b301462e0b499e4e4f7e8568767fff11e1b4b9c04c437d9b1f42deebefb6ef27be671dea4e17cf0e40320eab9f1f69f0330e2f22bd83bff6dfef2a7c748c82ae0a6abe33183821d3eea4a9d0cb9ea76cca7c8393fe9c6db98f7ce0b7ce8f6622b1843fe80be24db35fa8d1ac1ab8ffc1a5f30c22537c7ed439f7efa29595959a42425f09757df236cca409bf737362425f2ab5ffd8a9d3b77b27cf932c2413f923d932b6ebe015b7e1697e70f07e271ae43a1100372b3a9afaf67d3a64d5c7ffdf53cfbecb36cd9b2858a8a0a7ef0831f70d75d773172e800c6cf98ccc2671ee4134de0aa1befc168d2b162f976feb17c13bd07b4f3f8eff73169e244e6ce9dcbfcf9f3993b772ea5a5a57cf4e18784437e302571dd5df1289d37df7a29f316bdc4da77348c198318347a14adadad7cf6d967dc7cf3cd4cbaf9fbcc5bf0216bde6f4797da975993276072589972c54c5e7bfe777c8ec8acb97790e0303161e248aa6adee28fbffe1f049d89efdd7e370037dd328b79efbdccba8547cb18330a77cb11fef6dc9b0443212231854b6fbb11a3e5ecf8c64d9d308457df7897dfffee4fc40423b6a3f1871c0e4797a3b0d56a45afd723cb3239bd0731e7c61f60fd603eaf2d5c4ebf1c739737b5288a388eca48e6dc791d7f7b7d310fac8d92d86310974f1b8b6cd2933e7c2229471ae93dba07e6b6549eff4ce392bce3651e1b14582c160c6769dafa9f86e0743a354551301a8d9496967e6d71edf8f1e3b1dbedd86c367c3e1f46a3115555f17474208a22a22020cb3276bb9d402040281442d33474061316b309010dbfdf8fd56a21140c100c45baf69bcd266451a0b3a38398124343c068b26032eabb4da9dc6e373145453aba5464b3d98e2ae683f8fd413441c666b7a293a4b841d2ef23148921eb8d582d264441405514027e1fb2d986513eb94352d518bece786e36bdd18cd9145f258c4642040241144dc062b561d4cb0402016459461445dc1e0f8220200a02a22862b7db894422040201344d43d219b05a2d5d8a7e80603088a66998cd6662b158575485cece4ec2e1309a168f696cb3d9d0ebf5c4a261fc3e3f0a1236bb0d9d24120c06f1f90348a2802008180c062c160b5eaf178bc542341ac5eff7c7eb20ebb1d8ace844013516c6ebf5135341673062319b408b47f68c879d50f17bbd44620ab2de88d96c4212408945f0797d2848586d56f4b2049a42c0ef271c89214832169b0dbd249e5486d96c4250a3747a7d7143b62062b1d930c8d2594904a0c622f8fd7ea20a08920e59d4b0d96c74747460b5c647ac3e9f0f9d4e872449f8fd7e1c0e07d1909f4014f43a092516c36ab5a2280a3e9f0f87c381a6c6f079bd4414adab2d45201a09e20bc5b0da6c88111fbe908ac3e1401038a94c5996bf7539d7aa55abe9ddbbcfd915d7ba5caeae07f79be07038bad4fe27aafed38e064a3f11b3d97c0a91a0d0f5453299ad984ef151b47f8570f158e8842fa23798d11bba9f501044cc563b5f2c469424acf67f5e8e28cad8134e2e476f30a1ff42ea9713af31f51499278c46e3973e64270a9c6559ee6a57bbfdd4c66e9dde484252f7f39dbaade96a6b83c170ca7b2dca061c895fdc2e75d54110c453b693ac339090f485e304198bcdc117c7dea72c43d493989874f2c59d0544598fcda13f69bbe384e7eec467fbd8769dd182e30bb7f1584817004194b1394ef5cc98e96a2aa38d8413cef1cfcafcae21dbed764c26d3392ddb39ce718e6f9dd3b6217d17d1340d555141d08e2aa2c5ff981c63e738c77f03722412415194efac11ed9b108dc4a8afacc5af34a337d9c9c9ea15b7839ceb94ce718e3382d8dede1ed7727d433fa4ef22a228e00b745056b4976deb77525bdd744e947c8e739c4144bbdd4e7a7afa37f643faaea1aa2a1e4f071d5e17769b19212c50595c83abbde35ca7748e739c214edb86f4ec2b6f72c165731957703c5347cd914a5e9bf70a9da128065b2ab3aebd8529837278eeb9e7282a2ac266b3913f723473afbc9acca301f555c5c7aa159fb07afd1e5404ec59fd9933772ec3f293f0bb9b59b9f85db61557118c6afccfafeea3678fdcaef2defac7cbec3e5082a8335230661a57cf9a42925165df96cf58bc7c0361430637ffe0fb0ced914a2cd0c29245efb0bda481ecfe63b8e9fab9a49a659e7cf2499a9a9a50c26e1a9aa3fce99187e95bd0b3ab8c63be41355535d4d7976336f94949d7137005692caf65657b3bc3ce1f44c1805e180c0604045cae565e79e1399a5c5e449d89a9736e62d679fd11226e3efde85d36ed3f4c72de706ebbed3ad22d3ade78ed25366edcc8a061a3bb525a1f4389ba78f3f5b738585a83264864148ce59a39337048115ef8db131c282ee5fb77ddcd8c19dd75703e6f272f3cf304fb0e1471dd8db772c5155774db1f0a0579e9d9a7d8b97b2fb3afb8921b6e886b0e3b1a2af8e4bd85ecaf7583deceb42b6ee5d271bdba8e0b7b5b58fdf142d6edadc696de871b6fbf993e6976a27e270b5f7f9dc26a1705232773cd9c4b48d40b3454eee6d55717e2c1c6ccabaee78291fda92c2962c1fc5728a9a8e299679f273f3fffb49ec1b3c9e1c38759b468110f3ef8e0b75d95b3caa996f85555edf62feee97e666658d22f7ff9cb872291089224d1d6d6f6b5b38ee4d93c2c7c7f1797cd9ad8b52fac882466f7e2b29917936570f2cafcf5ccb96c2a6fbffd36175d7411d75d771dc3070e24d16c3cc19f48202923973163c73161ec506a0face750451b13c70d67db074fb12d32809fde712de70f1f10cfcca13bbe4ceb51cdccb8683ae306a7f1d1db8bc9cccec316f3b078d1bb147cef279c672b63fe9a20974eee4ff127aff3699dc4757367d272681d87da331933208d7efdfa316edc3832a24dec6f343171fa34528faee96a9a86dbe5a170ff1e5c6d6564678ba4a6998845c304023e02ed2acd477c1c2a2c231809919c9a88d16424a609488e4cbe77e90c46e6c1b3cf2de1928b2753b36109cb4b3ab9e2aab944aad7b3ad368df143338860c0e248a170df6e66cf9ecd89088248665e5fc68f1fcfd821b9acfbf413f48644fa16e4a177a45353578fc36e3dc9774c052473126dae0e044d61ecd8b1ddf66b9a806670e00f47f176b89938317e1fb7ac5bcfc6e21a6eb9e75ef26dedbcf7c1462ebf746ad77125bb77b378e556aefaf12f1990e866fe2a0f33cecfa7f0dd17d818c8e6e6cb267068c73a9c915c06641bf9f4c5bfa04cfa21570f0cb160d961460c1d80d962242db72febd6af63ea94c9a4a57d3b51399d4e278140a0cb4faba9a989848404cacbca0877b6515dd7446750c56cb1e06c6ce0e38f3f66ce9c2b703b6b68ee8c108b8669acaec4e37651dfd48660b46331c8a84a909a2387a96b7012886958ac16c21df5347824ecc610d555e5444523b2aad0d2d080607350535941a8a3959afa263a02314c16cb491975cf36b5b575389b5b70bb5db4b5b5e172b9f0785c783c1e3a3b3bf07ae3595bfc7e3fc1609040204066663a2d2dcda79d75e4b46d4826a399881ad7ffecdebd1bb7db4d7a4a0213470d2233231dbb35a16b3f407171115bb7eee048631b5155231289b075eb5604514772423235558759bb660dd5ed0a3dfac593387ef4c136b2ec3eb66fdf854bb0237cc1b768f2a881e4e566919c98029288a2a934b983d4b9c24c1b5b40ff4997d354b80a800d45cd0cc84f63e0e001a4e5f5a3b9782300c9b8b6b6a30000200049444154c9c9a4261928aaf5d077cc00b2b38e670b0d0543ecdbb39b70b08afc5e66ac163d9220a001a22e46840e829d617cf531562ddac2a635bb080682d8ad66a68e1d4256463a898e64a29a0a686c2f6b253b2381a183fb933d60340dfbe32991c78e1c42df5eb99c0a413490929048e1de3d7cbe7a0341399994ac6c2c161393cf1f4946eaa97d788c060393ce1f45567af229f7eb743213cf1b416e6677bfb19eb969a419226c5db7865d8575148c1e0f1c7788f586a2289a405e563a8e84546ab72f0660e5de06c60ccca1dfe061d853d269add84938aab2b1a495aba60da4ffb89974361411f6b9c8ca4863c2d86124d8bf5d7f9b77df7d97254be299640f1c38c0e38f3f0ec02f7ff94be6bdbe800f17fe83879f7891e28a26003435466dc90ede98f722abb615b166ed5aeeb9f7177cb47831ff78f9695e5a180f9b53b36d05cfbcf8326fbdf90f9efffb6bec2f6fa5fed0473cfcc21abc559b79f2a16b7871c356ca4b0ef1e2e34fe08c28dcffbfffcb4bafcde7c385f379e4af2fb2f750ddb7d32827d033af0746a38e4838482c1626160b138d845095c8d1ff47d0d428b15818b418793d73494939f5f3f675916db6784eb36fea87b4f4f3835c72d54f000887c3ddec289d35fb79efbdd5ccb8f287004cbf64362d8db5b43b8fb063d75ea6cdbe89a9a37b10891cd74b45c261bc9df19e57678c4f230f7586b1d7b521ea0fb36e7b29bfb8e7767ae574bfe088af9d558bdfc792d98f9ebd7ae3aa2b25a841822c11d0a5a245e32245574c234d1231480604c98216ab3d5edfda72ea9b3b187ade886edaaffaba7a3a3cd514f48f3b268a92000868aa0602448420ed9e00aa57c61709b3edf342868ce84fef7ef1299fafa98c05af2d62dc8cb9e88d063c8a864d14314a3a44d9de55b7afe258e6508fab95505842d6fffb3c788d7a8948248acbd349c4d54a626efc5e4422115455a5203f8bdc4478f6e9a730e127e08b0b9e5b631a6365115932228a06b4980795a3edae93114946537ca74c03fe9f86a833307cf62dcc1e96cafdbf7e98d6da72b2b3923972683f6f2d5a42e6884bb9e69271ac5eb9828482115c7ff77df86bb7f3fb47df851f5ec2e20f5631ecc21bb97a72017fffdbdf39b07327974d9b06475ea3a87004bd3353d975c4478dae158f7104f9461951d631e4921bb8f2bc5c7effd063388f1c82e179df6a3b646664909e96f6b5fb065996bbbdd3a78368b55a4fcb2972fcb57770e984f8906bc28409242727a3a90a6d95bb79e1c5b7483eff32aeb8209e0e7ac645d3b9fd8e3bb8f9d65b49b34b14edda8c5eaf67ead4a971df1e4d63cad4a9dcf9c37b183bb40fc5dbe36affa1e9095c79f535dc7ac7ed743694e06e69ea568788dfc3868fdf6243ad9e1b6e99436e5a3cd6925584e6509468a016c9141f79641924dc911881680035ea4132c653406b6a8c928a1a3a041b234674b76534363460322b889280280944220a8aa2a211ff3ba64670793a70bb03043aa21c39544f5b8b1b4d53e96828e38d5717d091793ed75f3616832c91ae97f0c5147cd1104ab8adab6e5f465ce22173c59cb9fcf8a7f7926288525751f48defd7d7e540692d615d0277ffe8475c73f515ecfd3c3e029a30610249494924f7ecc38d77fd98b9974c63e4885e58120701d0c328d11a8e1189fa50940092211d49804c83447520422cd488a84bec4a25fd9f8008289a86a2aa2891e3297f7492c0882c2b92210951d681160f7ba3f8ddd4b778494e4bc1a097d0348d3e4946326d7a74965c34c505404320466e92118339019dd58a127163356730dc5ecf73a5516cbdefc27eb010e7ce35a44dba00498827211d916545d22722ca4650cf5c7aead325168b2108029aa6210842b7bf8f71e2b633614712239108a150e81baf14f5b082aba9018086860682c1206df595fce5b1a7a811d318da3b1df7d1fdced6160e95945054b8178fcb4d527a3e8aa2505b5b8ba686a8aa3bccfe83c5141fdc4f7b4b0ba959f18eec7b53fa71a0b48283fbb6239b92309abb4b17d67e308f673ed8cf84e913907ded04fd7eb252acf44ab3b07cf576b67fba985ee7c58dbd5347e55179b881ad9bb651575949dec8290044fced541cdc4c7aff8bc9ff828c40d33454554389c50887a3082220413810251c8ad2e1f1e3f506f17606f179c38423313434fc9e565e79f629b636099c3faa1fde9646545565dcd05c5a9c6d6cdab49dca03fbe87d7ebc6e959595545454d0dede4e6161215eaf976030484343039ae2a3b8a28c83c5c51cdcbf939822624fcc261c0e73f0e0419a9a9aa8adada5a4a4044551686b6bc3ed76138d46292a2aa2a1a181fafa7a8a8a8a8846a3b85c2edadbdb51148543870e515b5b4b535313070f1e241c0e9366b7120b87d85578908a927d2467f6eb768f45498f684ac66836d15c7c80a133e3c6f24bc617b0afb0926d9b36e16a692367d0f9187412178cc865d1c79bd8fae96292f38761b427e176bb292c2cc4ed7653565646555515df067d53acd43a5bd9ba670fc53b96756d17ba14fcddfdcb7a8d98c45d574f65dd9277d8b4af8298aac6b58a5ff8edccc13d58bfbb949d5bd6e169759392331c835947de48037bf6efc7366c3ad32c87d9b4b596699373beb4cc6f1383c1d0a59f3c66c03ef6f7b14ee9c46d6742ed21dd71c71d0f0583412c160bededed5fdba8bd6fcf1e3c1e0f43870e65cd9a35242727e3ee0cb269df211c6691baca32dc6e3723468c60f7d6adacf97c15c5e555f41a7311b32f9d84a446f9fcf3cf193ca81f457bb6f3f9ca3514971d2663f064e6cc9986452792905f40d19ae56c2f6961c2ec2b1833ac6fb794c68b576e4636ebe96ca8e2d0a1620a0a0a48ef918723c94cd1a6d5d4c572f8fe2d3348341b49c8ef8de4ae62fb9e6252fb4fe2aa59a3d08b02117f88faea76865c3e931ed6ee1d522814c6d9548b41af128b2958ed46fcbe10e16804a7d345d9a1669c150a11bf40381a217f481ad32f3b1f51a763f9c65d38ec069aab2aa8abab63e4c89124e5f546e777b263e73e4c3dcfe3a639e7631005de79e71d8a8a8a30180c1c3a74887efdfaa1aa2a3b77eea47fbf3c367dbe8a4d1bb7525ed3c6c80b2f65ca8461043a3dbcf2ca2b1c0bb0575b5bcb79e79d477171315eaf179bcdc6bc79f3e8ecec24128970e4c811c68c19c3e1c387696969212d2d8dd75e7b8de6e6665455a5bcbc9c91234792d72b1b39d2ceb6cd5b698d2673fd9d37906e33b07af56a525353b1d96c141d2864e9920f21630c775d3319934e26a9a01fe19a036c3b70843e63a673e9058331e875a4e4f7a462c3328a5a8d5c79f54cfae6a6525e56ca9b6fbe89c562a1b1b111bfdfcfc89123ffe587f99b929d61c75d5bc9ee03875152c630b0573ac3860da3adad8d912347623299f0783cf4eedd9bc4c444540d2ebdea160a6c7e7656b8c9cfcbc261b53060c00062b118c16090d1a347d3634801cee21dec3c584befb11770c945a331eb74a8860404bd8519178f233f2382c7d89bab2e188f20405b5b1bc3870fc762b1e0f178e8d9b32759595967bd4d4e24180c228ae24923a463db80933aa363cfd269a7d2aeababd38ed990cea5d2ee8eb7d3cbae9d9b0885ead0eb5452526d6868048361f6ec2c65cdb20a5a0e5a11a306127b18b9faeee95c71fdc5d81db6af3ef939cef11f8edfefefea88be0e9224118d4659ba74e9e9abfd4fbb53d182a0fd770b722d5691a1c306515c14a3aeba92863a0f89c9665cae0e0eecaba5a93a88de9040af610e665c379669b34661b50aa07dfbf3ff739ce3f411413022cb32b158acdb884810846e53b613a7746742422547a3d1d3d3b2859f06e9ece7fe3e9b8840b259e3bce1117ae564505c9a456b4b33ad4d8dd8ac2a175fde8701037a31794a1929a9eb3018b62084ff736c00e738c76921f607e34f0887c3c8b27cd294ecc40ee8c429db99502cc86d6d6d689a467a7afa57fffa44340f68ee7fb902ffe90880510fb9595e72b32a4ed8a303dcc09eee079c93049ee3ff7b3a01d0ebf5288a82244927d98c4e65d4d6e974fff48c5f97d3f643faae12accd27dc1443d4eb30f6f4a24f6afdb6ab748e73fc5b38d6099db89cff65cbfe6782d3b7217d47d0344091f0174671bfd784eaf4201992508150ac0e698083ec5bcc18d2f40842ecab4e778e73fc7f432c16eb1a1d7dd166f4459bd289dbfe154edf86f41d418bea712feb83ffed9538c65c80e9f24988361b1a106b6fc7bd7e1d150f95917bef2812faedfbb6ab7b8e739c310c0603d168144992baec4327da8ce27e7ac7a76cb22c7fc519bf1af9eb086a4fc5b67d324386f726c372b86b9bc7a3b07b4f80602486cee460f0a8bee4d82ad9b5a79d86260d59d691949dc3e04156ece271afebfd07dc54d5c4d0e9f424a467306458320eb19e152b9b50d47800b4dc4183e99fe3c220f8bb8e2bdc1fa2b6298820e9c9ecd59f41f91e8c929796a630078a8244f536268f95b01c0d555d56e4e770a34a6aa69d3143e2bdf9c62d5e3abd2a6851022195e95393484e3cdeb0febd017caf7c42c6dc1bd04f9d8ae0f74367270802ba8c0c0c575d8d7ec912aa9efa88beffd70b4bb64620a0b263a78fd6360f634627919f171f8516977450561146af37604d4c62d8985c12c56a029d09ecd8554b403330a8bf89bc9ceec6c18345610e1f7691922a33717c5c7be6f367b3755b2991988226e8e83d6830fdb26a90c4f8b1d5851eaadc212e98dafdbe3a9d310e1c0c1056544cf654868fca21c91060dfde169a5adc68824452662f86f48d2229ed6cdcea4351002d8c86c48ce989e8f5c7a7f7e180405989425d8b07412773c1442b26637c7f24a2f0d9e72d884773e0e50f1f46df7437ad4e23fb0bcb5001d96867e0d05ef448aafe46cfdf99a0b131c6c1623f11052c09e90c1b914ea221ccae9d4db4ba3ad0048994ec02861484502216b66e294601344147c190c1f4cda841145582ed118a7cbd48930ed3dee667e4f06f2746f899261c0e7775465fb4199dca0fe94c18b5459bcd466666e6378e8774706f026f7ed43dc87d7b87833d25b93439a31cdc6b67febbf107f1cd85d56cd9e6c2d91ca5bd532646f7e33e585cc7ea75ad389ba3b47924a25afcb8279e29a5ba3684b3394a47c08c4af73aee29eb4b6d8346cd111d6fbc934065b544c81361f5321dab8b2f62ff96243ed8180f9dd15ed2c95bcb73283a3c85559f5ad95a9a0d405b7b0c677394f29d6e9e7b3981bae6ee3a31d79b4d24a6f540dfbb37425e1ea4a54173330483909b8b909383233919539584f3f3b83d291032b0ff504fde7ca79aaddb8febd556ac6c64e90a27cee628ad6e818816d789ad79bf8315fb275357379e8f37f4a3a6b57b50ff43877bb1734f9017e71d37aac71413cd2d519a9aa3d454a5f1e2eb02c1a3897d431d565e5a98c6a34f559e74dfea5ad238509e4a63538ced9b137877991130e0f108389ba3d4d79959f481837d450a31059a5ba2389ba314af6de5d9373309868fdf03250ac5fbcc7cb43691a6e628ce9628ca09cf6430a8f0f833a5389be3e7f0862ca8e808860c3435c7ebbe7f7f26afbff7ede8db6a9c19145524d3d81863d3860416af340026dc6ee26d516b61c1bb564a2a54625123cee663ed9dc94b6f4038127f294b5634b2b96a227b0ef879f783da2f2ff4ff238ef509a7b2191de34cca46e05fb0214d386f08cfbefa3cdc9c4524a222cb025999317e709b81246b1a3515417ef5c852b8332e34bd70aa8dc9139390756e74a21b4dd38844350c47bfb6532658b96c561292ec432f950360b5885c332711bb5d8f5e5786f405bbd9ec4bc224db5250c322bf78600dad4d26ac6185e2f21caefbc30f496959cbaf9e5ec5ad3360f33a27d6dcebb8e39a997cfed102d6af3fc8f8fe30f7f244340d56bdeda7da3e91e4ec3a203e7a0bd6f682f243987ae420ecda05e9e93078309c7f3e9ad98c6630107df34d94050b30d5d5d1b97f222177120e4727b7dd2ce3f79eac7c3e7f8c851baf49429262e8a56200966f3ac86d0f3fcaa81e261e7cf45daa8e54d0f30411fec5d322f4ef95ce5f9e72766d4bb05772c3b58984232a6db5e9ac7bbc2e1eab4681651f78481c722dba23db4e2abf7f41947e7d8cd88c29ecd8dac2bcf7f6205ed98369176884c3c9785dc9fce5053fedad1e1ca3256ebb31054d83d71f6e61e23533d0195701e178fb7823ac5b1661c82d97302bcf83acd7218b316231ad6bb1312941e2c66b924010d0eb8b9104e89d0f3d7252884655766fb1f3faa7a5c0d90f1038684084c1034c58f4c9ac5f5bcf479f3b112fcf61c6c5100a27e36d4fa5f8e94e3adc6e92077772f38d2944a22a6d35e9dcf764d5d15840029f14da99396a336d757161692caab272898fcee4815c3541e5b3652eb61ea8c196dd9f1b6e1a4c9e79138f3c5642414a1efbaa5d38fa4ce4c6ef05c9b275b0677b221fafda8ba5e7585cd5eb78f8819e2c5dd1487a9a812993d2d9bbdfc581220fb7ddd40b57fb7016beb5855a57983e632fe4ca69f5b4d455b2e05527b9d969840aa670fb94462a0a0d7cb27217117d3257dc7219e37257b2f0fd6adc5526bc8604f2c74d4668ac222337c2c4911d1cdc57ccbeca0f9973d5a548aa7256fd90c46834da95f3eb9b50b26333bd478c06e0fd251e1a9a2298f42192aced44432207b678e935e27c0032d28dbcb7b89307fed0ce1b1fd868f78884422a6f2e6a07202dd5c0f2953e1e78a895d716396875c53b299bcdc8a37f75f2c09fc2ac586726f8051f9f34473382aa72a4d08f64e88323350d7748a53da2d12fd98c357334e1b6b85da7b83d4c8f041309b6048c8e1cc2edc55de70977caecadebcfb0bc5232adc757cd42352ab21f84aa2a58bf1e9e7c124a4a203f1f929288befe3a91bffe15a5a808b9a38358bd42c8ada1936224da4e5e7d4b4ed2b3617380df3ce4e4f937ac34b7c55fc2c15949ec3c5046597121f5454b89059cdd8e4bb4b5224b271bcc0f9586b8ff810aee7d682da3665d8c5e6fa26873842a691a93c60fc3209ffc92db4c5eece60e829d02657b23148c8ea7438f44349e78a6815f3cb8158f318dbec307741de36b36b0a5650433fa6ec4281f5773fb230aab7616b1efc3fddcff478137d75f4c306666e71e3f9bb77a1145019d5ecf6fffd8c8838fc458bbd5c43131f8eaf59ddcff9b12feb6b0880baeee1e03ea6c613775623379f1bba1f28046ef11a3000804551e7da28e5f3cb885484a4f7af68b4b1cf61f0870ff03e5fcfcf76b38efb219c87a1d1d75313a7a5c4e62821f5150e9f444787f818722df28260d75b17f55215b2a0ab8f486a7e921a7f0fafcf82877db3e2fb56913f8c16d7d682c6ba1aca881f60617cb3e74316ceef35c3eb43f07f6b6a2281ae5955eea1be2e9c55b5ac31c2a892fcb2f7f6135e1ec9b993ef566367dda4865791b6e778455e5c9e44d19c975e32af037d6f1c9876e86cd799eef9d3f85792f94015056ee659d7704332f4f66fac062683dc0aed261b47a9239b04dc46d2c408b46ba7540a73260ff5bfc904ec7865429e6f2c0edf197fdc66b8ecf99233e99b5cb74aca9cbe70fbfa806e081ff892bc2fd1d2a4f3cddca5b7e1d3fffbec49db7c487013ffb715cc019f4ab3cff6c332fbf25f3db9fc9bc333ffeb23455c5f8e9ef5d6467e81939f8b8fd4255e04891917f2ccde0e24b638cecd7c9817d2009105535d0c208627c0aa61705629a86aaa9a02908e271dd5a4d899356cf30a68ccd40164ef02bd2e9504221a8ae46331ae3d3358301a2515055c48c0ca48404b49616044d439365f892a9ef1db7f4e68e5b201252797b411b7f7d49e289dfeab8e9179378f3edbff2e1e15e3823a9207c3dffae21834c3cff747feacbe0278f7c44c7480bcb37a5e3324429dbb59926a79f1d4556860eb260129abb8e0b75e8f9f87d1de56a3e8fdc7204008341e477bfcec5d3020f3dbe9bd27d028333e3b6b4dd9f9761c9bb99ec9c0a44a1a3eb3c02604ece66e60f1f6110c57cffbebf33737084f1e71d1f757ff876fca3545f11e5a77f74939fada74fbec8cc8b1cccbcc8c1fa4f55feb16809378ffb761655821e3d1fbda7a7c198c61fae8fb785c52cf1c7dff5c4ed845fff790b55a512056912a3475a183d7200b5c5f0f3bf7ec4dd17ea295ce764604f1769697018d8bdb60dbff97a7e7f5f1b3929013e6df090939dccd8e183c1e764ebdbf7030331e9225c376a3339d9668c622191402aed7e0b75c118ff7bfe404c5a0e46eb735f5af78f761f22cfff14ad261d49d63089d60cda4230bac711660e8f8fce0fd4067146547e7dfe20146f22aed7ae05e25126ae1ebe9da147b3415f7c612f7ef3869b7d8531761659f9f98f066094d46e2b6d7016fc90ac562b168be51bfb21dd756b0a4643f7114bc42fb37a998e5565bdb8f9ce2cac963a4ecc7bafd34bd86d0a4a2404249c5c1959c491a0e1f47502c73b39ab4d8f5ef28062038e3fb8ce0a33af7f68a2dfb4114c99580ab491629649350814367ac96eda8829eb3ce008a332cdac6ff6d1e66ac3d77a1853e648a01525aa515e6f434a82a1592dddea63eeeda3d51641a9f4210d1d0af7dd079999f0da6b909b8b3c7b3662388cf6bfff4bb4b515312f843939fc956d274a220909224a5d07904242ea617e7a6f322d55015a5afb60487272cc39edeb604fd023286d08229c37a89103ce83d457450804fcb4ba75dd6c76218f9e8fdf17d9d73180bb7e60068e743b97d1246134f88f862d9289065476d4a5d3bfbf8b745b77498c492732ab5f22497623462d118108ffcc33d4ee3020d38ca63980e31f0347828c1a7171e27d3d5b04dd7a3e5c24501a1bc48fee9039a92dcc12065d182d26c10929461d497a88b5a1c432d8e71f4a7e7a050972dc0e3664740a43d30fb362ad9d3be70a649a2476bb43b477faf13b2bd1594f16941e6b33b32460d5342adb82e407f7a1847d0024ca22add151784331bccee323efe1d9098cbc660a978daac1df998ddee8a1adada6db992db280495139d21e24b9ad08c9d893783cd1eed8f393182eec60d5672ad2989fd3dbac231088dfefb3ea87742ca3e93765fe0b4bc9cdece48e5b5258f4a18b89e3acb4393bf9eddf6ab1e70510febe851d79117e7c671a2b3ef3b2799b177f404175cce0da4bf504437b79f74317b7dd98c2da753e566fe824e08f12b34c67ce5589c02e5e78a99d9a7a3f3ebf99cc11d7909e7b10387e439e78b19015fb2d4c533d94acabe18777a4d023279ba1c3f258f0e86fd0a97e6eb936def18dbae422b62c28e6913fec263121c8adb7c6474e414f84f2bd3afa5cd603abd0dde662486d8251bdf01df6909498082613bcf926bcfc32a4a723984c88090944ed76dc7a3dc6e146f4562fcd2d611ef96b15dbb6b760b719282e8df1bb5fe7b3776f9815ab3a0804c38475e3b8f4cadec0667c7e9567ffde4c7d9d48ffb1c90cec1da3be31c296ed3eae9d9bc4f3afd4b171731b7bf777f2a39f9770e7add9e4e54de7c51797d3190c120aa73161ce6dd8b35631ada78169409333c8fec226664f72036ede78a79d39b31d6cdbd2c61fe739c91f1ae3ef4f34326684cc35574e62e13b15141e3a423862449779190346b6011538cb3a69f70f64c4c0187a21de496ed8ecc56814183dccccc80b62cc7be441227e3705932ec662dbcaf65dad44c21a63475b78f16517ce563f3ebf8d82493790985ac281a20416bdb792482c4a5818cacceb2f02569ed673f8aff0f9fa06fef48f16fa8f5479f6b17a268cd573c5e55378e3f5039454d6118e9831f49c43af810d343627f2e20b1f138ac50845329872d56d445b96a21af3b1f60d02870048eda1e796eba22c78a793798beddc307934858baa78f8b70f20ca7a665d7ff93fbdd6b4cc14c60c4be5a9dffd8aecec1eb8fdf18e63da79fd78e9431fbfabf0d2eee943a62d1ed6e7ca5b6ee0a50f2a58f37e35aa20f2b3bb4e1ea164e664307a681acffcfe7fd0a941a65d7d05f0d149bf13a867f6f7cc7cfcf061fe706ffcfc277a697f513af2eff243125a5b5bb563c3ad929292afadf61fda77250ebb878c341dad6d51ec3689584ca5be29ae7f1105301a043233f4b8dc0a9d9d31540d4cb60492130524fcb4b5c5484fd3e1f128783a14544dc568719092ac432ffa686c8a128ec403a2d9935248b406904e703eacadf3138e4ac847addd19e93a8c463d01bf8ef67637aaa8273b434427838619777b904e5f1893454ffad14cd74a54c5d50efa641b0e9dffa4ebf5572954fdb49a9cd600b6dc5c24af17bc5e1004484b231c8d52e7acc7755912c3efeb85de0a91884a5d430825a682007abd446e8e11bf4fc5e5890749d79b6ca4a61a31885e1445a3b1294a4c15494ed663b7a884c32a9d5e85d4141d8dce307e7f0c5555914489f4743d4643024d4d2e1455055147727a32367d0782107f286231156773889cecf897bdb9254a72928ccf17a5b92dda758fac1691941407ad2d41fcc1102060712491e488210b212281186e9f115b928c598e2fe375742a8802d86c1291b04a4b4b8c88028e9414122d3e7cbe289a0636ab4853538c48544113241252524830070906645adbe20b1b92de4c6a9a1d93ecf9971fe66f8adb1da1c5154327490802d8ac12c9c9765a9a0304426140c09a904ca23d8a1a95696a6a47d5341075a4a42753b7af8a8a72b8e8c60ccc52189f3f4a20a090966ac4eb56f1293a329225dcae289dbe1092c14c5a9a0583d849436380b454233a9d484b6b08b349c26231e0f7c9b4b577221aedfce8c76b796fc17998f4065a5b238414106423269d8fb454238a62a5a5d943301243106532d3653435464767948cf4f8a858d344fc3e99765727aaa023352319abde436b5b08835ec26e8f77629e8e18c56bbc7c503781877f6cc09a703f9148e42bfd904e346aebf57ac2e1f0bfa4f6170e1d3aa41db3219595957dfdf02353d76135fff76bd954d580a76820b54fbd8fad46c02ecbe8753a544d23100ed3220b44278b8cfd6dcfaf3ed939cef10d78fce943fceceebe188dffbac3e157b1667d074b56c5b8ff9e0472734780f13778bdde9396febfcc535b14c533137ee4746c48df1544314cd2d07de8fe5080736d1b2d87d3513b74289204292d98078ae4cff8f7c5b83ec77797fb7f31f0ac95357daa83e953bb6ffbe2740dbedc0fe98c841f395d1bd2770d5b4f0ddbedc904db1309b9550459c29c928edefadf1d82e51cdf5d2449ea16571bbedc0fe94c20c762b133b664f7df4830644251240c06059d1cc494dc8ae95fcbf4728e73fc7fc1b7160f4951946fec87f45da1b07402e1582fd2929d64a5acc2610b7ddb553ac739ce0a0683e1ecfb21592c967336a42f213ba3196f681c46731f6a9d12a1863a2231055192d009610a72aa70587ddf7635cf718e338ea228ffd466748c339d06e99c0de92b484baaa0ee500356fb489cca45786361b21241274b449428db8e6c6352dfe55810efc8be00002000494441548cc16fbbaae738c719e5443fa4afb3ca7626386d1bd293f3ac4c9c3182e9fdd7766d3b52a5f1ca6b1df8231de8cc795c38773ab386aee6b1270f515a21929860217fd458ae9a9b4196743c76d0f32f95b37d7794d4143bb9838772f57505e4ca3bf9cbd371657c34e0e370838ea71eebc18082e35ebeff783dc6bea20604d94a8f11b3b969563569a606766c0af1e14a9598c1ca8f6e37d13f2f48341063d1c220bb2b65f27a3bb8e3067098233cfe8c9326e73f2f0341477af26e96efcda15d9fcd809c24da15f00663a808f885e9bcbc26cc4f2e5a85411ff7d2d65468acd6b3e49310958dd598ec267e775f3adb76fa58fa6907aaaad0eef432627c0feefbd1f15c73bbf7a8bcb3b09ef2c3d5bcfad2982e5f927befdf47306cc76cd233e8828bb8e2c21829d27125ff274b35d66c6c4093f464f49dc6359747493794f2fcdf8334b43423c8498cb8f04aae9bb28515cbcb58f4818bdc9c641232b3b8e9c717d35bb7265e6f6cecdddf8377167d4a0c108dbd98367b2c978dde8a1286d52bacacdd5d8e2f1ce6daabd3997cde71efe5eafd26162cf6d016543024e573f55c1b63fa54505311e6c5f951fc98b96a8e9589a343e8a4ff8c38bf3b776abcb7b8958812c1923a8c39d7f667540f1fafcedb47c9e10654cd48729f0bb9f50a17ba581acffc6d311140d11219397d26374fdb864e5668dcede67def550c943ea4f880937befe9ff6d5fda19e15b8b87743a36a42903f378e3c5a54c7fd6d2b5cd9e94ccf577f4a34f7a09478aed3cfac21266bd6ca5b129c87573b39834210d51766210bb4b349ccd21665f92c06533b310650f7a692f003ffb511aaaaa51bcaa8997b65f82687502c7c3790c9d309a39730c68413dbf7d742be53da248e96136accd60ca9d0fd1a3e9039e7cdbc7bc078b295cd64851f826eefed934b62c7b833756a8fcecaa1a7efac37f5e863f98427be730aa9c46b63758508d61ac5699b29a202dee08a2008a2ad0d03c9a51694ea68cd90540a023c667cb6d9887f5e14f3f887f5d8c468149e36d9c37da42c01361fed3a9e87bcd0036775d4f56cf5ceeb93797fb7e5543347adc40e86c0ef0e0fdbde8956745d255a017bbbfd03d060fe581f1160c5a94e75e2a63cb1a2fd7ceb133fd8ae10ccade8bbf3d919ffcdf32660ed5e372451833c2c03d3fca4210450cf2c613cee463d8e052faff2e1e9a65ffce025e7df3332e1b6da76c9d97b5ad63f9d57d014c8668579486632c5eb28bc4d18ff0c369c35934ff15766cdac7f06c136b1706e973cd8bcc30ede24f0b2bc9ef51495ee67f861d2eb5674f7ef8936c32ec0d6c581d61d1ab2b19f34707b7de2ca02859043bb3f8c39335941f7272e1a4461e3ada2e1dcd43f9d9c36bb876820e9d2cf2f9123705d768849a623439e3d7565311226848a16f0ed45405a86feec0604b61e0c014ac5203bbf6b848305869f284312767d3bf9782451fa6b5d940c5e126644716515f03e78fb65155e3c76c92c8ce32d3d21aa2bd3dcc80fe0ec291344a8b6af104155272f2e993e323d0e9a1b4d887d96c229ad083213dfc74b489541e69202659e837a437e9e61aca2b3a09778a0405238ecc5cc44007165b8cacb408ed6dedb4782bc8ccce402f9fe5784866b3f9b4e221a931158cf1ce68e3162f6ded51521c2e86f52ac7629110952604e371ff9c0d5b7cbcffb19fe24a03a2a0108ea8ac5e7f5cafb57d879ff79778292c357679639b4c2246bd81dd5576fa0ef69395d63d6ecee882fd243a14744207486190649a3ba2347861fcc04c7247cda2bd6c2b005b2a3b19d02385bcbc9e24e60cc455b9a35b197baa1d140cf6752b23184e202d612739d907293a1460d386762a9a22a8068923f561d66f76b3e3a01777504775ebf1e3da5d41366f3c44a4bd93f79646a9f68e424346a713b05824426107075c02b3a676d7ab65a534d02ba70159eeeecf118bc1679f77f2c1d208876b6544a1fb8d1f9e7f90f4e4004639084227e8f418f511c6f62dc46291d0a92d087ab1eba13a5014e2bd8f3c6cda6344128ed75b40439615ca2ac3bcb3a881e51b6b1936399ee177f18a32ecb136967ee6635b696f82422e8180c29a0df16b983471182d453b78fbed77a9ebd4d367d870c231956d4702cc1edb939ca1d308b41c261a3cfb1ed9ff8cfcf45a0a721a311b35509a118c66041410343e59e1e2f5858788397249cfc94514159a9aa3bcf36e13afbdb39fbee74f44d2c944fcb0439a4c9e650bb2100f6550bccbc55b4b52286fb0d3541263c1a24c56ef18c7e28f9258b62d1e9feb0f8f96f3d6ca7cf6ec1678e1f5148a2bf504dc2a4bdeb6f0fee6096cdf56c06ffeaf945048e1dd0f6a59bf31fe11dfbbdfcdfc37e3997e0faed1b16cdb7876ef1bcddfdfcea7aac148697927f7fc5f272b77a450d29084a74560f13b363edc348135ab5299ff713c8ac33befd5f0879712d85e68a0a63d85cf3e0ef1d9d67e842256b6afaf65e1f2fd085f98aec1bfdf0f49b4dbeda735fffb64f55e6ebd2eae13b3d9a46e2f91a7d6c8db1f49dc725d5c9f71d375799c3f2609b34ee0930f453edf624214c06e8b7782575e91cbd4c9a9584d229f7d0ccbd61d9f0a74d6fa6868eb4d419f0836a9832f12f6492cffd840760f07fdfb1a896810d6c02e4b48ba24b4583cdf7a87a2619644f4921e4132a1291d5f28a317057da2ddca088534b6efcde3505901164da3b1ce0fa2c0d4b17606f731130ec5e8d9c3447a8284d9784214450d4a3a62448431c8e1a1cc9baf120c1dbf8947d677601d3e8edefa035fabad7f7c571ffaf7b5224555de7e5b664fb1fea4dfc4c2025bd71a09aa16268f3baeb6f7b5e879e32d89191726e3b04b4c9d94c6dc2bb2484c90d8bf45e18dc527c7c3b29845d252f548b10e02474d633561853a8f05b3e932562f97d9b65b4114051c47efa1100ee257f524386c08113fe1b0867ab4dd537412a29c80a6f841fbcf8b3b5e73d0ccba1d3a6eba3a11005180e42419873946d817207ab4ca4643bc5d4c422701bf82a68173b78bb47e43b1a6c68fddbba5957756e533ea8234668e75b27d673172624f7e7aefbd4c1f3f982d2b3e0140d66b4cba28cacfee492159da467bc3619a5b3cec2f6fff7fec9d77785cd599ff3fb74d2fea5db2d525db72c145aeb8609bde7b80401208a46d92cd6e76f7b7ec6eb29bb649964d0312204000530d18dc30b6c1bd5bb6655bb6aad5fb6846d2f4997befef8f6b4b168650960021fe3ecf3c7a74cfb9f79c39e7ce29ef79bfdf976f7ce7efb9fb968b703bfe3ce1f84f4fbfcec9a6363c9e3e0e6f5dc3404f3b0039e3556ebbddca1d0b6a19f47470b47180af7de77b7cfdee2fb06fc36b23f757cc8cf395db65964f3aca82f24eea3b9269689139765064faa54b309f8e12fd890ab4c5e371745dffd0fbbfcbefbe8e79252f02306db23180682a74d65b7964854cf125d7b370c6260066cd301c7762119dceae568e1ed158362f8d59d38d15d6b429894c9b02f198cea0b79383fb235cb138035dd339d614c4af5898312505e8185387d090c486d7ec1c182ae2bebb62a4251cc5270bb824680f44b10fd5233b8a0095713699be500c7fc44f3cdc8f6c33a81eba6e9431245b983925754c19c9095d988a6d3476cf606e054c9c95c765f31da4258a5cb3c44d45910d8bc34cc3f11e84e8e836c42a095c5496c775d75c4db23a8397bff44dd4981dac326a4ce7a55d1eaebfbf0438f281da7ac942234455d8aff31f3f6ba0a9c1c2f4898923e96a5464d74607af1d4de72b5f4d233f7327ba0ede2e132b9eb510c899cf6d979fc46a1ea6a4d84549b10b4dd3d9661be4e9d79ab8f3dabc31e595165b282dce605c56945f3eb60a6e1f47a94b61d2a517b1687a29cda77e457b433596d9a9ccb8c0e8c3753b6b98b5ec5eae593a87c7fff0079a8fae47ae48649c55a276284c89d886644e43107bf8ac408d0b341fb1f1e04a2bcbef5cc2b4e27500984c22cb2f4a24321b8efd603bfded0e287591936d22273b8de1b902777cfb65d4d878b6d4884ccade48a6138e0326dd44af4fc46de9451234fc310d9b55c66a52501cc968512f908822aa94253723c93644a10bf434629a9d28906893319933102463e2918198ee40d524e2a372540488f2c56b3ac84dd7b8e5fa440ac64b1c3d1e24d33140b6d3303b44359d98209060939162e968f141200d80f2e456ec8ad1f713162e20bead86fd7b759a84057cb32c9168c0ffd7e38764f2ada6be7e98096516ea1bc26466280cf50bfce7cfbb89e7ce658e692775755e264fb4d2dc12a5ab3b4a60187a07ca993453271eefa3be314c79a995f6f6186d1d51c2018db6ce427226c8402f11bf4afdf154b2cb6de45acf5d4dac7929c4c36f687cf95e91ae86fda428325969091467bb79f5b537c9f46c61da8232e0388b6797f2bbdd2dbcb9fe4dda1aaa9934bb0c681e2da3cc46ae75ec0061b50431296102e19d5c3a652ab1e4e9a45a04a4609c49a90a53734c780231c64782e83d2e0687adb89d2192134cccbdc0c2e66d3b480f1f236ddc1444b905d069dd33c870fa52a625ad1b29e7445d98c2f126fa3c51eaea83f4f645d9b5d7c7e4804e79a983daba089e8118431e89b0760149e90142611fad6d514a8b2decde14e3878f7573c3972732d8f216dda288cb26f3c8c33e76f68de7cee9ad349e68c43dd98ccfa7d1d41c211a51397a2c838289a5403bb5f561f2721d04022eeaeb5b51758dfae3d9144c2c019ab96659166f369f400c7430148c5296594834eaa3a9394a59898529f9991c38594f821ca2b7b79fa2492598cd5e96cc2ee6b9e7d75169a925af341947821ff86cd8906a8fc4b9ffa7ad942dbd0c6578038da7c214e46773f2848781c161025e0b98e79290e225103473f46813714d67a023819c92a5c4fc6df42a17519ed98f2218b21fe5b35ddc7159272b5e4d41c4c4ace22c9edaddc3da0d1be93db68ba2e9970327deb53e696e1bc529369e7d6d2365520341bfb15a9f9a9bcc968ed96cd8dec3e183a98031a85fbba092adb5a55c2c1d24305c4456c610e019f3cc8c4407f909165e58bd9174df5ec64fbe1838371885626be20bd3faf9b717fab9fe07b7609744229f821f92f4fdef7fff07c9c9c94892445f5fdffb8ab5757676120e87693e5545341aa0acc4c281aa00c94932815088ba8e6e32133bf1f57988443426955b39763c4cd5e1209dbd11ca66e5b36c910359eb67ffc120a5c5164ed646d85f15a4bd3b4cfe94715c76711276a98f68288e6f4063d2d274b2ace72a30eea86a263935883ad848675784c27c0b29594924a63ae938f602c34a94bbaff360318333af087bb881bafab7193f41e2da85862d231636caa858f6ee65a89a886fc84a5e6a0d3d2d226ded26eaeb42747704f0fb3cf435d4e154a3385cf9f8bcade464fa50ac128ea430f5fb3772aaaf89ab6f99ccf8941e4441a3bbce47c6ec42cab37b914f0bf2efd9e7675cae89e6d6306f6d1d2033c3c4e09031539716dbd9b73fc4d19a203dde183397943277ba402ce4a5fa7888e2420b7babdb313b43c8c17ababac264a4c9b8dc027b8eb6909d3e4868a00d8f27c6c40956babae3ecdc13a4b53388232b859b6ecac72977b2f74080cc0c171e4f1adb779ea2ad238c94e4e2e69b0b719b3a482a7430507f90e3757b299a9acea2f93684b897834782941659185f329ea1b6fdd437ed20a73c89a51725e0b20e913cbe88beeae7e808f573cbe5c3e4657c76b66c752d1e7cd14112e526fa7afc98cd22e3c717b27bf700c74f7ae9195499bbbc9499152a417f129b36d5d3da1ec11b17b9f9f649449baae9ee0c327b998504651855d570bb4d2cb828890c538046af8df90bd3b16a5dd49d78037bb68d1bae4bc72e761189a8544c4cc0629188c6340af2ed648f4b2225ddcea9232fe3b79a3972b88edb6ecc247f7c06a1de469abb86b1676732a524484991939c8915f84fede758bd9f01ff10652560b7e9582d1213ca8cd35b8bd3496aba9553475632a00e71f36d25a4dada88c634c6e5d9474e72057424c1c6e6c602be7fa31f8b6d3e9148e45ded42efdcc29df97bc605a0aeae8ea2a2a2f76cf768344a7b7b3b8585e76a43095eaf7764f3575353739eedff0e446312078e14e31b4a23d11d2118cdc517c8231a8b6393779297d9498fe742fa0744ace60e16cfa92629f1b363b83d8fbf1cfa3a420c7b63144c72bd7fe68f80ab6fdac68ac7e7e070fce5695d5b770cf1c2337e16de388deb9664a238fe09bfdf3fb255fbc4d8feaaaa7e6c3e049f47c89246696107d08dcb1921146ee2d089ab90151762ac83a913bb19f2bf41af270bafbf12416a05ce0f487f0b48cdb6929a6d7dff8c1f11fff3b36958ad9fccef72429995af7ddb42517e378a6cd82c4d26d327ef87d4d7d787aaaaa4a7a7ff9f1ff6798428ea24278e32fa7553142d769040c84669a1882080db3988d3318ca635218a9f4e489ff3f8fca1a8e0936351a4a628a4a68cbd76765cb6f7528cfcd88dda369b0d87c3719ecbf6016132a92c9e7bf89ceba2a0214aefafa77d1ee7f1d782b34fd8cedea2fd45f5905caebfccfef7f382da536504022e72b387484d3cf96957e73ccee313c3d906eb4f4c0fe9bc0de9cf231cc9c3649f4b479f87c1c10819e9bd46e70802021a16530459fa783ae33ccee3b384b3ed479f981fd2791bd29f47d1b8dd1c6f2ca4b0682a8ded99ec3fd88724c6911505490f5198be8bd2ec6328b2fafe0f3b8ff3f82b82c9647a4f3fa477336a9fc9ff7f816cb55a713a9d1fda86b471a7c28cca09e4ba6a46ae79fa55b66df7e38fc430d99398b5a082fc84e36cd9de4373ab8ea298481d5fc0cc196e12c5d1f851bbf6f471b23e8ed96c26293b97cad9e924494d787b53d8b2bd9690e864ce0c0bf9b96347e0ddbb4234b4fa112433e3264c637aa9079beca3a325ccbe037e22e6442e5f2ce13ccdff3db27f889a168dccbc2416cd329eb576c320be41155d8b1208aa5c73651ae9a9a3c7ac662584c37a82bd3559b4aa19e48ecf212f5924aee98454a86a1a47dff0332c9e746c4cdd82432287aaa234770f60b29ab8ead25c9a9a4c1c3a52872608d81232a9accc26db3d1a0bacad35ce9efdc384e31a8ea42ce6cccf27c37a927dfb43d4d4f4929ea970e9f22c007cbe282b577561b51986cf69175d4869d20924c1181823618d2d5b03f40c8411151b9366cd62524e3db218a5ee5880c32723d85392b87c915176d5c13027eafde89289ece249cc9818c6a98c92a077edf573aa250a7a9c6038ca9c59494c2a373cf4bded41b66ceb65e6c2b491282770c673dfccb643edc491c9299dca9c8a6eac4a84c69301aa8e8550dc295cbe083e0dc1d296e618fb0ef809ab3ace941ce6cecb21c51266cb9616ba7a06d00589f4fc0a2a2bfcd88421ea8ec0a1a66e545da66cc64ca6173621891a81de08fb07cbc9968ed3d3ed67fedcd4f72ffc33867d073c381d32e5a7fd970e1e3c483c1ea7a2a2e2cf5245ceb61f7d2ce45ab7dbfd910cda5d8d09fce9f9e8986b83a144da7c25984c0203ed09fcf169e3c4e995d7da696ef163320928b286f88e4075eb367471b276f074ba8e703a7dcdd33d540d5c0ff145acdc3a998e01fb98fbea7b26238a66883a78f10599fa2695d04084cd6b2d1c1eb899beba549ed96c44c5edabf6f1fc5b25784357b167ab83cd470d97794511309904c26d015e5c9543f73bcaf00c5d80d72fb3a355a0ce13a7775065c3e1202fef1e66fd013ff5be041edbb58ce6f65147303502fb763bd8529d84d92462320908828e24e998cc028a6ca2ae268395af8df5aaed1dcaa63f90874996683ceee6d9970d23797bff443a7b449e7eae79246fbf27c28a179a31998cfa4be2d8155a346ea2a1773266b388ea77f3d8931a83c33ade063fabdecca43d782327f63978656f09000d3d9350051b42cccaead7cc1caa1e3bd3c9b2518e3a1863e36a17879b0ce7d9785861dbbe7cfee917011a9bc60ad545c22a8f3f31408f7017927c057f7a264c5f5f94a196006b37a4702a701b4d875dbcb8a3844f03dd83b97882d9289244ed11172fbd1e015414194c6611514fe6d5551235b5417aba82fc7105f8e42f2308cb78f48901a211e33d3dbeba8363dd951c3b1962f5ba8e3f5fe867141bdfea667fd5c0c8ff5bb66c61f7eedd7fe68e517c5c3c36386d43d275fd43b3fda74f9bc46f9f7808c8607858c56215c9ce08f3a55b749cd6649aeb86f8c79f1d038c1ffeb4c936e6cd7161b50d631787d0349d61bf86db753abefd042b8b1738b158c338a46600deaa6ae4bbbf7d90b2a438dff8e727e89d16207b34a02d572defc3694d400dc39efbb7e1edb5d3158d53d394cc9d3fb98d84fe717ce7c72ff2b5abe0ed2d3da4e6dfce2d375ec6c657e3ecd9ba9b8b2a60f91217ba0eaf3fe967f2b2e9a4e6b603dd0074f54dc66cf2627386d9572fa0ca7e5c4e85932d611a9b83c4621aaa06c14812fb4eb8189f63d46ba037c8b68d2ad3ef9ecfac541f0e970345f653520c99196efcc302e12189c6feb13fe0f2e261ca8ac1a624b07b47278fbfd20db7e7b06c9187a2dc448e9d681b933f255966f17c0782a4e0769d403aeb90c366d3b8ed3a2f09f664c2433aabbff926d17006270e0d10375dc8edb77f81537b4d3cbd7a03d755c2c58bfab19b9de8319d93ffbd87ee7609a68f46179e35ddcecc0bec54ef16d87baa800995b9e85a15b5c743d4751453327d1068052014d6d07540d350c3514a67cc6582dcc2c65d4dc4e33ac78f0fe20d4fe3ae3b6e65e8b89dfff9d31a6e5bfca15ebf8f051565435494e95864376fbfd5caaacdfd883765316f2e787d0e7c7d76761e8c120c46d1ec314441a262d63cb2c34778736f031a3a9a2ab0ea643ad7cddd444fd098a0438138ab574608679573d39c38afbe32c8de9a0e1ce945dc765705e5896ff3fdff574d795639475b7ab18ebf90afdc1424cfed63e796245edd7414f7f819b49f58c76fffbb88175e6e252bc3cac5cb32d9b3af9f0355037cf3be127a3aa6f1f48afdb40f84c9bb6009b75fd6424f4b2d0ffeba9b92a22c62658bb867711b47f758797dd321628a9b2bbf780dcb4ad6f0d8938df435ba88ba5c4c58b600838937168aa29c63b4fe7371d93e8e937ab1bfbf9feeee6e54f5c3d940aab6bd4dc5dc1900acd930484f4f14b312c5691d26e297d8bb29c8e4397300282c70f0e6e6003ff9e5008f3fefa4a3472212d178f975c3d37b7c9e9d9d7bc2fcf4971e1e7dc6416b9731484dcfcf60e3b6bdecdfb383b6e36bd1a2631d0e13ec3e50756af68631d94a48ce4cc317d5f0c674f2dd16ac2993897a8d86ae1b8c92e530e3b6b930d933880ed68d3c27e41539da318169f975645847b729766b07e1f000e1b08aaf3dc8ee4d3d347745a89cee26d92d537b7490704c2325c54cf4ac596230a2b2a5aa865d2b1bf9af5f5a786af322a271634fb2f6cd41feeba72758bfaf9bd9172f18f37d6ce620767390e17e91237b34a6ceaf04c0691d3c670564b148c88a999fff6f0f3f7e00b6edb5103f2b8b246a24d87dc442227bdf1c22af6c2616ab95167f0c8b22916ab760492c21d26ff0f7dc361fa2ae525f15211acb232b7f2ce116201e81fa866c12b3624c4e3eca90c7c4b6ede94cbdfa46f29246b76a47aa83ec3f10c064313177e1241efff1bf72ff4ffe40c6c449b893dc7406e3089248a6dd84257902d1810fa67af071c3660e62338718ec11a839205031673a600ca8bffb7d173ff8ef7d441333c9291c47725a32a54589fcfe47f7f3af3ffe135317cf4756147ca7a244f2af2021494314343c3d219e7d324887693a9755f670e08d0354771773d7dffd8e2969693cf5b8a1f575a2314ca07816fffcbd1202edad341c6fa6afbd9ff5abfb587eef23dcb570121da706d1349d8ece10fd1e63b5ec1b8cd1da6684b87ef5b7afa3e65dc7c54b6f60dfc65a9aeabaf1fbe31c1a4861fab553b96fe931029dcdac5fd3c7b27b1ee5ee2b2fe64f0f199a5ded1d418e992673c71793b96cc2b96e2c60503cdee989fd4e03f6d9d73eec18f26e902d160ba9a9a91f7a741b4899c0dfdf6c2ce96ebd6174d9121e5258f78ac4c1c04ceeff7a2d00dffebab16d0a0e69fccfafbb78e97599efdc63e6cbb71b9e58777fa990bbbf04e1a0c6430f76f3d48b22f77fdbc22ddfa8e0e5d77ecd7eef4482520e086349999a0a75872c3cb3299b4bae56a928ece2e8215004086b3aba1640900c790d9b2810d575e27a1cf428827896dae1c95e3cfe292c9b9189281c18b91e083a696a75d23b3c8b89f90a72a295caa976ca0b4ca801172609c617bae96cf2623b6bc01081d4ec426efad68f1817ade64bdffd15b7ce13302b12b75c9fc4f55724f1f28b83bcf5ca3a2e9b385a0f80e08099975e90e84b28e3df6fa8e1bd90936de3b9278c09a1f5648c6ffcc8cff44936dcaed17e8c8544766d34f3f29142be7e770f89ae385651c003c4740db410826cb48fae414b8d9527d76430e76213f327b79e53e6b037c4c13d61e67cef7a64612d2d553656574bdc9cb39ebada5a3627f8299abe84d9b30c7b5a6028c286b5fbf8875fae6692a999affec343782ff2623e5dc588a6831644903e3d19e560bf99175e90f1a797f3adab8df6b6db24fee3ffe531d80bfff4e3ed9c3a21a3a487387c2ccabf3ef00839e1c37ce59f1fe6bea571aab6f73221bb8db49438f5c0b1dd3e220953f88febbb49714538d11f203b33810985e3f177cd62f0e0f78109589428d74cda495a860d9378847824155fd84e4f4c63e1c43cac7a0226fb2ffe6cdddf3c718a0ac7831ce95428cb8f929e9c4a77374ccb3ac5c262e3b7d5128ee2d160c1a43cd4e14bf1fffa49201780ab27eca520dd98786401ceec91743d8eae4b2826fbbb5245de4bd2f6c3eeb2de0db2dbed7eff5cef82bb6e94319bc63a4245fd32eb5e95d8d159ce97bee2c26eab1b932ec91256b384a6468173b55e2451c46691f147c2808594cc16eebd2f85f69a5e0ed74ec2e46e0346bda6db4fd879fc550b33ae9acafc99c6289f6a9749330b1c6a1b22b7f32d6cb973815a66e6d879a37398befe3e86bb1bb0e5cc043a51633af56d099892a0227decfe3f33ad99f41499b61e377d9174e66667515962c66e82a46976e695db188e8b34da3ce8bed1c132c12ab1bc34119359c12499010df4d1ce124501abc5841e1fabc31d1a30f3c20a6812a6f1d55b3ff86985cd6a41508780511a831a1338b4ddcacabde95c795b1105790671b83ccd4a4d4d84e6de21bc4d7b71162c069ae96bb2f3e80b321397cf62d98547dfb59c9e0e136d6202ff52604c34a959bddc7671136aac1ab43a44211781d195a2a64320a263b6989025053d1642d7350a93ccec3f19a3a13748b46e078ef10b80a6772df32f89a0c7cc334f697439a673cf2dc173d215938c2209a069c4559d500c149382a29bd0c201d4988ba3e1991458da714946ff5754a63023b78197d727f1ad5b3fa8be8e000020004944415405726d323b3d217a7d7efc1d27505cef266f6bb4995d1670e93a277a82148576a3868d773d5916e98acd63301464b07d94003e232789a2658bb9a9b201bf6f1c66ab87eeeeb1e1e01db2805dd5a8ed0d92de7710d95a088cb5fd024c483073a46f2afd41157bac8da0371967dad48fd8b21f1d1fd986f4c8ef36929b39c4dd77a6f0dcca0116ccb1e3e91de481a75b70e778f9e3af03148dd7f8e657d358bb7e98edbb86088655ac599770f3a52642a1833cf7b2972fdf9ec2e6b7fc6cda32443014c3947611d75f9f08ecc7e38df39b077be81fb0b27c791f85d9635748bf79a28a6d27ed04e962ff9a5eeefb720ae3f372a89c97c7ca5f7e1351d0f9c61d86e3e705575e4cd53347f8ef1f6d212343e4ae3b8c2d54c817a5ad56a6e2ea1c6cc2de73be675c059f6f80ab2b57d01dbd045ffb4c3afd3a4ebb4442b248cc3f44be32886e9f496da39fd2c24edca916a62cf0f3e44fbec17020c0c21b2e43b1d6b27d87c4da37761289a9284973b9f68ef9c0769e5ce1e1baab12d8b5a78ddfbfda4b6ec930bffee900b3a69bb8e5fa247efbfb5676eef150571fe4abdfaae1ab5fca267f9c9d077fef61d01f241849e2b23befc062ddc496ed1e2c16819202133f7bb41a0f39f04c353bec437cef5b6994ce9d4561f7200fffe43b381c3adfb9c730e2ff61c511361e94f1691eaa377673c7cd4964672b6cd838c4edb7187a56355b3c4cba66192ec1d051cfac70705b85b1c2aa39d1cdf2c50eb26cc7d9b3cf4f24a233afd2c98dd754f0f0bfdd8d226894cc5f4052da11eca9794ce880c77ff275cc168dbffbd2b922719f0436ef68e5d1357d14940779a0b99f799516aeb97a117f7afc08271a5b89c66da4565c4bf9e41692a54e16cd70f0c0bfde8d108fb0f0c6cb09766c403025923cd10d9cc46412c92db2f285db7456bee8e5b1556eee5c368bba17ebf9d9bf7f0b9323891beebc18d888cba570665362b7cb984c22e9d9a92c5c90c21f7e782f69b9a57883c64075c9e2893cfa62073fa80be18f1593e332e4476ebaef361e5d79841daf9c0249e5db5fb520cb024ec7a84f61d6b84c2e9c97c2a3ff752f0270cd97af045661b74998cda3abe90baf5c4cfbab717ef8c3438882427ad97c2ae7558cac88decb0fe9ec2dddc771ca269c3c79528fc562646464505757f781d9fe73a66dc4e5f0e1724af8fd2a168b5121ef601c51941005e364c6ed920806b51143a762b162b709887a844040c3e99408853482210d5dd751cc56ec76095988a0aa3a83432a3a220ebb84d934d69a3fe08d12570524d158a9b99c12b222118b48040241345126c1292049a0a3100ac40845e2282619d7e9df80a6ea040320d9cd58a573670e5515e8ea4da6af3f85a6b60c62420ede7026b1988edbda8c596f23317132926c87f84616ccaac76c8e128be9f8fd2aaa2e6073d8b12a31c2118160d0185425c58cc321230b11868755ec7691704465d8af21890647ce6c127038240687e244221aba6e74bccb2923cb0243431a9aa6a10b2276a7038b1c221cd61004e3f470c01b05c1e80b418004b784202a84831aa1701451964938eda8eff34589c647dbd261179165816048c3e93026abe0908a6eb56157cea5c80c0dc7b098254c2691f0e9beb65844e23189a1e1303a0216bb1d9b398a20884442100c851124990497c0c7c03af8d00806e30c07ce6a6fb380dd6e6578384a2c160704cc561b364b1c018d485820108ca0236273da69adeea6a529cee21b32308971221195684cc3e950080775229a88cb2e120aaa84227144d984d3694216c2f806a3381d0a922430ec8f6152444c26996844c41f0c23ca16eef8f2169e7f7236368b097f204e4c03415450a4084e8782a699f10f0789c6350441c4e592d0758d7048c5e532265c5d1788464402c130ba20e170da31cb21fcfe18b22c62b148a7f3c984422aa1700ca4099812fe054512504ffb217d10a3b6c964221289fcdfd8fe1fd58694e09671d88c2fe3709c595d49a4a79ebbd2b2d9446cb633cf3f4d3e15049ca7e54fad5611abf54c7afcf40724492029f1cc687feed16252e2b952aea061326b98cc631d5b0462d8ec60b38ff548172501870bde6d190b861e524777226062e9850d0c078668e94840104d10dd41e5f45e4e36fa696a71803403ef909f8cd41614452071a4eec62064b580d572e69a7afac3483bd8ac32b677218fbb5defee459f982831baf337b67fa3ed08a929ef26811ac76a03ab6dec331312dead2d19198c006c2e097877be9ecb39dade96b3e47c15934a72f299b433f7aa58ac60b17ebad1926d36199bed9d57a3b89c60e834c2d9dfd762d5cfaa7398b2190994cd8033efabd92c61361bed65b10958d001f5acf74ee3ccbb90e01e6d6fe788bc888ed9a262b62880ca15976420cb22a2ace3729fe9070d30f28b62e4f4f5b37f73222665b4fd05e1ec67c299f7e49d92268210c76633da04c90216cb88fcc83b6d46ef4525f9583cb53faa0de96f052645a5725afdc8ff66a587aaa3b9e82490976146923426961ca7605c22c3c1186efbb9badfe7711e1f05f7dd5dfca996ff7190653f2c644d3396fd1f8785fc6f018a1267d6942de89a8ccb356a08b59abd58cd9f7fc1baf3f8db812ccbc4e3f14fd40f49eeebebe38c0de93ccec590df452cae60b7c5b0988690449d8cd4f3aba0f3f8fc231a8d7e2872eda7ea87f4b782e3f57389eba524b83ac94a5e477262e0fd6f3a8ff3f81c4051145455fdebf043fa5bc1b89c6606862fc09d30874e8f424d5b2b91581c519631096126e6d791e81c7aff079dc779fc95e18372d43e562e9ba66963fc0c3e28fc41309b4d28671d95c7e33ac19086a6e908a284d566c124450804e3c462c6e82a290a568b3426626a3014271a3d9d2ecb58ad329210438d4b0482517444ac5601d33b0e658241cd08392d0828660b16938a2818d742210d5d9070da85117f8f70482512035991b09f3ecd1af6ab681aa0eb68ba8ed3218f097a99ec3e455b572b265b1a2dd105c44d2ab999029224105155b6371e644ec1aba4bac66ee334d50834198bab08a280d321128dea84233a60ecbd1545c46e1b9d5562319d60c8d0a772b9949123f8617f0c55357c3e649319ab5947144697c7e1b04e24a28220202b662c1610f418c1a04e5c358e84cd560b66394a24aa120a8d5201ac76f348c4551d81584c22143aedef254858ad664cb2911e8d4038a2a2e93a56ab34c631568b0b04432aaaa623ca0a168b8822c551559d604045c33869553e43b25bb1a83ee28e22ca3256ab82246a040331e2aa613391143356b306ba8a3f70fa144937de399753324e97e21a21cd8c4284785c334eaa3e07385b7ae4bd246ccff643fa3806a68f6c437ae84917d3174de5ea196f8f5c6b6915f9fd634122f17e045301732f5bc0cd7337f1dfff5343538b425aaa93fce933b9feda0cb2a4d1d850bf7bb89e8347e26467259233b1829b6e292647de47d5d6549edad0856c71b1e04233972cf061338f7a303ffd9cccb113cd089293e492f97cf9da66b2eced6cdf1465d5560bba2c73e71d7666940f11f64679e2598d9a561b59b90a5fba5d222321c8efffd84757779cc8e010479b6c3cf4eb1c26958ebe509aee20d17d94b5870bf099b399986ba5691086c3713441202acce1c18d41fee1d275386c06595653a1b9d6c22b6b2274f69fc2e2b6f16f7f9fc6ee7d01d6bc3188168fd3d93ccce4f985dcffedd173e74387259e7dbe8b43d52778eea93964651a69dffdfe6144291187c3c2c4454bb97a699c14a961e4beb56f286cddd905a2822bef226ebd26429eb3965f3da8d23bd0862ea4503c67395fb96c27afbd5ac3732b0728294e27213393dbbeb6804265f3e9273938763c97679f7f8338a0c925cc593a855b17ed251684d757b9d97ffc04fe48845b6e4c6741e568dd4fee9379668d8e5f15d1ad19dc709d850b2735d2581de6b72b4ca882cca5973b583ecf8f59f96c08da1da8927969551f713d88c9358dcbaf2fe6c2b200cf3c7b88938d9da8ba1d4be662eeb9a907bbd0ca2f7f63f01c837dfdf4c4b359f1703236ab40ebae015e8a7e9109c20a8e1cece4ff7d7fe2a7fccd3e1e9cad87f48989fc9bcde68f6443ba6456310f3efa02579f8e4a0b90949ec07ddf2ea230bd9ec66336fef997cf72f3dc347c8331eefe623a8b2e4c07ba4e7f4631341ce3d61b92b8e6ca1cc00bec03e0a927b773ddcf5633276588ef3db095c2f17b9952343a202db878125fba53420f297cf75fdfa2b15447498fb3634716d7fcfdcfc9ed7c89ff7cb68ba7ff6b8883ab3b6853eee1fbf75fcc5b2b1fe3e93501fef1f620fff86d63203ef87a3b8f565d8d25b19d3381f806fd590c054a69eb37b3afc38e6e09e374ca1c3f15a4a73f8228405c15e8ea9fccdccc1696cf353cbd03de186facb593b5682aff306b74d658b2d0c992854efc9e080ffd2c1df7f42b80cd23e9f9c519fcbffb33f9c6b79a50d5d1fb02c1183ffaf7740a0b9cc0b932ba93669570f12516cc5a945ffcea307bb6f829ba2985ebefa860428e4cd0e3e2f6bf7b919be6ba0804552e5ae8e0bbdf3a2d4d7056f902c35c30b5860ba61afca6fd3b0af9cd736f70eba244aad77939185dc0bfff5b10bbe5dc4006ebd71d20e7c207b8e3e2193cf5fb5f7378ef416617dad9f44290ca7bffc0a596fd7cefc1c34c2c6ea020fbb3a13d9e5792c53ffe533ae9ce2e366ff0f3ca93afb1f867a9dc7b8f08e412f065f12fffd54c536d17172fb6f1c04f8d365bffbf7e36b9ee4090370171d6aff173c19d5e82ed7106878cb6a93914c46fcd664689ce89a3c3d4b5f4614dca61f69c2c12a406dedcd44daa3581537d219c9945cc9c1cc76d0ed1de6aa5aaba09537221115f03972f4fe258cd204e874c51a193b6f6209d5d212a6726130ae7b16fd749fa87e364164f646a898fe1813e0eec1ec4e97410492d635ea90f4f97cce1ea0662b28b19f3a690e7aae1e0a101c21e8961c1465a691182e730815e816155407087997da18a1c8bbd6760c8bf94c8bf989090f0910cda01af0f73922116f6c6c6417a7a6324dabd14a61b3e3b81811ecc499923f95f79ddc7af1ef6b1a3ca9855c3118d556b47d9fb6bdf18e4570f0df0d6deb17a445a5c4555357cb59b89fbc706729c90538d498e111ef6a2cb26448b9d3e7f9cde90ceb4716e52ca971068d905c0bef600a5d92ed252537166161368df37f21c35a6b0bb2199c2a26e3253468ff2354d262d711f5999c7a93d1160c7dbfdd47746b0bb4df478e2ecdaede5689d9fa82ed1e51bfd910d0c86d9b5f328bdc7db78e09110873ae7a26aa3b387c7e7a67a002ead6c1ff37d52133a494b3c574f271ad3f8d30a0fbf792440558de59cf4d2ac1a1c163fb17080b8aaa2d813312b5126e4189cb4e0400fb233194134eab07d979f077ed7cb2b6f9efb2c30c4d87efe3f8d3cb5ba81b9575c06c0eaad8d98fbebf9c31303acda598c2f361e7f40e5f575461f2ebf742e6d7b36f08b9fff8ada7e8549b32b89c4350e768658362185848239c4bc0da8e1cfce096576521b99899d68aa4a70700073a2f1be86c21abfff63173f79e020d1a402b20b0b46ee8985acbc5a9dc4f2d9cd98648dc8b0c051c712b2ac87914f9b21aab6f7b172730e434113ed478678614d360d7d57b0779b9bd7de3648afbff9430baf564dc4e7b5f1fc2b4e6aea75fc9e28af3f27b3a7fd6aba9a0af8df5f371089a8ac7da393bdfb0dedace32706797995214373789d9f7d2d97e21bba88152fa773aa55a4e9949ffb7f1be3505b0ec188cc706f94d79e53d8db7615a76ab2797ca53101af5ed7c12f5766d1e9b511892bacdbd0c92f5ecaa4d573393b36fb59b7a5618ca6f619fc3991ff8f03a2a6699ce1b37d18acddddc837ef348c3a450566ecf6d37b4c153a6aac3cbdc6ce37ee32069fafdd53cccd376452516c62c3eb715edb64469604ca8a8d1fc49db7e773e7ed394c2937b37d438ce7d718d76fbd6d21af3df29ffcf4a1e7a86deb017decccacebe0f7c8ac5ce9a4a4dcc1e43289980e51dd60f78b92133d6e1014fdaa8e59109005194130a1aba35a449ec6413afac651526ec22e8e9277fd01333bf61573bca68224330c0d4671382416cd72307d821db359a0bccc49865bc46e19edb4a80ecd5113eebcab294b5fc0230ff7120a8fda7c4eacef2565ce62f294da0fd4d6f77f7f22972c4fa62853e4b96761e7c1733d9c237e914deb1ce8561bcb1618038fae417fb399479eb173c355761213042ebb388bef7cb38059d36cb41d8bf2dba7ce71552637dbc4bc39898c4f0ed2d162c488ef8eaaf89402264df812fb36c5d9b673089322507aba0fbded9de8ee1c66cc98824b08d2df33840ef855704922a2e440d7c29cf16afeac4053056af6dad976d4cebdb7199eedb22c30639a8319151662de1efc43a31cca53dbda09672ea724b50349d068dddd4b4e6901ae748383b3f7ad1e9e7d7b028b2e71b0684a2fbbaaeab0a7e472f7dd77b360ee74f66f5a0580a2a85cb2b48fbbbee82449de8eafbb891ecf20d5cd3ebe76ef3ddc7ae3e5389de7f6cdd978fcf937a83ebc8713b5d59cdcff3a019fb1f328ca0ff0851b35ae9e710aafb79b9ab641be7aef57f9e29d777064cb6b23f7cfabf4f0856b60ce7863fb3f69e66c6ebde32e2a2f98c8916deb511485783c4e341623128910894488466384c311a2d128d168947038422c162312897e3c36a4fefe7ea2d1e887b621ddfcf5cb989cfda2d10085c64ba9c5051aabad3cf6928559d72d63fac43701282f353a2b16816327ba68a8559197a6515662dc575ce8a4b810e2319d53a77aa8ad09c31599cc5cd24fd105018607ad34354f4732777136852430a0b06aa58d26b99cfb6e0990e0388a5b114994059a8723b8076a50dce5409062a7427720ca50689858b017c56978c1ea9aceb1e628418b9999ef88409a9ed282cb61a5a17312f32b742e9897cbf2b90e929c22572f7233bdcc8e68566838d60d91d197d62e0b5c529ecdf2c51792a216f0c88bdf448bdb01997858e7e54341eefccf0fae613e6d4a22009180ceb6bda7e86cb7c0f4c491f4585062d31a3b5bdaf3f8dabd6e321377a26bd0d36ce64fcfd9b04c9ac5b22547312b7e72b26de464dbd0341d2de2e7c955a7e08be3c694979b63223727098739c62f1edd088ca722c94cd9a2d9ccbfa098aaaa63f4b59dc4644a1b1990de3edcc4b4e5df65f9d2d9749c6aa6b37e3df2ac248a9c3247074254484d48d64c0469ec76fdd3443c22727c8f95c737b8b9e19e6914e7ac05409105665ce0a4a24c60ebfe83f87aec30c9851ad3597330c8d4e949a425b7a16b225b1b1c94e5be45864da01a4870da8884c24443214027ae81248948a2882899d035635295458d3c5737a26443c0037a1a9aae18c4104940d42d088231c99b05086bc9c45485587074e2932d3a5fb93d4e496e9858248fb4348dc3d54192ad43a4da8c95a8a683260898240151b18c99d4f35cbd58e4d155b259160c5edfe97a0683410e1fa9c6e3f1fed9c14640409225f2c7e7919b9bf39ef93e086493c9444a4aca87deb6f5d7bcc0819e4166cfb453752448c17813be5e9d7ff97137e6e2795cd0bf9e7dfb06983fc749cd89304dcd1102c33a1dfd53a85c08b1582b55474254ceb053571fa1ae214c28a051df3a81499566a099683c4cd59100cdc78e5134691e69d94e60f488fdb9a70678ecad2077df3344d5b65d582aed64662651969fccf34fbf40dae03e162c1b079c60f1c2a93cf066232b9f7f8981b66a662d1b0fb4101e8a537f249971535c64998f8cf98e26258a28c649b0ece68a69038413e660171211bc310a9d1213d3153cfe08d9c37ee23da978bced24270e939c64a67286ccabab5691183c494ef91c24a5165069d8e2213eee5226bad78d94b3ef6080c913adb47786a93a3c4c5b7b98d5ebfb98312dceac196e0e5685e8ec8e30e891080af3c8c81bc61fe8a6b62eccf4697636aef6f383c73d7ce12b05d4ec5a8ba9c24ab25be181ffede290bf803b2657b367fb49162f70d2d7a7527d3c442412a3f6c4782a2a2f004e72e05080b292040607933974f824aaa6d2dc54c0a4ca69c031aeb93287978eeda1aff90803fe1893674e241ceea1fa788859d3edcc9f54c0c64355c407db68edea675ae5142c966e965e3899158faf608aa999b20a07094956cef0b93e6d1cde1fe21f7fd2cef4cb2ea5f7c4cb1c096a544c2a62ffde4e7afabd0406ad60bf88d4ac1ec0435f7d908ee01c2e2e38895df210ec13f19917919de741128c5546e94c27f75ed7c3ef5f4f46d32cccadc8e7b1cd1d3cf7fc0bf89a0f3379c135c0c177ad4f46929389594e1e7dea794a2d3d0c0f1babf5598599ac3e39991756f750b33f93338aa6372e5fcceb3bd35950788060208f8b16f9cf7966568a9bd2743b8f3ff30229c347289f7315b0e35dcbdf7fe010ab922d341e3f4cf99c2f5357df40301862f6ec79c8b23ce2997de664feec4f575717478fd5603b971cf8a120272424bc7fae77c1e0908ac56c6c4302011535ae239822ccbd2884ddb187a04f60c8646c1d42219d016f9c98aab1f8529d39d315341dfc01e3fe7058c7eb5389c5e2cc5baa317796719fa6e9f87c2ad66c1777ce6d21cb3d9600ebccf672fbb566e4a1ed0c60b81d58336c5c7485caee3d4f13712772ed72432738755a1a3745ea39deb483e9f392593ad518d80409264e8b905839569b68043a284a903cfb6e0e9e9468d382f8fc0e14592429314cd0db459add8e337536f5a7da484e1cc6ec5298bc28c4d0f6c7f0ea325fb96b3e96d31391e2d4b9e3163f36ebe88ce3f76b68ba6157ebf744b9f1ba3c344d6038101f491ff0c6890b1ad7dc20306da2841662e4185a48f072fb4d02ced82606bc0291880e92caf829838c97eb5107457c61014dd3894435bc5e95682c4ee1d4388b16cb2365a89a40346ac2eb55896b71d20b432c5c624c54d97353981e7a83c6ee380b2f9a68f4a1aa8fd461c1d5e3896fdd49c74098590b4a985f694734494cbbcccdc08617f0e94e6ebfd042ca67280ca0680f70d5b5719cb6cd0c790582a966c0c4b01f06bc2aba18e1ba1b55ca4b8c558964d1b9f4920013ca0c578df6fa3e1222fba9283144fd4b8b9d582d120517d8b85b18a231e4627c651ad7d3cab1c67d144c19c792258698e16db78cc77d9a917fd9c599e4e6da70a65ab9f256919d7b9f808409888a516ee54599444c47e90e0a4c9c9b49b6d3b075cdb9219be8e6c3b47be248a60604d94e5eae8d6baf1a5da5b8336c5c7d33ecdeff04d164375f5e6ed475e9920c5292c692afe7672a98749df23957b064691907b7be4d6949e908854455d5f7fc186e2412e1f0ff6db2113c1e8f7ec6cfe0c489131f587ee4d245bb70d83e3b06cabf14a23199bd874a180ea490953d9d40308a6750231653d1e3c39495e6d2d5d54377b70faba59f45b38f9392e47bff079fc75f3d7cfd1182c32a59f9ffb755c17be1963b77f2d843b370d8fff2aa08bff8f50972f2ff8e5b6fbd75e4da9b6f6ea2b0b0088733e17d07a468344a43431d1593ca397efcd847971ff9a83624ccdf31f4343ee7902d025367580011abd5423010e260d53164a78024ba9930a184fcfc3cfafb3d78bd5e14e732b0be9becc7797cde90900b1f6d7ff1c1f0abdf86b125590c4de4bf30eebe2f86acbc3f6b231e8fd3d1d14e6666d65fa41e1fd98684980ce2a7a3f4f74942049c67493e5bac164c2691785ca3b030175114b1db6dd8ed36c68dcbfdd4ea791e9f3f6464be7f9e8f0b8949ef9f0760e39b6ff0e043bfe5dfffed87544c7eef9dd447c547f643fa5b85c9a4306f5e250b17ce212beb137c63cee33c3e656cdcb8811ffde887d41c3fc60f7e703f555507deffa60f09f18c1ed2c74990fb3ce1d8b11af6ee3d40575737f1787ccc09c3799cc7df0ab66e7d9b5ffcfca70c0efab0d96cb4b6b6f08b9fff94bada0fe64bf741f1d16d487f23d0750da73391dede015a5b3b48484ec19d9088248a48a28ec3664151e44f455def3ccee393c2b46917f0c8a34fa0aa2a9aaaa16a86313b3939e5632d475614e5a3d990fe46505050c0d1a33594949471b22dc8de86012c8a1fc52423e821d2dd2e26e4a7e1767dfeed69e7f1b70b97cb8dddee78cf53b68f0b726262e2fbe77a17bcba7e0bf3962ca62079947bd6dbddc9fa35ab190a4531bbd25878c9a594a6bb58bb762d757575984c26324bca58b86811c9caa8ecc6a64d9ba8aeaec66c3693965fc8a2a5cb483549785a8fb066fd0e82929b39172e6052511eb238ba1279eb8d351caf3f85a058289e3a877917946397355aea0eb375db5ec2e60caebcfa12b2121c686a90fd5b3672a8be8b8cc2292c5f52894d1279fef9e7f1783ce85a84e180c69d5fbc83acac512f6ab3d94c626202dbab3b69d7331937be90ac449198aa11d6a0bead9fce832d5c7361d918812aff400fbbb7be457d7b2f264712777ce1266a6a6ad8b56b17a0118d84289b30934b2f198d21dd507792b736be81cf1fe6defbbec619adaa152b56e0f178902489fca9d39957390bb73c3a811cd8bd8d7d07abd14485dcb2695c38e7022c7a9475afbd4c479f17d1e460c6a2654c2fcee6c8a12ade7efb6d6c361bcee414965e7b3d59e633549318f5b587d8fcd63e54c0644f65c1d24b29cf319c87ea0e6c61dbc113042231162f59c6e449e523750874d6b17ee336ba8722b8338a58b8f8427293cdf8fa5a58f7da5abcba8b85cb9632615ce688accaa78d8693c7d9b2752ba1984e42463e175dbc940c6b98b5abd7d3dad98f2ec86497ce60f1ecc9b84c71ea0e6f67dbbe5a346b1a575e732999894e4441c0dfba95ad03b98c33c7e86c6b79d7e3eccf3a0e1c38c0debd7b018d4838c4c48ad97c1abdf49197456aef21fef8c82b63ae8562a0d952282b9f8023d2c8230f1bd4920d1b3600505e5ecef8ac2cccef7821b76cd942201030d273b2b19c4e5ff9f0a3749952199f12e7d58d55b4f58e0de6d71f9129282ea1305d61f573cf525bdb42b0b78d8dafbc48af9285c5b397c75719ded79dbbd7f2caf61a5c096e6af7ac66fd1e83c25050504079793969f16eb6efa8a5ff2c67d748244a777737ddfdc3ec6855a8ed8bd33518675d558017770eb166ef30d59d16561c10a9af6f19b92f161c60e79bcf73a043a5b47c22e3d25d888240525212e5e5e514e565d17bf06df6348eb54345e23a8a338dd7d7ac636868d4237dd5aa5523f7e6a4a7617ac7f6b02f289035be80a2dc44f6bcf92adbb71f46d561083ba51326302e21c8e30f3fcda0cf4f555515a74e9d32ea51908f4d3afb1510b03a132828296342f9044c91569e78ec6900066ad6f3d48623648e2ba2243f079765ac3ae0cbcfbfc8094f9082c21cea8ebccd5b9bb6a046c2ec7ff971aac329a40b2dac78791b7d839f0da63fc06044c0969c4d69493e83a776f3ec8a0d80404a761ea5656514e5bad9f4da731c3b7692be8e769e7ff205f4853780d00000200049444154f402721d3d3cb9a68668ccb02756ad7c954e4f3f0d0d0d6cdebc195dd7894523446371745d23168d100a0509472268a76d8fe1709868244c2818241c89a269865d321e8f120a060945a2844221745d271a8d128f1b4eb2f1789c68f4b47e95a612098708064344a271745d47555542c1a0713d1c43d334e399a120c15098f869467e341a25120e110a85084755525252282f2fa7303783ae036fb3bfc960f8777474d2dede466767273d3dddf4f5f5e2f1f4e3f50e3038e86378788840c04f2412fe78b86c1ff5c6d2b21236ad30acec7d7d7db85c2eb232d3b9f9faabb09a149ad20456fd7cd548fecccc0c0a0a0a71b813b10802aaaad2dfdf4f7abab11a494f4fa3a0a0009b2b11ebe901694f6d3b7ffff5c59426a9acfcde4378e757909f5134f2cccb972fc16a56880db7b3e6cd830cfb3c74aa22f5ad5ebefaadcb717a52f9e67fbc0177cd63cbce1a720a4ab8fcaacb78f3551f35bbb672fdbc2f306bd62c742dc2ca9a7d4c5c5c4c7acee8f9674f8f075d039b2b837d754162c2302e9742634794da463fe1a06a6822c5150ed575535666b0c2077a06d8be710fb3befeaf14a4b8494c4a445614c68d1bc7b871e3e86d3bc1aa1752b8e9ea5963dab4b8b89882c222d6bc3e76a0174591dcdc5cc68dffffed9d79785445bab8dfb3f4bea4b3ef3b61094b581559641110041591451044c55d67bfce1d9d7166fccd1d9d19bde32c8ecbe855508111451051101144441064dfd7000924644fa7d3fb39e7f747271d4202c48802d2eff3f0a43975aa4e7555f577aabefaeafbb2b147c7a03fe3353264e0d5e875329aaf9aad5b7752517a1cb3a90f93c78fc36cd4e3a94c63f67bcf10088484416c6c2cd9d9d9182d762ca7bf1c0489d4d40e58ccf1d45457505db40d5f306494b7f4ad0f89e936840e791d88b2db89898e22180c525959496262222641c5628b263535199bd9822618f1f903ac5ab78fdbfefe385da4a32cf9f9ebb8aaaf85e8efc686e59bd2ad4b47bae577441614444f054bd6ee4490c6d1b7773f4a4e9ea0ea640034114515a9aaf370acdac3036346e2087466ce8fe7a0dcda1355ab65496134b75f9f40c9b10a344dc15951c4e279b351734732f1aa3816cc9bcb964365986333983aeb017a6738f8d94f7e4cb7f4680e9cac454c2ae081bba79113a3f1e9e2d7787fed4162327b7270db5a5effbf979933670e696969dc74d34dac5fbf9e0d1b36f0e8a38f7262ef5ae6ccff88d21a2f09ddae65d6e41b38756c3f7f79f2d714f4e886d6f516ee1d91c7d79fcc65e9e77b516433a36fbf9f9bafeec4cb2fbfccc9bd9b911372e976c33d4cb92a8bacac2c4a0a77f2febb09dc78535fece547d8b4697358009e8fa8283b168be5fc379e83760ba4cf3ffe8cbed7df03c0ead5ab19387020a9a9a9e864094fe57156beb788de236e03a04bf702366cd8c0d71bbfc21097c52db7de46d78c28962f5fcecc9933c9ebdc95af377ec9c1fdfb90a352b8f1d6690ce89acad01ed9bcbb64197d120314ee5e8e161cdfac0e16939ea0d7c5a6154b906d1924a477a0aee2303541c8b41a702b5d083a9f07e0882b4867b31e9bc9866c4e20e8da1b2ea7be642fbb8f17d37bc84812cd4d56b1a228e072bba9f748784a3d6cd9574dc73c2b43073a70bb027cbcbc949cae0e92630d6862932b06674065f5f603a80bdf62555d35c9bdc7f393db47626c384a737cd3023c29d7322cadb9de49dfe04e513c6306d4b5472f962e5d821a08604defceb4c9b7d229bd49709a8d7ad4a08f3d1b565259a3724d8f6b1045018b498fcf59c6ca0573c9e9350293c54e7a66369bb76ce5a517fe89aab330e296595cdf2f0b08b9961010d8bcf96b962f5d4851690de3eeff0d005f9c7421942fa764f33a546b1a53a74da763b299152b563063c60cae1ad287d5ff7a873d5f7d06a644064ee842508323f541ba469bd0d101c5770a4d6919b2fa626168e88fb243dbf86aed46fa8cfc31822010f0fb7963ce6c0eefdb8194d99fe4cc54628255e4c65a98bff00372e4622a8bbe00142a77af44cacb222a3e91d2e37b293eb48bfffbd7df31e58fe5ae51fd583bf7150e3bedfcf2f73f61f7b25778e3e5c5f4fee39d149faaa0f7e487f9df6be2f8d5e37fe6c8aeed58b263f9f8a32ddcf1a717e9e45acdf44f8fa2691a555555e1e57b7d7d3de5e521373c739ffd27ca553733aa5790d7de5ccc753d3b21685e8e6a31fcd7fd4fd027d5c6b19d5bf9f8a32dccf8e3f324972de3e7cfcde3e6ab9fa4b2b292134957f1d75fdc4bdc6996e0c736bd43207528d7a658d974324074744c9b376c54554155bf9d3ea9dd0249ee3a96db6fec06c0e4c993c3d73d15c758f8c66c8e9b0b7878422f00a6cf9889411608bacbf8dbb3ff60edca35f47d780a3367ce0460e2a449dc366532f8ab79f99fffe4d3a52b18d0f52e6ebaef5e967ff225155e11c196872036b70c57023ef6acfb88855f1671fdd499e46538d85f193a1d5d17541082d508724847162509b81515bfe247533d0872a883354de5c88162aabd263af56a1e775daf9770b9eaa8abf2d03d2f164b721c83fa5ae9982ee3eb6fc7ac1748cdb4517ca80a9dea4351146459461620273b8fe93f7d8234ff5eeef8f1bf79f0d6c118f55654c5cb271fed65d09db7b7b9ad7ffaf35f603148b8ca0ff1bb3ffc8b9d9b3bd0297d58b37b8a767ccedca59be83de636faf708ed98faebab58bd783eab8e1999f9c030ec563d43870d67c8b0e1e8051fcb17cee1dd37e6737dbfc79a953572e448468eb88e752bfec34bf31770c7f06ec4ea443a8d9fc9a4411d79ee997fb063c306face1ccf8c19330058fcce4a7a8f9ecc94d15733fbe597f87af5e7f498763d51924065402141a84594cc205c5aee5d5d27f7f0d61b0bd0771dc5ad2342b36fb3d9cc6f7ef35b9ce587f9d56fff41e19e7d7418da93dbeeb99db51bf7536b8842326701b0f9ab4a3a25a6101f63603f706cc7468484027e3dab00834ee2687d9094040bc931768a320bf06f0879c030c822233bc6209b5310f54634d5455d20861a41a047b215933604d9f472b89e1aa1b1dae82d00e0ab5217bdea4e7142b03174d85564a4455354e4a26b92858294d0cbae36a0e19225baa558516c0309d637cdbe47758c25e63477bbaae2e59365fb1874ffdd00545755d3a37b771cd1b19c6e1ed4da5f4551d8bd7b6793fbe376d2eed131ede66b8935358f76eaab2965d15bb3d9e67470effd1348b2851c57cb7a1111011101590b80da5ce24aba50ba8684a4f9d01ad46951c9f94c9ad185135b16b1a6433efaa88466f98e6f59c12b0bd73362c6bd0cefd3099d28106f9549340a6c3e564b66f12758b206027075868545c5b5949597e13cb11f4bfa3800547f2d870b37634ae84d7e62f3b0b10909f1c4c6c6603f7c8c6bdcf50c4c4ba36f8e1e8b1ee27a9818d8c9446d50a0d058815ae9097bcc73182546748e4611442431802034e95bea8b56b2c39dc1d39d9a7f977321eb25100444342435085af3f6ab39b49e7fbdf6015dc74ee5e661bd318a028adfcda6e50b58b2a592dbee9b45b7cc4444414092453440502464cd076ad3fa4fd3143c012faa60c2aa1391f12168a1b7e77579765c3623882a92a8d23c5a2a04032a7e44404508fad0140dbd24d037d5c4c7bbca1967fa0ad9918b64fc2e0f5b7c335c25fb79f585d7f0a6f5e5ee49a3b04a22aaeaa1d62f61d7eb900822691a2022ca46b27b0c25abc7b5ecfbe8593eed391c3558ce5e8f48b62d0fab14ea93ee834631a0938179ef7ec82fee9b4296456675919bd22a27ce633bd047750742b3515910e034d5b14d1670681a3b4ebae8e4fe8ca027745634412750ec0a5053efa4e6f02a1a23d7f64f8b26bacf68eebdae3bceb2e3186d0e8a8a8a90c365835d27600daaec2a719152b61ed9d2f4d2d58b42b3d9b8abe8137679b3b9ab53d356be248961ddd4f9ceb2793c6739a0fe0d68b7407ae17f9f212323837befbd9779f3e63178f060aaca4a79f583cf712465f2c29f0bc9cdc9e1c73ffe319f7cf0016b3f5f83c7eb2136b70f536e1985c7e361debc79cc9a358bcf57ace093959fe0f5ba894aefc6a4db6e02a0baaa92e7fefa176a9c3ec6dd348ddcf4e63b822fccfb885dc7ca50fff36f3e5b20f0e0830f929b95cba091d7b0f8efbf2128dbb9e7de8701e8397e323bdf788b679f7e86b8eceedc7173c8ecdde3f45076b49ebe93aec328b5d4f1d7d7bba9a9ae6144ef348a9cd59c3a1cc4e5049b45263a0ea8aa254da846b3dbd9b7ef10ddbb77c19e9842c18891ccfff36354d7fb197be74c8ca690b0dbb372375dc65d4f9cbde940e66bafbdc6c48913d9b2650b6fbef926274e9ce0b1c71e63d8b061cc9a358b056fcc66e7ce1d787d7e527b0ca6dfa03e949797b37cf97266cc98c1ec852bd970f028b51fce63db8a054c9e3c994e1df3f8fb5b1fe114edbcf3f273acb05979f4d147d9b7772f0bdf7d17afcf8d3e2a95bb7e722f0073e6cc61cce8111415ee64dedb1fa3a801245b0277ff2cf4b61c78d7c3bcf6fa3c1e7fb7025b460fae193198dada5ade7bef3deebaeb2ea6dd359e57de5ac2636b96624eeac8d41b46a03399183e633aff7afd49be120c8cbef97692126c2ddaf862b17afd76defb720719d975fc69df570c1c388009e387f1f62bb3d97fb888a0aa9179cd70baf709ad04766cdbc29b735ec3ab5978e8a1dba93f7a1051aa27b920174110309bcde476edc3a4bbef62e97f5ee5f5859f72e798eb38f69f793cf3e41318635299717f48ed909c9c1cf6411d171787c5622131239551637a31e7a95f129351408d372478c68d19c8ab6fbccb93bfdf8f5f88232b3e747deacf1ee2d5b7e6f0c8622f826ce6a73f7a18a3d1484242d3cb2e25279351a30b78f34fff8d2a1a98fec80340488f68b5365719ecf96417ddc6df408cb59578eedf13427575755835be67cf9e369ff61f3a742876bb1d83c180cfe743a7d3a1aa2a5eaf17411011849032d6683436db25102519bd5e874048d36f301808040204020140439474e8f53ac48668063eaf170d01bd5e8f2489cdd6b31eb71b45d3c252de60303404ac0b12f007d0041183418fd4e00338e0f71154544449c6a0d7855c6faa2a7ebf1f516f40d7ca7674494929274e94130cf8292d2d2380911a8f0dbf5fc528d712650a62b35850350945f13164c85558ad165455c1eff3a3027abd01b9a1ee419f0f4594d0cb52f8bbf87cbeb04375bfdf1fd645c9b21c6edf465b0f49d6a1d3c9a0690402010c06035eaf97a0a284db41afd7238a62c31b4ba0b1c94c2653f86d061a8228a337e89104e1b43e54f0fb437d2108127a8301490cb928f5fbbca1a822adf4a1a62af87c7e54ada15cbd0e51207c5d4340a7d787dbe15220e4f53080200a088422b5ea74327e9f1f456d8c3aa20ff755a87f7c2048180d7a0e6fdbcae123850cbe650216490c9f8837180c04fd3e829a88412f11f0fb43d15f440983418f2808783c9ef078f5f97c489284244928413ffe401041d43179d244e6cf9f87c56cc4e70ba06a80202289346b73456d882c633000a171616cf077a3691a4a30803f100044f486d058f4f97c88a2884ed7a43f0afabc28a21cfebea79ff63f7cf810bb77ef0a2ddd14b56109a7d0bd474f1c0ec7853beddfdece34994c0d0d40f8af288a2da42e847e207abdbec5f5c67c3a9dae59c334228a22a673387c3a5b9a2ceb90e5e6e5098280de60e4cc5a08a288c17876af053131d19c3a558e2cebb96ec4209cce3a8e169e441445dc6e0383065fcbb163451c3d7a024d5370bbebb1d9ac48928ca9957038b2c1d0a2d1cfd70e8de9677ca1f075e359eadfda8e872ccbad468738bd0fcf6cbbd0e3040cc6966fcec67c8228856781cdf29da51d2e05ce3a2ecfd29e67b65d5eef3ee4f5eed36abaac6feae7d6c69de9b4b63abd7f659d015917faff6db74d41a7d32188324653cb363c5b9b9f6e0f270802b24e8fac6b5e83d6c6946c309e5520545656f2fc3fffce8e1ddbc2d7ae1930909c9c0eb4d7a75a6b5c9a23e512c26030d0b367f7f0ff6559c7c68ddbd0348ddcdc0c0c06037979b96464a4e176bb5b15c81122b487db6f6ffbc6c7774defde7df8e3537fe6a73f7998c3870f71f5d5d7f0f8e3bf252333f3c25a6a5fb092ae100c063dc3860d4455352c0dd1260541c068349e75a61221c20f811e3d0af8c73f5fe0c517ffc5a38ffe8ab8b8f80b2a8c202290ce4b454525814000bbdd8ec5624614451c8e48f8f10857269d3be7f3f4d3cfa0d3e92eb8308288403a2f870e1d425525ac561356ab85b8b818ac566bc888f01251ce4688f07dd1b81af82e84114404d279c9c8c8a0a2a296f8f8188a8b2bd879a81a641db24e8741f0d2bd531af1b1d1116f0911225c00da2d902aaa6a900c264ca79ddaf7fb7d545556366c0deb888a89c1ac97a9acacc4e3f184766acc66a2a21ccdb6d8abababa9afaf0fed84194d444547a31705025e179555b5a8828c3d2a0a8bc9d06c56525d5589dbe30541c464b5136535230a1a3e4f3d35354e54514f6c5c0c065942d314ea6aaa7179fce84d56a21d362441a0acac2c6c72a0281a898989180c4d3b1231313114179750511b45919a8a9c089971029224e009aaacdd5f4e7e92872eb9a9cdeaa604fc386b6bf0f8fc08928ec48478eaebebc38766354dc56cb61113d3b443e171bba9a9ae22a8a824a7a484776c4e9d3a15369b305a6d44d96d61c337803a670d7575f5688280c16425ca6e4344a5aab2027f20088288cd1183d5a4a7dee5a2a6a606511491743aa2e3e2c3879d354dc5e376515353870688920e7b740c96066f00eeba1a6aeb42a6160e8703eb69bb788acf4d55752d7e4545d69b88724461904582012f559555049171381c988dfa4b6666e971d75353538baa69c87a238ee8680c0d5e1494809fea8a5274e628a2a2a2d0340d9fc7454d8d1345d085c795200828de1a6a82068c8286cfe72526a68dfe602f216a6a6aa8abab6bd8a113d09b2cc42726b275db56e2e3131145297c7836f45743d3085f733a9dc8b288cdf6ed3675da2d90e6bfb79cab860e2527aaa988a2634778f3f5d7a8aaf7618a4ee596e933e99d11cdecd9b33970f00029c9c96416f466fcad2197178aa22049121f7df4116bd7aec56ab592dca90bb74ebb9d3483ccc9435ff1c6dc8f708a318cbef92606f5ea026a28e48a20087cb4f81d36efdc8f261be971ed186e1e7e351629c0c19d5fb268f172ea8ce9dcf7c09d64465b4175b16ef9bbacda7298f46e03b97e585ff44a90bffded6f949496a2296eaa6b151e7bec57e46437f9c6d6340d9d4e66f5d7fba833249115a7e38013dc01150d50d058ba76373abcc852535bd49e3aceb2c5efb2ed5031c6a844fefbbf7ec2c6afbee2a365cb4053f07aeae873d548ee987e6b38cf8e6d9b7967fe9b54d4b8f99fa79e2636361680679f7d96929212649d8efcc1c318376a24b1baa619d9a7cbdee793d5eb50243d1dfb0ce1e63143b1685e66bff202474e94231aec5c37611ac37be6b0f6b3d52c5cb8109bdd8e233189290f3e428eb1c1fd88e667fbd79ff3f6bb2b5000833d959b6ebb837eb92183d46d9fbec7a2d59b707a024c9c348581fdfb85ebe02cdcca9bff799f63551e62327a30e1d6f1e4259ba838b18f39afcce69416c384dba6d0af4b5633617a31d9b1f92bde5bb4987abf466c4617a6df3583beb9c988a288b7f2240bfef10792afbe911b6fbc1125e8e3c8deaf78f79d0fa9141279e0915964c7d991441167e14a169ec8a5ab35c8a1fd7b983a752a9224110c06c35bf08dc78ac2f664a7a5377a2095240945511004015114cf9a2e49122e972b244c1beca5ce852ccb184d463c1e0f4ab0f5a5d6a2458bf8f4d34fb15aade80c267a0dbe81b123079395e9e7f8f16254eddccf31994c74e9d2e35b9b00b4db30322b3b9ba2a21344d9dba6e0ad73d53178d080905d45438337366ee39998333ba4b5f460301816488d9ddcd8298d791a974faaaab65a667979053b76eec66ebb74ac86235c7ceaddf5e4e464919e9616161ead8d455555cf997efa583d53207dd3b1dadaefc3edf6b075db364040af6b694775266e8f1ba7d389c3e1c06838ff4eb0cfe745a7d391dfb50b966f18f8511004962d5bf6fd1b461e397294fcfcaea4a4a49ef75ebf3fc0dab56bd034c2867f8d4ae15080b9902575a3a039fd5f63fae9791aa7fc8d69e74b3fb34cbfdf4f54949d9e3d7b477c63470040555476efde85dbed41a7d3b53aae2ec6586ded992525a548924cb7aeddcf69d40b2141b76fdf5e0e1c38488f1e3d484d49e37c23bece59c7966d5b283b55467676567b9bb45db45b20f97d7ee2e3e3f1fb83cdaebb5c75088280c5d2b496f478bc215fbc6ac8e953e309615114c3d71a3f3736fe99e942c35192c66b40b33c409bcb5414257494241044557ff802e954d9297c5e0f292969b85c2eaaaa2b484e4a4110444e9c2c222e361eabcd4651d171ac162b7171f194949c4051155292d3ae08857d3018c4ebf76330eace3b16bfcfb1da5a7abdbb1e87c38124e99afdfe1445a1a6a626bcd46fbce6f5f91b9ea935388d0ba555555562b3d95b9c0e90641d46a3a9cd7e902e24ed16481a84854c2335d5d53cf7b7ffa55bd76e4c9a7c5bf87a5009a2d1747218f8c69ddef886684c079aa59f5ee699e96796199a06379e603eff1afcf247232929e4084fd354e2e3e21acec0f9b0db6c44454511080431180cc427c411f0070181e4a4a4f012e5874e634499c625526be3ea628cd5d69ed9387e834af317ea175f7ccedcb7dee0c5975e0d5f3bfd371af21ed924909efcfd130c19328cb1e36e6a76dca4b12d2e06df62db5f6bf851872aee72b9f8eb5f9f61f6ecffe3a9a7fed2cc4e415555d0b4668dd77880b4b1831a3f3776d099e9a75f6ba4ade96796797a077d57f61497128ea868342d3438cde6d0ce582010d26fd8edd1f81adea031d1b1783d0d9f63620906436afb2b014555c2c2e46ce3ea628cd5d69ea9a91a885a83b009a5af5bb796c77ef5680beb69455142f73794a9284d21cfeadd6e9e78e2313460dcb89b9ae7b948aa8c6f6587a4286a5820fdf31fcf3177ee1b40cb1fba1afe82cd3be46cd3dcb3bd651aaf9dde496d493fb3ccc6cf173a62c2a54a5d9d13afd74b6c6c1c3e9f97ba3a270e470c8228505d5589c56ac36c3253555581acd311657750ebac21180810131377c96cd37f97a88a02a709a4d6c6d5c518abad3e130d1a848baaaa7cf9e5173cf9fb27282a3a4e5c5c5c4b81d4b043d638e6c3c246d3a8aeaee6e9a7fe802c498c1c35ba29cfe53643d2349a4de7af1d3294a54b9770f2e48916d3fcd3d7d18d1dfe6da6c1adadc31bcb6f4b998d5ba957ca72c4ebf312dd60efe4f7fbb158cce8f53a3c1e0fb22c61b35af0fb83041585c4c444fcfe201e8f87c4c404345545d3ae0081d430164e5fb2b547bf73a1c76aab4b365122a8348ddf0e1df2e8d5bb0fc78f1f0bdfdbfc7b690d9f9bbc3c02e19dbb2e5df2e9daad7bb39543633082ef9b6f37435215820d760d3d7bf6e6e93f3dc313bf792cbc566d241854c2d3c5f62a0a4f4fbf104a6d55d308069566f5fca162b745a1a902412d88d16842108486259b8cc562c7e70ba0691a8ea8683c1e1f9aa611ed882618b872221a37ea5a1acd4abe8d52fb428ed5d6d2834a105513c2ba1e87239ac71e7b0234387ab4b0d9986ea643d21a75480d024ad3b876c8309efc7f4f111313d32cb2c965aa436abe34ebddbb2fbf7ff28f2d0ede353afe16c5b6afc3cf95de9e3ca7a73775fa95b164f3f97c049500669385603088cfefc564342308026e4f3d7a9d019d4e87c7e34694248c06235e6fc825afc964be22966c8d4b99c6d9737bc6d57731565b4b97440925a0a0a8a128b210f2edf4e82f1fe3e3e51fb5f8ed9dbe640b39e20f3d63f0e0210c1c3898a8a8a856f44e9799400a29495b2a857b3738ac6ab98ed5e08cd073ed55fc9dbb5ee72f33f401942b44a95def7611edb0a3691a5eaf079d4e429244bc5e2f8a12c068b3e3f3f9717bdc242525e2f30670d5bb888b8b4109fef097b4d052917ba194d4e7e2db94a936e883d4d376890d060337dd7c4b2b02a96189a636e99da049917de66fe0b2546a0b42c8eda9d6063b9ec62fd838fd3cafd2ee3ce96d9d069fab4c4551c22e477fe8988c26342de4da57a7d321cb32c160c822d8683087a7e816b395803fd426669305556939587fa834ee58355a4ab759c1fc3d8cd5d694dac140906020785ec171fa8c28d8b08973bee558e378b81833e3760ba4b4b464f6eddd8dc371fe50dc9a46837fe89099bb28363ffad128ac743a5dab47431a3ba831bdf1d0e999e6f88de6fce72bd36432e172d571a2b818ce6bb71ae14a21180c60369bc363adf168c7c51cabada5a7a5a5b271e3d7b8ddf5adbae03d934020b491515e5686abcec5f9c6bcd7eb459204e2e262cf79df77c137164866b399929212f23a74203a3a86cacaca36e5eb9adf19bd5e1feea0c64e6b9c9636aedd1baf01e1cf8d6f95b3a5b7a5ccd3d36362a2c9cecaa0cee5e2cc6564842b97b4b464929393bed1b8faaec76a6399a7a7c7c7c5d1b76f6f8e1e3dd6e0a9e2dca4a424d235bf13955555f87c3ece37e663631c646565121dfdcd0fca161616b6ee03be8d7c6381949999494d4d0ddbb66d6b66dd793e8a8b8b282e2efaa68f8b10e17bc3eff3b269e3c68b5d8d0b8edfe7a5b6a6fa1bddbf73e78e763dabbebe9efcfcfc76e585760824abd54aefdebd713a9d57840d4f840811da8ed168c46eb7b73b7fbb74482693a959189708112244b810fcf08f71478810e1b221229022448870c91071f21f21c2254850510806025c6e277724490c7b856d0f11817409a0aa2a2e573d1eafe76257e592441225ac362bc66fb19d7c39e1f3f93870f030e5e5e59cc795f52587c1a8273fbf3331d1e7b74f6c8d8840ba04a8a8a864fbf61d787dbe8b5d95ef05afd78b5e6f203e2ebe4df70782412c1603f95dba60fe863e9e2f478e1d2fa2b2b28a7efdfa5f769b473b77ed60f7eebd0c1e34a05df92302e912e0c08183586d56060ebce66257e57be1d8b1e3b83d7e7af42868d399a93a571ddbb76da5a4b494dc9c9cefa1861797baba3a3232b21025e9b27b49a5a5a6b379f3a676e78f08a44b80fa7a37b91db2494949b9d855f95e703aeba87797e2f3fb9b9d9573bbebf9c7df9fe3ee59f791909010be2e8a12168b0daff7f2fa717e1b1a8fa05c6eee5fbe6d7d230229c245a1d1f750a3402a2b2be3cf7ffa1f962ffb88ddbb77f1c7a7fe1216d0578a23bdd3693cbf76b909a46fdb4fed1648258776b16def11fcaa86d91e4fff7ebda87356535c5ccc55575df5ad2a753e5ce5c5ecd8b59bba8040df3e7d70bbdda4a7a79f3f63844b8646f719c160909292933cf5c7ffc7272b3e0660ede76bf8ef5ffe9c277efb243939b90d1e0caf2c81148a0cdbf619527dc50976ecda4d75bbf55f00001b9a494441548d3b80ce6825bf6b37e2a36d6cd8b09ec1d70ef98eebda44a8beed17a2ed1248f52737f3c6fc8f894e4dc3669239557c98822ed91c387080152b56b45b20853a20e4c8ed5c6cf8622d5b76ee22afe02a0a0b0b59b76e1d3ff9c94fdaf40c55d510042eb86b8546170fe7abfbf9d8bce10bd67cb19e2012291d7b3272f860122c1235e54779ef3fef52a945316cf4687ae56520e167cfd75ff0d9bacd08d1b94c9e3c8e3873fb76a282c120dbb66da36fdfbeada67ff4d147f4e9d387c4c4c46ff3f5c2685a934f739fcf4faf5ebde9d5ab77b37b7cdea6f05957e20ca9ad02c95f73940f162fa532682221d68ebfac980487118ba1136fbcf13a83065fdbee7a7cd3df8ba669dfca8146bb04d2677317227719c29471d711651071d59461b4343f195c55b29b05f397505ce525b3d7b54cb87e30016739afbffa6f5c7e059d298aa1b74c65687e1a73e7cea5f6e82eea4d89e48f9cc9d8eea12dc3daea2a5e7be5252a9c6e04c9c4c01b27931d25f0cfd7e721c93ac64ebc9d7fbffc325bb66ca1b2b292993367a0572a58b06039551ee836ec266ebeb6804debd7f1e5f24558a36331f79dc28c6b3ba097430d5c767c1b0bdefe90921a3fb9570de7e6c15dd9b77611257163b975600a95c51b99b3e8183fba6738eb562e63dd968308e604c64d9d41419a9d3f3dfd14c9c620270cd90cec9fcdb6f527b875e2185262653e58f401d6a41cae1dd09ba0dfdfa61d139766a663f7ded8f57e3e5fbd82e51e81dbc7f767d33baf72c8d08f81e683cc5db08aa407a660a9dacdf2e5abb0e55f8bfed827bcf67e2ebf9cda335c96a6690403be908b5a040c26137a59c2e3f1801a44510151c26834515b5bcb0b2fbcc0dffef6370c0643c80d062a0155446f3091969686c9646aa54c337a594409f8f1787da8802ceb30180d48e718c4e1255b30484a7232d3a7cf6cf53e25180af573b13c185e2cbe8940dabb612347eb55c64f9d445eac15bfbb160df00743c241d33402ee53acfcf043761e2ec19a98c7f5e3c6911b6f66de9c7f73b4b81441349077f570460fecc591fdbb59fece1bc4272642e71bb86d48174cbab61da4d734ed5b39f4699740faf450195346a761d34b200858a3935adcf3f14bff26d07108c3f3832c58f20905d9e974ed94ca88d163f1f9bc5495ece5ad17de66e8f3bfa0b0b090e3a4f15f936e2529bee9609ed16461e888eb71d7d7e3a93ec29bff7e9b679f7a9881830663341ac9cdc961cc9831f8fd7e1e7ef8614cb2c8fca79fc13e681205ba52de7afb3d0677c9e4d4a953acaf94f9f5cc3bc84b4b422735fd5096bffc0a42f7d10cef56cfdcf73ee4aa0ec9a8460b3b3ffb90d1fd67b17bd9623cf1b7b077cd677cb5e520ddfb0fa2e2f016de9df33e05bf9ec1cebdfb61ec74ee19d1178b4962f73befb0a9b01b035df5ec3f78885e3983a8733a59be6c19d3a64d3b6fdbf6efd30349122150c79eeddb282f3d4620d08f4fbedccf8c7ffd964e6277e63ef23caeaae114179ea2ce0f536f188eeb90c6fffbc707709a40f2bb2a58b3ec1d3edd78107740a0dfd83bb963540f9e79e619b49a93f84403d58a838977dccbfef54b58b3660dbffbddefb8fefaebf9e0830f4834812f3e9f11e3a7b3e4f5d7b9e79e7bc84d8f67f5870b58fdf561bc8ac43537dfc5d4615dd9be7221f33f5c835f67a663bffedc72ebada418ce3e889db5b5949d2a6db3e19fd7eb01be5ddcf8cb896fa243da5be224de6e2323bac1979329f41bf23a4382495555be5eb2980315417a5fd58f5d9b37f2d9f2cfc9be7d14bdfa0d2237af1aafeb240b162fa547460ad555556c2c0df0f3a993e89496845e14da3c43bd283a248724521754cf29093fdc759cd4e0165c560b89f14662a3647cb5e56c5af10ea58a1d821e4a0a7702bf00607441061dd212114f7bab063c756cfff43d0ebb8d182595a2c39fa3931fc166b3613299301a8d381c0ecc6633898989d45457b374fb61fa446fa24214e89069c16c0a9d8ee9df21913e1d3390cf58527db8f31839d2d7384d46d292cd38a22cc40b796cd8b0980d7b77b3fc6b2f77fc369b5d9fec62cbcedd04750650550a3a87e29be96589f1fd7249880dcdeaa64ce9cf6f17afc7d84d8fa28ba3678f246274529b841180412fa32a410e6f5bcbe1c24a86df3e1d05385aafd0d96e444726aabf1c4d7153e55751104930e9f0db3a1074cd6b56d6d1bdfb796fc1c774bb793a66e71ede7f7536778cfa2b353535e8f286f1eb3bae67c19c17f9fad3e53cf2e04c56ac58c173cf3d07c0ecd9b3c99cfc30bfba79207a4964765515814080c33b76b164d16abadf741b72e52e16bf3a87a9c3fec29a2fbec694d585c92347929e914eaceedca7921ac331b515df65b6fdfd6dd1b490cbd9b60824a328501bd4f00755745253bb6b6a285c92a66a6c3a56c9c1a222823e378a2a919b664053350abf5ac6d6521f4659a0f0c03afc9e49689a46f7f458fae465200b3484876a6bbd2fc22edb0d037359f8c576bae77524d122535ab813476276b37b7a243bc81a3b9dc9033ae3ae3e85ce64e3e0defdec2cf2f0e85ffe80706839fbf6ec0adf6f10c566c208a0c6e962fdee93fcecb91749a8fa8a6d9bd6b5a88b48c8dd945fd59045e89595c2b593ef63785e1caeca9398eca190de7a5168218c000a5263c9bff94ec6f7c9a6beaa1483d581162d1115e360e34bcfe0cb194d9add46954526bfd735cc7ce82192cd023e570d343cdb28360d82e86ee3487f7e16cb0349140c7d98f8364e754fa76cff06e62c584df7319319da270dd5534fb42c501e5048126a10440b083a4ca2808846bda2a206ab1074cd3dfc5578158e39ddf40cb810cc194c9bd234c31892e3c0668e426749467396b65a8f511d63d09dd166e55e85a23a373dfd2e74f62ca64e0e3df3e609e3f9f8cb2dacfde4033caa9161236f6240afecd68a05203d3d83821e056d0ab7a3aa2a7bf7ee39ef7d3f2cdabe64eb9613c78ecf77b1afa8829e1971b82a8bd054108c51a192348d0c9b0efa0c65fac49b31691e1425146966d597bb99f8f8d374964f7268e717a08566659200126d1744e15a5f0c81d4e3c6e91c9cff2ecf3ffd071005648385fbeeb90b4992c2dee26ebd63127396bec5f6658026316bd65d24c447911b15e485a7fe80c516832a86ac6e0d0643d893dee94459cdf4cab4f1f2d37f20362e118f1aba5fafd7873deba5c4d8b07acaf9ed6f7fc7bd774ce3e6c96378fbb5ff659524a2375a79e4a107d0e9746775f53961fa04de5cf42a9b16879ae3a1071e20252581dee9c9bcb8e03f8cb8f5212c661dbd075dc3f18a45bcf0cc1f1151e9d5f71a26de72232693a999c24f946d0c1e91cd4b6b14465e1332e2aba9a961c58a154c9e3cf9bc6d5bb66f1dcffefd2d3287ddcce8fe5d90940092243028d7c1fb1b8e7083651bc6b83cf496587213cc7ca12a6c3e508ab46b25f1f9239b959564d5d32d2797bcabaea36f9a0d77d5c9709adce0a7f974ef816649a0a4c6498c29d4877a5168a1cc4cb119e892d381cefd4752906cc653131266fa8c1edc1097497df509e62d7897ad5f6f3aa740d2340d6f831dd2ee5dbbf8c73f9ec3e7f386d3f57a3d33efbc9b81030737c4a7f7a1d7fff0adb41bf9263aa494eefd195a53cf67f35f66052292ace3baeb46d121370aa331a4f71b74fd08167ef831cf3ff7670454060e1ecee08103185090c9fbaffe93b531f19c729910c450c825bd5edf2ee112526ab75f2809d5d5d5e1dc7bf6ec21100850505070de8c1e572db5ce7a5440d219888976100cf8f1783cc4c4c4a0287e6aaaaaf106820882446c6c0c3a49a4aea60a9737886c30a3067d242725525d5d8dc16068712c405315ea6baba975fb900d16948097c48478eaebeb1104019bcd8612f0535b5d8527a812171b8b28a85457d51050542459475c5c2c5e8f87603088c3d15207a1047d545755e30b2a08824c7c5c0c3a9d8e80bb8eaaaa1a6c7109980c7a40c5ed72e27479d034305b6c38a26c949797e37038c202b2a4a484750bff4a61fc547e31b917a2108a9f55575747f459cef77cfcf14a723b64d3b74f1f5e7be979e62d594976561a56838eb163c7327cf8308af6ace5f97f2fc02d98197ce3646e1ad2075dd0c9aaa5eff0f1173b106d29cc7cf041baa7363d23e0a965ddca457cb87a1bde4080ec4e3df9f923f7f2ecb3cf3260c000060c18c092254ba8a8a860c6edd358f8b7dfb3eab89b0937dec0aa55abb8fffefbc9cdcd05e037bff90dd3a74f272733912f3e5ec4479fefc01708d2b16b1f7ef4c05d2c5df42eabd67c818a8029269b5b264ee4aafcd60d3df7eddbcff1a29374ecd439246cbc5ede7a73362ffceb799cce5acc660b77de358bfb1f78108bc58aa2281c3c7800479495aef95dce3b362f77366fd98ac964252626aecd4241f17ba9753a09281aa22463b3d931e865aaaaaa888d8d0554ea9db5d47bfd6880d56ac76236e1abafa5c6e541928d048301ec360b870f1fc2e37613e57020cb325959d96df60eebf1b8d9bf6f0f63c68c3aeb3d757575ac5fbf9e51a35aded36e8114a175162e7c872327ebb9e3eea9245adab6057fba40ba12d8b76f3f478f9f202faf63b3a0860bde9ecf0bfffa27536e9bc6830f3d12beae280a470e1f223ada7ec50824a3d1f28d04d285a2baba3a345b6d38e86db5d9f9e94f7e8ed96269537e8fc7cdfefd7bb9a19d022962a97d81b9f5d64917bb0a9705a7db213572ebc4c9586d36860e1dde22aedf956787449b976c171287c3c16f7ffb642bf5695b3d2247477e0034c6dcba9250551525184409368ffb36e2bad05bf3f4eb8a72f1423b5f2c2267d9225c34d2d2523879b294f2f28a8b5d95ef05a7b30ea7b396b2b232da62d6ebf178f0fbbd17254ed8c5409624bc5e2f8140e0b20b63eef178be5134a2338908a44b808e1df390659975ebbebcd855f9de3019f4545795b7e95ebdc140af5e05c4c7c57dc7b5ba34484b4b63ebb6edd4d7bb9065ddc5aece37a2b6b69a8e1d73db9d3f22902e016459a663c73c3a76ccbbd855897009101b1b43ef5e059c387192e06516ca3c35b533e969a9edce1f114811225c82c4c4c410131373b1abf1bd13893a122142844b8688408a1021c225434420458810e19221229022448870c9101148112244b864682690743a1d2e970bb7db7db1ea132142841f3865656561af2067d26cdb3f393999b2b232366fde7cd905a88b1021c2e5416565253d7af46835add9697f0097cb45797979b353d81122448870a170381cc4c6c6228a2d35462d0452840811225c2c224aed0811225c324404528408112e19220229428408970c1181142142844b8688408a1021c22543abee472a2a2a28293d85aa9cdd6da8248924252711177b6578f18b1021c2774fab02e9e0c1c32424249cd59a12c0ebf370f0e0e188408a1021c205a35581e4f57a898e76307ffe3cbc5e2fd3a64d2327278783070f327ffe7c2c160b13274ea4a8e8448bbc0b162c60f9f2e52425258160e09a01c3b971ece06f54a9d75f7f9df4f474468c18d1ecfae38f3fce638f3d86cd663b67fe0f3ffc10a7d3c9d4a953bfd173cfc7071f7c407e7e7e3856d98562eddb2fb1727731bd7af765fcf8f1001c3870801f3dfa67663df813268ceacef1a385bcf9e69bfcee77bf6bf7738e1f3fce4b2fbd04c0be7dfbc8cacac26834326ad428860e1d7acebc8dcedb054160eddab52c5bb60c9fcfc7912347e8d225149ae89e7bee212727a7c5fd677272ff36de5ff836c7eb45ee9d318d8dcb17b0bd5c61e2845bd8b3670f13274e8c9c14b84239abc748a7d3c9dab56ba9aaaaa2b6b6968913273277ee5cb66cd9426c6c2c23468e6c354265454505575f7d35b7df7e3b208403286edfb615bb1eca9c7e4cd149e466a5212a3ef6eed9853fa821ea0c6474c82329ca425959196a7d0ddba2a3c0144d5ec71c2cb2c8b163c75014054df55352748c9365d588061bb91d3b12656c722c5e5d5d4d757575b37aa94137c78f1ce154753d6647021d723331c9221e5739fbf61e413538f0ba5d74cfcfc366355276f218c74f5422591220e0a477af9e64656561b7db713a9d1cdabb0babd948557d90c4ecce6427da5183f51c3d74984a5710642b3136a999f052150fc585859456d661b0c5d2a1630e6545c778fe3fcbb8f38187193e7448f85e8fc743f5be956cdfd489829e59a83e1f4545450ddfc5c5fe3dfba9f5a8c424a59299968ceaf7b277e736a22c46ca6b7dc466742427251ae9b450d8a9a9a93cfef8e3003cf0c003dc77df7da4a5a5a1d7eb09fa9c1cd87710a7572526398dccd424149f873d3bb661331b701912e9929d8c592f71f5d557d3ab572f4e9d3ac5134f3c112e539224befe6a0351663db5722c39e9499414eea3aede8b20ca2466e6106735b0e0834f387ca2969ffdf2bf39b4772f8b3edfce6ffee7693ae775405114645946538394971471fc44398a060949c96467a6b7796047b83c39ab408a8f8f67f2e4c92c58b080f5ebd7535656c6c1830749484860ca9429443b1c9c283ed96adeeddbb763b3d910242b9dba5c45ef1e49fcf1a93fd1bb5f1f2ca28fbd2502f7ccba938c38035f6ef80a1009f89cacda7a8a5fdd733d00eb761ec4a3a99496d53060dcbddc707546b8fcf2fd5bf978d5e7d42a065c757564f71ec7ed63ce1ddcf2c4d6b5ccf9f00b0c660b1e8f8f8163ef6254df0cbe7eff2d16ed77939b68e7bd85eff2bf7ffd3bd9711616bdf17f9c1012b08b6e366cdcc2c285ef3177ee5c6eb8e106ec763b8ffefa774c9a742bceb22354187af3975fde46f196b5ccf9602dd6d8248e1fdc45524a06bffef5afc37528ddb591b7de5f09462bbefa3afa5c3f8ba8c0718acb2a282b2d69b144eed1b72b89c15a366cda498faca6a8bb873f5bc2eccf0f116701a76267fcc4db89377a78f4f12798386912deca420afd1df89fffba1dbbb569a621491256ab35d4f1b28cc56209ff7fd7b2f9bcb1fe1889168d6a259a4993a761139dfce2b1df70cb845b71e45d4d765a12667d28ccb55eafc7e57221cb72b88ccaca4a1e7dfcd7dc387e02d1d9bd888d8d61f396add4d6d5a3055c94afcb64fa4d03d97bf010151515287e3f070f1fa6a4a20a576d0d3a9d8ebffffdefbcf0c20b044e1de2edf797532f58b01965f2bb768d08a42b80b3eeb299cd26c68c19c3a4499370381c1c3c7890b8b838a64c99c2e8d1a3d19f43bf643299888a8ac26eb7623484649eacd7d367d4041efad123c4e8dd549d2cc46e35d1af730a014f1dd515a5ac593c2f5c466a417f66dc7d1ffdbb67b1f5f3d5cdcadfb869279facf99aaa9a5a4a8b0eb1efabe6e9adf1d9daadc46677e7c1871ea2476e02dbd6ae0160f9aaad4cbef31e664d1b4b6e5ae8477ff47829c5552af73dfc08936fb80a83bea5dc8e4ecd66ec6d7772effdf7726247e8f99fafdb41628702eebf7726d7f6cd6a9167c357bb31c665f3c0430f33a8570736ae5cc1902143c8c9c961f4e8d12deed7476572fd755dd9bc613d155575e1eb8bde5f43ff11e378e4a1fbb0284e0eefda0180352e995193eee0473ffb295587bf22e8f79eb75d1a59ba6c3dd7de30811f3d740f467f1585fbf600109594c6d8697773e7e8bec458ceef82dd121dc7f553eee4ae7103c888317275d70c34af8bda9a4ad67ef01f644163d4a851f4ebd78fbcbc3c6eb8e106f2f2f2b8e69a6b9ab7d5862db8441bb31e7880871e7a802183af39cb1323fc9038eb0853549593274fb273e74e5c2e17068301a7d3c9ce9d3b292828c06e8f3a6b44adeeddbb3376ecd8e60f1205bac49991f40e044902cd47e98993bcb77825c367dc4fb452c6ae7dff0adf9f68d363d4ebd199a350fccd7555b57e85dc6e3db865c22d18040d9bcd7ade2f5aeb578832eb301a0ca1320355a1eb019504ab1e9d598f64b203e05534344920ca28516f4f46105bc6994ab0ea48b51ba87725a2a975e16738cc3206bd01bd3d114e9634cbe30c2858cd3226831e9d3506c5bffb3cb516e8d07f1cbd57fd91f7beda1fbe5aee531860d7a3335a91f43ad4603d00d12699ec6823a2604453dd80c6975f7ec9d2a54b319bcdfcf8c73fc66eb7b7faa42abf42bc4d8f64b421e9643425e48226ceac2337c678def66dc46e90e91c6f06c0e7f5f29f37165030f93e72ad5e76ecfa136881369553eb53b05a4d980d3a104404e9f28a4f16a17d9c5520555654f2ca2bafb065cb16626262b8eebaebf8f8e38f59bb762d6eb79b3befbcebac851e3b768cafbffe1a4190884f4826233d0980903aa36960699a8a3fe827e0f35056b487a0afc90fd3faed07e892fe3987f6ee24adf3f866e55fd53195c325d5149faa22d6a0a005dc9091d9a20eebd7af471064e2133319d8399df7f61d63f59ad51c3b7490b44e370130a4732aefae58c7804437a78a8f02901167234ad2f860d53aace5eb09fafd2dbea3008882d0ecfb0ce898caa27dc759f3c53af66ef902cc1d9ae5e9d7218577361d61d5679f7362e716b2ba3517daad21e9ed8cbde306163ff837e2d2433b9a37f6edc0aaf5db099cda87dba3119fdef58c3a35d1b76f5fba75eb86200858ce119ffdfa826c56acdb82af58c0e3938849ee04688882d0a2cc73210052c3fd1ae00b0650025e2a8a0ee17156b6b99cfe5d3298bf7a2b9fae5947b25d4f7cac83acdcce6dce1fe1f244fad5af7ef5fb332f1e3d7a0cbbddce92254b301a8d4c9d3a953163c660b158282c2cc4ebf5d2b76f1f3c5e1fd9d959cdf2fafd7e4a4a4a3875ea14c5274a3118a3c8cc48c6e3f1d0b56b578c46233e9f8fecec6c3252938892fdecda7590607437b232d3e9d7b7377ebf9f2e660f25659518537a306eec00ccb288c7e3a17bf7eec4676713adf7b367f71e8a4e9e222a219dccf494701d02810045454514171773bca8045917cf80117d90eacbd877a898f8bcbe8cb9fe6a4cb2487287648e6edf4c51a587dd87028c1c319cdcce5958ad020776eea6d4a951526964d2849178bd5e727272888a8a42a7d3919f9f8fa6690402017af4e8417c760ac19a931c385cccf172b04767316840cf70bd62d3933104abd977a0106b7a0137dd3428fcbdba75ebd64c87a4aa6af819466b32e9b29384bc6e74ebd68dd4fc0ed41cd9c3811375741b3094015775412784e6abddba750308b795d168c460306030189aed78793c1ef2f3f3c3bb59299db3a839bc9b03273d140c1a4affbe9dd0091a822084cb3c135555515595eeddbb03a19db5603018f675238b22690e1d9b37edc06d4c2725bd0357f7ed895eafc7e17090939383aaaacd9ed158efb8ac1ce2ac027b76ece6587129068b83ac880ee9074fabee473e5df5195df3bb70e8d04182c120f9f9f9582c165c2e17bb77efc660309092924ae1d1a30c1f36349c6ffffefdbcf0c20b2d1e3261c204860c19d2e2faa5404d6d2d73df9c43f9c9a3541b3bf18bfba792916867ebd6adacfa7405e5a78a49ec731b3fbb6d609bca5bba7429bbb66fa6ac2ec0f09bee66dc809ceff81b4488f0c3a15581b46bf71e4e9e3889dacab67e23a228909a9a4ad7fc2ee16b4ea79303070eb4b8373d3d9dc4c4c40b54e50b8bdfefe7686121fe40105b7c3229f1d1e84481eaaa2a4a4b4b50041d291999c458ceaec43f9d13274e505b538364b291969e864517399d1321425b6955200583c15008df7308244110906419596aa9f08d10214284f6d0aa525b9665643912653b428408df2f91f5448408112e19220229428408970c1181142142844b8688408a1021c22583cce9a6c60dbcf8e28b3cf8e0836d2ae0c5175fa47ffffe6cd9ba83e9d367e07235595b77c86d6ec876e870518bfc2e571d2b57ae60d6dd3371381cd4d4d45cf27fffefb5392dbe6b84961c3c143aee92d7a1d305f97f84b37339fe8e5afbfbff011173a14a5f01292a0000000049454e44ae426082</data>
+ </image>
+ <image name="image3">
+ <data format="XPM.GZ" length="75429">789ced9d5973dc3ad2a6effb579c68de7d31c1afaa58c52526e642fbbe4bb6ec89b9c0cadddad789f9ef03e69ba4764bb6d596eb1c9e8caee25304c1446602488094fbbfffebafc3ed8dbffeebbfff75762ece73f597cac4e95fffa52feafae67fff9ffff57ffff5efd168f8d73098fc958ce3bf46fffe1ffffab7defa4bfde50de8bf86eb3d70cc5ce4e02461beed78487cd531d557d51d8754dfa7968380ca67cc82efb70bb6166c7ce261230da7a2e331f13cf308f59b8d8e63aaef02dcea5b6b6609ae363ba6fa6c4c3c1a8c07bae16ccc3c19d2fd4be6440ee97ee91a71d0ea574970a2507f79d5f28858af138f1ba1f6cf823b7bc6cc02e7cb01b31ed1fd8ac58ea97d95259e242680bdaf3a9ed0f55f992dec616f88c3811a52fbaa0adcdedfe07cd40895477dd1701058b21ffc1db5e54bc56c0345e745c7547f19776ce87e332d8f493f1310c7c321b882be711b0f15e22176e610d4fea063aadfae1027031b24541fe233198ec6a48f59660eb83cec27869309ddcf0e99c309d55fc33f428c98af5b0e611ff84b3a8f93bded397898a07cb90416c14492fe839643b26731e998f4b3b09f728278c3fdd550e07ed525d8d983e2cb401f33b0433a9fa23d6668515ff919dc964fd17fedc8b990eadf620e428aa7721f2cc288f4b7d41fa8bbc1bfccae7fa07fef80451493be29ce0f0713d8c390bf86aebf0ca87f1b0fdc08d913e5474244649ffa88598574bea0fe3e0c1aa1fbd760a1438a9f7ab1638ac794e27f3876114de5ed37663d227b57a760a73fd59f1d134f9cc7e19f18dc9eaf0ec182ed99a6c4e13042f9f2062cb4c0fd683c73679d342c73f0c8c07fe51cb8adbf3c01cb21f7f7e59623f87395380e448cf2b0772c5d0892fe382f4623f4ffe2002cc711c57f85fb4b1948b417f652ce3e349e980178e82aa4fba17e351e0be8b30e966182f8a6781dea018f7779067616217f986de66804ff1f316b8c2f92cb077144e753031e8731ecbbcc9c085c4fe3f3d08ca211e927f6c1810b3862f8d3f5f688ec2f97994544ed9317cc0af690d71da33f9f816514d3f5398d67a34110c35fea8859425fa9987544facab463b4cf633611d943a33e0a78b2ff8039467bf47ecb01b5471d835d7d341e8990d9c2ff19f9d7797b027fab6f60579efc210366c3facd80c78388fa87b42da3bdf28679c87cca3c8a31bf5460377fd1f98ce263140c63f8d3e6e05112507fc83e330b8cff1eec11387da83f282eeff4817e7bccae426aef02f1b8d547f9cc23e82f7699273cde903f9d359c50bc7c668ed89e17e07110c39fe71de37e55c7d0cf631ee3fea501ab41027d13e2d0dd9feea70ae610f65259c7549f885a4e281e45cc1ca13f894de618e74b016e2600b22fda133542f65c02bbfb5379ef137314533cc931731cc35e6bcc4942fa8941c7d02f601609e6cb45701848cc87d03f768921ec7bcc1c23fed239e604f1ec3177f6d8618e602fef2b730cff8965e604f6904bcc22413cae740cfddbfa6442f156a0ffc489e6fc89f5532345acbf10274d44507c0e9963e44ffa90598ea83e85f872f96f8cf8d9664e605f75c62c13c493ee18f174d431e249312bf677de31d56f589f5048aa3f477f144e23aa4fc1bf622c303eaa596609fb79571d93bfd53ab302cbb065bebfed18e3cb6dc7181f63668d785465c7283fdb31d94bd4cc26c17c8cfe233a7fa07f0a3551640f8dfe2e9b16923f3e314bb0deed98ea97e89fd2c513da7bccac606f95321b8e0faf63b2af17758cf6415f3919092a6fd15f55ab8f84fd94f337d9cf5f61d6f0b7b7ca6c600f6f83d926888f13f064c05c774cedf1061d933f45c23c16c84f610fed04fe46ffd7ae3cfad341c768df36f310f697edf9b140feb1d931f251d843b7fec9118f2670092cf96397390860cf4bb01b1f311ea37f1b773fb29737df31f49d611ea1bd6a8d39e0f65eb52ca07fcc3c16181fcf3aa6fa15df7f32417e25373aa6eba5cf1c4be45ff09f9b6d24f94fc3feb611aa7f0276e30dfc077f59a72fd94f6d310709e2edb663f4af25e609f22375da31fa8b600e115f15ec63954bd9289ee8fec1603246fd6a9999eb931173cced371d23ff396e595279b1d231f50739cb9ce07c3903564ad1fdfc11b15bee707b0e9963017b7cee18fe94cc89803fab8e71de320b81fce7965962fe3034de0723b73c42be9032bb1482ce1be62484ff6fc0aebf51fb05f419b9049dc62f75cd1c23bebd3b467be69913c487ba6516b09fb7d731e2216d19f6aa697e09e83f3a7f026ee77b6f0c6efbb72798d93efe1eb3807e6aa36394f73b86fd569925db77af639c5fec18f325fc15b8053be2eb0cac8c46ffa5f9c6a55716fb1fde1ad85d0ffb6c322bd4e70d998dc4f83761761931dd6f0b1c8e14d613f0cf383103b247310796438c172597575663bd49f361306984ec83f64e269adb83f64ec231e23345fc8703cdfb37a82f0c02f45f1ffd259c18b4c79b65b612e3e317703840fca9fd8e717e817988f67935f318eba312f60a5580f14023fea25188f9d8873e91bb1efdfda6638c67a71d63fc5f611ee1bcbaea18f1bdca1c6be4dbf047a478bcf1d17f62978fa17ed931fa73d231e9eb4d98c7c87fbc7de610f3af6cebd392e2ab423cc73ad014ef1afd3b6984f443fc265dbe80fe96848986bd0270c2f166291f0a4423d45edc4f846e40207df79943e82f0473a2b09e9b6116b0478af6b8e52bf68b7cd85bbafaa8bcbfc6cce3bdbfd432f26791312b4ded29e03fe9966bc85fd15ee5fa0b9d4f3f811ba1eb4b70dbdffd181cba8c86ec9b758cfe3d6256b0a7f03b267ff821b351c81787cc5663fcbc0447a1c27a9ad6178176fa613c1980c304f6f3669885c27a2b61d6b09fc5f8a59321eceb63bc33ae3cdddf5b0747034dfe49615fdb089dc7f8629d7ee8efe89f564bc47746f58d07c301f4d3437023d49edd96b11e577c3e54f08fff8d59233efd757034447c79cbcc23e8eb6f774cedd1146fe3a1cb3fe0ff057068315e7939380ad0beac06c721c68382594b0dff92bddd6a73c8f3e501f318f1e29d774cfe2957c1a26d3fee1f3442f6bf65b6d8ff5323703450d43eff8239c078e929e608fa64343fbae530ef5f6b016efea3fa2b7018c31f7e068e26883743fe1f4f1aa1fa707f37fe723c6f80a3c4201e1799a582bd4ec16280782c7db0569ae22da7f1711c3642ed0bc05180f1c73f628ed19e94c6ebb15b9d8fd09f71bf284a509f19836389f9cdd27c378e1ba1f29be048425f85f289eb2f54debf64d606f6cd3b46fe88784962a5b17f0d7b2782f7dfaa8d8e297e2cf5ffb10cc6987ff23d702354ff31381e1accb73bcc82ed03ffc8d67e3efca7daf235ea576602fd52e8a78300eb6d8d78d48d907eb85eb7fa96971d637c837edad587e737a8df3442f7678e638378a2f5d2d83642fad2f837193442fe9fef18fef4c0f104d7db00ecd23f2a9f93be6eb1cdf9b04ffd7d1244438cff3be7e05818ecf76e83c508fb8ff51c584f309e5b1acf5db6cce3ada478994c5cc4607def8327bc7f2f8fc189827ef537706b1f4de3e7246c84dab7078e22e4eb05f409dbf239cd5793a8116a0ff48fdcf88de73734bf4de278a4c87f15ec17b7ed31923950d41e43e3c924190ff07cc63f0427d650fd25ec2bdafb978bccc100fd11f7936e40207f160b6033c17e83a6f89da846487feaef6e30d0d89fcbafc09318fb21e937662764ef839643ac27f8bc1406f335ee6f1a8f50f90b70c2e3adc5fd6d2364ff0cac15e62743f35f386884da7f0b1681a1f664642f976ca90195cff6c1ae07225e4ec16efac27e28d9cb653b23ccef1ef58770e2f243cc37341f86f41fb53f6076014cedc7fde346c87e371dc3ff9a5960ffd14b9915e777684f1c19b0c6fd12571ef9078ddfa1984cb01f5865602391ffe5944f84ca25d0b04f046e84ec33002721c6cf92e6d3d00885e71d9ae6677a3c877824fbd1e307acaf76c06288f127a5fee966cf08f3a1ff8939b1d8ffa3f55c144431da9bd2f8198d47c301f69346e089c6febb9e054709cad73ed8588c6739e527d47df0fcf11cdc3def586b19cf4bca10dc5eefd3f81e85d108f976710896c110e31dc5679488c900f93af4178d507d68afd031d68339f923924e903fe1bc9691813f68fc894cc4fbf75500d613708df256188ccf35c567dc3d1ff716c1d108eb79710e9631c6fbcc825508fbe7a47f3c8c8721f6ff9296b13f6d67c0c990f747a87fc66e356130de7d02ebd852794df9521cc401f6ab34ad3fdce43901175fc15a61bd9bd1fce4960f633ccfb134de37d32bfa9314602d2cfc370b3613e43f19f58f38d60383fd6ab25f9c0413d457913f63b7fa457f2da1afb003e43b45c93ce2f988e22b968d10a3bdd2b90bfd87ec1f2b21c7a82f034b8de74d92cfab00e39584fd751863fd9e8fc16ec0c6f38c9099f73bb343b09ce07e16fed02ac67c9e65cc12f9baa6fee1265327a4cf36b86d6fb10976f14dedcb281f8badeb50d43e730b6e84e287d6afc92094789e5332cb08cf5b729a4f936138c0f8981f82137e9e9b5fb78cfdeaec8c7988fdd28ad653c9480f911f7a9b6033b2c8ff693c4a0269b17e30a8df2d9030fed882790896abccb141fe40fe4cc6e300e39995e066039deae3f36efcc17a85f2c3c44da0d8bfcb77c1ae3ce6d373b09043bcdf41f95ae2d25d8c37fe3cb8d198ec2d9943ec9716d4df92a8e39439c27c9951ff4e62d720e40797e046e83cda1b0b897cbdc0fd5cef433e5fe27e891b0f602ff84b841af95641fd279189c07c5928667e7e91d37891a844e1799598039ba1c5fc027fe846a87e5c6fc210f9bf0f7b996484f9c752ff49ec3844bc642b60378362bebd022b6bf1be0d8d8762d008d9fb00eca66fec0f537bc43089f1fcbdbe020b8bf1ba9e05ab18fb05e506d88e399f277b89d198cfa7b87ee404f9ec05d806bcbea47875d9123f4f4c497f318ec66c1fd4378e79ff5e9f8305ef1f5b8a7f11ba0508fa4b048e46d8afd2943f88480516cfd769fd2262d1ce0f8a39c17ab4acc0ae7d785f6101ec0610f4270f6c23cec72f5ac67869a87f89241213aabfdc03cb01c6039fd69f6e781c213fd4f3ccbc5f58af8175c8ef2ba52d8f91bff1f55a623eb094ff0a3909311e163760375f623cc5f5aa118a8fb996d17fe416d88de7988f28be8516bc3e2fa19fb103d8bb96cc6dfb175ab6e80fb0b715bc9f98af83e508fda1da06db21e6a36a857984f582a4fae52032181f0b8a6f972c49ac07b325b04e0c9e9f1e31eb98e2ad5eee18cf5f483f3972092bf66b28de5d650afbaff9049cf07e4bb6016e8478b665ac6fcb75b052580fca33b0b1a83f47fd934688717d2879ff211db7ccebd713b09616f6a2f1c8a52b01f2836c8139627b8a96915fe7e7ccfc3cc0ec81b5467c1403b071330cd9fb166c8778dee091ffa59bc0797f701f2cf9fd8ef29639e2f73dae9805f49773603dc1fa4e537e43c31df22bd8c70524f6576adccfe5c3583f5a8a77294383e77f19fce76e30c6f503667e1fa148c05a62bf2aa7f894aa11ba7ea665ac4fea1cac5d0647fad1f8eb2ed7d84fab616f6d13d83fa5f9411a6960df02f5193b467fc8a93f491b0bac97f2af60b77e43fca3bc6d84eeb7d632d68bf905d84d3fe8dfab6033e1fe6e5b467f28ef18f627ffab41f7bec017b0e1fd85ca67e6f1a3386919e50d8d1fca2db7908f7a1aac2ddaafa93f28b7bac57c569e814dfb7ee26acbbc5f49f1e926b331f6fbf33570a243ec9756603763603e6156033c8fcf4f9947888fdc63e6f57359828de6fd2ab4b7d9ae44bc46ccb1417fa0fc4e75ef4f164760b77cc4fb92d077ecf4c77c47eb25e5566b685f760e7682fcfdb665e4aff531d88507f447fdae37e3fd169db58cf335ec1fbaf2648f94c63315b97c08f3cb0cd868f8a340fbe34688619fb83def5d80dd7c8df53bc5876a5eafc5fe2bf411c988f39d6f6099e0fe3a6496f0af1c80b545fe5c7c061b7e9e93219e641263bf25cbc122c0fdec19738cf14aa33dd421c9deb0af3411f65fea15667ebfb7362d239e32c48f4a34f6e373dc5f298df5490dff289de07dca32053b7db1bf4ff3836aa607dc0fed69b62f612fb45f9b31d61fe529b3e1f85e6919fbfbd516d8c517f2079abf9471190eecdb31de474b0fc08dd0f99b96a17f8afa8ce1fdb412e55deb916fa497cc16feaed15fddec82f5ba4fedd183365fc94fc04a603cd70adc08d537ec18fbbf15d88ed07f32ca57b49b0df0feaa35e046e8fa8b8ee1cf2f6033443e5e2d836d84fb15e71d63ff9ee2538f7480782f3e819dbf911f5f826dccf62f5a86bdaaa58ee18fa38ef1be6bde31f25f9a1fdcdd26d85f2ba0af1b1fb07ecdc99eb4bd8af550c9acb19ec904d8f907f9ed376683fe581e825dbe837cf0983941799fe25f371b64c8979798f97a7f07ecc62fd8f38439c4f85e8e98391fd0b057e83216b47f1ddcc66b655ae6e79bd03774f563fdbec22c113f29f48b24ef0f988c39c1fbb8d935d809c65fb42fb23c5e499a6fddf25962be91db1de379e33eb3853d850477ed5d658e515f06fb278ad7afa9648ef8f9f40e33cfc7e900acf9f9450d7d9cf5399f85bf85e6f54da19905e247c7ccacaf0ffbb9e51cf44d3366de1faa291f6cd2053cdfc96dcbfcfcecbc657efe80fee708eb0d5f328fb1be4a69fda6dd0087fd31b9006e3664a9ff6d31f3f3167f166c028bf7718f9823e4eb92c64bdd2880eb611fad62bc4f612f9905bf8f7206761183f1f79059a3ffd8bd96397f0c99793cf5602fedf4c1fbdd73cc31f4f1b83ed73ff0fe24e2dbc810cfeb34ae378d90ff63668bfee49f825b7b49c447934f61bf0af6b28adf174999f500fbad69c86c11bf15ec67cd10cf537c8a0f3370f5613fc2829d4591ef5f819d603f68bf638c47641fe3d617dc1f86cc7c3f7d016e84ca97cc23ac5fec2c73027b09eadf66e4320cf4c725b08eb01f917e051bde2f13aa63b42f651ef3f3a939e610f379ea33f3fdfc6b668bfe28a0afcbbfb01ed6687fd008e98bfb8f5d7c623f67c49ca07f69d4470f9ce87e671d63bce2f2a6fd7b8b53666bf1bc87e60f33d1fc7e8ad967b6180f2bd43f711a237fe2f38dd0fdc7ccedf3f335b01da0fe0cfe0e35e7e3f931d8f0fb757a9339c47866773bc67edd2ab8adcfa4cc43b01f300b4bf7b734bfb8de3942be550d9923de6f9cb48cf832df3ac67c38664ef0bc421eb68ce7257a07dcea5329e680d7e3d72d637f32a5f1cbf54e7edf263b629ef0f3bb05e618faa8a863c4eb2ab3843de4676685fea9116f716b0fbdcd3c62ffa23d89f300fc97748cf64f9879fecc2e3b86feebcc7c7f7d026eeb2f87cc13e43f06e585bb027f4f70c62cf9f9f84acba8afc4fd858df07e89a1fcc89d4df8f9acc72c618fb4ec18efeb4d3ac67cf0a5658cff1af126ddfc87f989c63f97cd0bdc2f457f680640e4db11b3417eef211edd69e44b1afe332eff87ff136681f6898259211e35ea6bdedfc0fb5d4bccbc1ed5885f375b63ffc622bedc688cfb6bf2bf8bb600f943b5c82cf87d977566be9fa5fcc95d3de4fac87ece5b63e85bec324ff87d4cf28775eb31d4577d065b7e3fb2d860d6bcbf44f3053d6ec47873d831d603cbcc11bfef16306bd68fc643ebfa37bf4f7ac5cceb1dbd047682f5e51c738cf9a75a636ef32fdd32ea4f293eddec17c15e62ccccf7f7683d605dffc07c21462d235e85661e63fc2e5b4eb01f5d26cc92f305ea6f367182f189fa8f1526c0fe418dfb09571ef909c583f356827c426c3373be592c316b8c8782c627db0c9f98ff43668dfdae0ae79b00c2fed671c798df2f3ac6f3425aef347fdd09fbe5882fab26f8fbb21cfa58cdfb21e68299d70739e2c59a80df67de62e6fdfc1cfe77d18cf594499863d8cb9c33f37e53c1f5b77f6f9a2fb58cfde77ca363d4bfd9329e47f9ba65b46fe7bc97e914f2a6d7cb740a794ff4329d42de93bef2b56f9c583ff5333f7f46b45f3829fdcaaffd6ffe11fd76ec9ff8a7fe997fee5ff8975ceecabf76656f5cd9866efd197fd69ff3e7fd057ff1d97a7bf90521ef2df9cbcee22b4e56fd357fdddf78229beefc96bfedeff8bbfe9ebfef1fd0af9ffccf8e0efd2ffed7eeaa813f746547ae7443813ff6277ee847ee0ef133f5f6f24b42de4b3cdfd75ef39ff0a4a73ced19cf7aa99779aecf7985577a95fbaebd6fde9177ec9d78a7de9977eee4c2bbf4aebc6befc6bb75bf9d93cc78b3aeec9c374fb4e02d7a4bdeb2b7e2ad7a6b5ca2977713cac9d7bd7567f10d27eec8dbf4b6bc6d6fc7dbf5f6bc7df7fb81f7c9fbecbe0fbd2fde576fe00dbd11955bf7026fecae9978a1177931ff96081709c2435d42082994d0c22d9045ca257a7937a11556263267f1dc893b12852845256af14d1c8963f7fb89381567eefb5c5c884b7125aea994132f1037e256cc78a1fb9c6d7f7d50d79c98170b62512c8965b17257a297f711f2deaa5875165f73e28ec4bad8109b624b6cbbcf1df7fbae933df7bd2f0ec427f1591c52a946be88af62208662e43e83eed7fb758dc544842272fe8d457257a297f711dafd7149a7afa59bf29aa3e62d15a99a4739eed3badf5327cdf94ce6b290a5ac644de57cf94d1eb973c7f2c47d9ef26f0feb3a93e7f2425eca2b792d6fee4af4f23e42debb95b7cee2334edc919c9573725e2ec845c74bedeff4bd2c57e4aa5c93eb72834a6eca2db92d77e4aedc13b9dc97074e3e493747ca43f9c5fdb221bfca81ab6b2847329063baa6977714f25ef38e1cbd174747cd1b6c89f295274325badfe9bb7999cb9dd3ca34259555a9ca54ae0a55ba5fe8cd3855a95a7d5347ea589d28a34ed5993a7772e1be2ff12e5e2fef27f4dce3cac935497374a36ed58c9a55736a5e2d74bfb7df8b6a492dbbcfa6e48a5a556b6add95be75c71b249b6a4b6dab1db5eb7edd53fbee9a03f5497d5687ea0b5dd3cb3b0a79ef6b2fd329e4bd412fd329e4bd612fd329e4bd512fd329e4bda097e914f2deb897e914bc29d5cb744aefbd6996de7bd32cbdf7a6597aef4db3fcb4f7c27bf2e1ad78452215ab44fb9afe264aab0fd7e7dde427bd17fafa4eb4fee8567c4f9a3f1ad0a9ce74ae0b5dea4ad7fadb47ebf45ef2f3ded3474e8ef5893efdc3bd77a6cf29c62ef4a5bed2d7fa46dfea998fd6ea7de417bd37abe7fe6cefe979bda0179db64b7a59afe85577b4a6d7f586defc68cdde435aefe9ad1fbaaef5deb6de79ea3dbda577f59eded7076fab4d7fd29ff5a1fea2bfbe7ffbf4400fe92fd29bbf6a0c9b7f195827c6379e110fb47562e4936bb79e5ae67bba367ff86fccfbb7e165f935ef196bd2e7bc476dc94cfeb6da4c614af75999fac512afce54cf97d057e6c81c9b13736aceccb9b93097e6ca5ceb2d73636e1f6afb6c9d334fcf7f4f57336be67ec88abf2cf09e9947049a05b3487a2c9965b3f29deb5aefad9ab517bdb76e36eeb7be8d64b369b6ccb6d9b9d7ea5db3778ff6cd81f9643e9b432effc57c350333a47323139895674b8c9fb1e6c484ae5d5b2632b1af4d627d4b7f99669569fea2cc3cf59eb536b599cd6d715fe307753ed0f57e795b3636b4d5e316fce7bdd7ea686bfbcd1eb9ef637bf2ddebda91f3c89ebee43d7b66cf9ff39ebd70e72eedd53d1b5cdb1b7b6b67ec2cd19c9d779f0b7691cb2f395ab62b76d57dafd9f5e74b3c2776a3f19dddb45b4dd662b7ed8eddb57b76df1ed84ff6b33d6cf5c2c869bfb82b683cb4033b7cc97b8f747da6fc63fd7e9ff7dc3d473668fe12d57e7f15f78af79c2d22fafbcd67bc97fa6a927aa9b87f452a5395ea947a436a61cd34e5f219fd9aa7455aa6555abf54e2a9a4dfd22373a3125fa7c7e9497a9a9ea5e7e9457a995ea5d7e94d7a7b5f2fbe62269d4de75ccdf32f79ef91aecf947facdfeff45eba902ea64be9f22bd7bddaf79ca557d255aa712d5d6fc6d187b6783adba41b36a6efcd74eb615df4eb76ba93eea67b2f9778c67bfbe941fa29fdecbc77987e49bfa68374988ed2201da7139da7e133de8b52a7439adcd7b5f9ccfcc61b99f744d767ca3fd6ef7778cfec66dc1b3299a9ecb53540e3bdd34e5e98f7329359575f9ab9be91e52f7b2f2b9a39362b319a6655461941f6ed7eb9ec283bce4eb2d3974b3c2fd959769e5d6497d955769ddd64b7d94c369bcd65f3d9c2436db9f462e646e16cf9b1f75ed4f599f28ff5fb1ddecb56b255bd4b476bd9faebd735ffce4cb6a1e9df9b7972ae6dc566d6c4ed76b693ed667bdff1de7e76907dca3e673413655fb2afd9201b66a387e5b2201b23a65f2af1acf726599845599c25b99f7bb9c865ae729d9bdc3ee7bd3ccdb33ccf8bef78ef81aecf957facdfeff0debd169479f5b66b9defbcb795fc38c9ebfc5b7e941fe727f9697e969fe717f9657e955fabe8a3357b0f79e83dbb9cdfe4b7c8a79e13bd996db492cf98493e9bcfb9ffcdb7bf7d746b1e4bbe902fe64bf972be92afe66bf97abe916fe65bf976be93ef7eb46eef213fb653660ff33d5d3492efeb8bf4209fcf0fcc71be9f7fb287eedce78f6943b32eb893fb675c7c1de65ff2aff9201fe6a33cc8c7f9240ff3288ff324ddff38bdde4b7ef609915ed4b7856f3cf7f9078c9edfb15194cf16a29085d2df5cd07985296c91eaf9f420fb58bdde45fe2e4f67ff9336fa73f5fabb78ef87776aff167afd7dbcf74f94de7bd32cbdf7a6597aef4db3f4de9b66e9bd37cdd27b6f9aa5f7de344befbd6996de7bd32cbdf7a6597aef4db3f4de9b66e9bd37cd42ffff0e592fd329bdf7a6597aef4db390f7f25e7e9bbccd2f6facadf7de6f96de7bd32cbdf7a659dedd7bbefe695d8a075416157dd7c5b74767fe23e2f43e72dfc7cfebef7e3d294e8bb3576a39ff6eabce5ff8fde7e547bd77f1e8bb95cbe6f359efbd4dcbab2725af8b1bf7795bcc14b3c5dc3bb4f415717acfbbef8517bd97178bc5d22bb53ce7bdb94767db56fec9de5b2e568ad562ad582f365cd46e165bc576b153ecba337bc5befb3c283e159f8b432afba5f85a0cb83dc362c43506c5d87d4e8ab06b695be7e3badecb7b51111749a37fe9979efb14a5bc77362f55d97c9ad29669493629f3b228cbd28d11655d7e2b8fca63f7eb63ed8a07675b7bdcbbf6a3bc579e94a7e55979fed47be54579595e95d7ade5cb9bf2b69c2967cbb9729e78a15c2c97ca653a5e2957a9cea25c2bd7efee556e949be556b9ddd5c1753eaeebbdbc57ee94bbe51ef969bf3c709f9fcacff7bc77521e965fdcaf5fddff06e590341a9541392e27ee282ca3322e93a72d25ef75678baecfdd5dfb3bbd57f98dc07b9557894a56eaa9f7aa669e38a94cab6d65abb4caaabc2aaa12e7abaaaaab6f747c84baabe3eaa43abdbb5775569d5717d5655707d7f9b8aef7f25e75555d5737a4ff55755bcd54b3f7cf3a7bc7951b05abf96ac169b1481ad1485ab918ac56e868f5694b1bddefcede79efeedadfe9bdfbdfd51af972fda9f7ca856ac39d772344b5c5da6e573bd56eb557d158571d549fcaa5eaf3fdf6144575587da9be76de1b54c36a7457e25e9d0fea7a2fefb97a039ee1f26a5c4daaf0e159cc7b5554c5e5a0badf8fdcd853fbb5570bf4ae47da158fce6eb5ad6daffd28efd5b276fdaed64fbd572cd7a6b675eace66755e372d286b37c6d7754dfdad3eaa8feb93faf4a1f7dcef67f579ddcda9f5657d75afc45d9d0fea7a3fefdd7dd7d7f54d7dfbe0ec493d53bbde58cfd5f3f502cd61f7bdb7582fd5cbf8f59176c5a3b36c8f8ff75e7952afd4abf5da7defbd9f3d3f52eaf57ae3a3757883fca8f7be2be87bbf57fe1356a937ebad7afbc37df3bafc98f72ebe2f7f9fbe3725f2ee7defc35bf44f92de7bd32cbdf7a6597aef4db3f4de9b66e9bd37cdf2eedebbfb5745ea9dfef8e38febddb796efbdf7e71dd7bbadbc56bef7de9f77dcf6bdb779cf95ebe5cf915dfadc2379a56cdff73ef6f86e94bc3f5ed67bd4f7f65eaba7f7dec71e373dedf1eff05aefbd3fffb8f7def41ed328f9e8f7d667bdf7fef463d7f3283be97ebf476ff5de876759ff5cd9e5bcf2fee7d3b32f4adff73ef218b9258eee8edb328df7be5f4fefbd8f3b86775e2ed37bef4f3eeebd37cdc7edcae0a532bdf7fee4e3f7f1de87675eff54796d1fb3cf39ffe0e37ee49ce6e3d7bca7b75afff5de7bffe3d7f7427aeffd29c70f57d6bcba7e6564ebbdf7a0357bf7f7245e6ffdfb1dc3578fefdbfaf1c14ee5ce735e7d54eacdde6beffc7cf9a9ca39f71e7cefd53b6f79fedc5dd3caafddf9a51af6589f3bbd1ecac37a70bcfbea7d77efd5bc573fc952ffccbe77bfdd77d17bafcc937df9c7fb846d3f791cf5fad13efe6bfa3cd767bed73f5f9b0f1ff4db57df1d6bdf6c793a7adff5bda77780a71fb7b8edbff75abff7f29d7ffef861ebefa2f7ed96e6716e4fbf383a3d131df747bc6723e27d8eefe6cc1ff7dee368a29173efa1d68f5bf0288e1f78f861995f9bc5db7a7fcd429d07dfa8cf5df9d6e76f89945f8fd09ff3dec376b57def1db4debbd7fa7bbdf44d23cfdebd1a3e60c47e32ba4e99f7fe13daddbf5beb99fb9e7c30a7ffc05cf4f738fe15efb516fdad39e793b1f61f2d6fcd39bf237f66cef9cf38fe95be07e9bdf751c7af79e63fe7bd7affa1fc5c0b1ed7f2b4d69fd5e767eb79fbf17316784b7b7fc47b0fcbbfe4bdd74b714f7fa26b5be6356b75f5ff508b1f59e807f4f9bea5df22af45c74b967eadceefdfefc93d76efdfabed2577da752b8637b7e8c7e392eeff82077ee0f8a7f5f9f571e16dd73e1fb92f1d3fec7bcfdb8767c64756bcfb65aaf639ff5ef27ac6d9e79c7fecf1c7652dfdf1eff19e7e6555d17befa38e7bef4df371efbd693e7e2fef7d78f6f5cf94b7e49caf94ebfbde471dbfadefe967ff42b395de7b1f75fc76ef3df7ef12407aef7dd4f15bbdf7f4b8f7dec71fffbcf7eeaea5ace5a097e914f2dea75ea6537aef4db3f4de9b66e9bd37cdd2784f25bd4ca734decb0f7a994e69bc67667a994ea179ef732fd329e4bdc35ea653286b99f4329dd27b6f9ae5dfffef7ffeebff031e8bf08b</data>
+ </image>
+ <image name="image4">
+ <data format="XPM.GZ" length="236911">789c44bdc7922c3b8f6e39afa7f8ad6256d616e55a0c7a905a8b489dd9d603d2456aadf3befc65c4b7c0bdf34cce320f771204418004c9fffd9fff5c1ceefde77ffef7bfde3fdcc76df79feec6bdfde77ffacfc7c7dfffefffff7fffcf7ffd7756e4ffc9b2e43f4551d4ffc9fffbfff9afff9e7d9cfda7fbcf2459fc9b83693a038407058e0079e616207f8c605c80abc640ce4f8e2348f5440d2800970f8032cf1660e74a206f5cb300dd8d4099d4fa4a7f0ac8ea6e018e12812a1f5b3db10e289b6a0e266e2a5077e3b000d30b406fe052a049c7c557269ecf364e60faf3b60069f85349fd5d04c5025c1f01b2a456f50f0179ea55db7b40932f0a363d5f01b4804b7ba9cf5597f365409feb1ddbd702b9777a626f0f30ba5ed55753a6956b73957423023dd15097b6a0a17e24c26c5e9b05785c02e4891afb7a1f502483c07b0412907f0294a9de71ce3bd250b405383d059485247632009a4212f35e206b0bd5d6170b90c782f92b4099aa19aedb08f452b703a8d2521ab41d81847c5519c824c2d31381201081931ed01792d849b700459695faecd103a02cf5d2131f81ea72e2006d2911ee48c84591ba4e6a3911083a262dec7947e3a552b30f15ac8cd51f0f01e14f7569013e576f3855eb9769854c8fa47465e64afacb1d60a8d4fa87d2b1d0052b3eabc62e4ba70e347d577f292bd7e9a5ef9700dfa98b75b70275372c946e32a160f5488f721261d92483de51a85daac4152ac7e707a04fa56387d2a02aaf2ab5cbfe1ea0add42e877f0057e92794a3aabc4b540e19a5aaae46ba98cc569d0c7cb650f7a8d3b29406edef0ae443adc6de55f5eb22fca727760059adba1c2c016aaf9f3c0b34f33e25b5fc1508d6424fb8bd08f4d241ea106c4329d3b72f013545557b5929297f533b8970e2bf045c8ad5be97d4db342df48ef50740954b622b52cba094ad647a940954decca7e4d1b69553bf7d1b17c025233a964ba5dcdcb22dc08427d2a21438923170595e4a4f87296028d41b4e2464173e8b9ea611a81c5ec6d1071101ae012e93082fd5d83ecd73bdf4819fa4d62bdd19a02af58eeb1f405daa722bea73be6a9dcad19f0bd45deba441eab7bef389de31d167bb6041548e1f296e97baaa560752337475e6d4b69994ae6b3cc389df1468ebaed05772813e8c392aba5eda87970a8c790434540ff0eab7d3c70340a7724c0fa5747d18e7192cf6014e7a3af11a0afab64ba41fd7af0b3004bbaecae5d2a0212de82f5e0d356469adc69ea97243317a4c9fca3154fdd8a8ef4b62436da3c7d2b1018fb9906a0f5dc38033caff18a3a5f3e78026d1b0f6c6139975c29b274085c51d3722d070d27f44a066705706b08527ead9a3157dfaa6ee31d669d7aa2e5298b16dcc5550bf1d879496eb16463a98ec92aefedb0346c0e18a40305b2ac7de814031481ed3972d81f8d9e9b940f05024c2aa10684b7906937e04d4a94c5f3f001a81a95bb47e9a0699aa1ce327a0a7f59f7281b4c628fd76025966c3c9a340182c00b78011e338388122472d7755f4b44c1a35e5f221a0f03228eb35a0f42ac7db9e409da9fad3725da0ad6583263d056b9ddc8d89ff11701e5bd8a972c19960147b4e015d2911f62780a190269fbd08c4d6bf1b0123e0654320144cd641462980a297aeab57a6e1abf250263d4fb42d8ed1ddea020497054d1ebf04d20ca7a6fb16c87c83315801f48d647af31181647ab023507aafaf146a97bced70bfaa123000fcc28ca7452cc7af17c8ea52a05b028c88f0fa3302b57e371508ce945a6e47422ecacceb2707cb80dcacc34ca04e9069f32ad032224fbcaa5f384753fac5301f14a8a2a46e0d30e0c24d548eb2e82a75f53de958193feb0f00057a7ad4022a8f75d81468ca563d7ba22e56f6d8c2c9740f6046a993e256c19dc05c14009f4ab5afd5fa556cdbe75580b9a3bdca51651603fd9c09e43575d99408835f407fd93d05f81613cc57829e4ab54f54fdaace10f2fb39a094e24edfd208f495ec49a04d18a35c0e28bd5e7ab50ee80bac36efe89b14214b61eab4a1fafe14603edd8f7e52676da6cfba0b81bcc18cefcb4a055faa964a552a47ddb6e8477f03e890e9c5b1c0dc01d14b1736396d82cb220dfa95516ab211a3f4d30804c51598a9ab37a1ef4ba5ce9e05a29ebe0f804a129b7d481d9aa66034ed1f049c0d9e85cc789b25f8a7de015a737a6b80d9a07d758f3677b51aaa9780da922e3699aa23b7d580d4cfde05ea94925e4a1e6d6345bf4b01841ad3bb4ca04d2d0296fd68fb442f9d4c77012960c24ffa96cf3e4b615c507ef5ca4646c905d556d1bf2453975938fb29e57779220d9a7e4e00d672f93ea06a24a0d363405fabbffcaae55c5134d28f03194717ba873e7b463982f20b9c97807ca472db02a1b608489ff5598141b9d903b4b4cbd735a02312cf5e003d7afa29a3e4f38cba7c5c44a0a27fd81305eef9ef04509a23a06eea83015143fd6d005ac2fbdf1ad03343727924500f34f6511e012f4d049a94202055cbf9d66b989ff41a2c42d0448fcace0036eedf5117d38fe9973a61970db94aba21031b869b9af856ae4217c257c9749b9f84314a229c3d452073717206e8bc8afeabcf7655e5f493568dddcd2dcae22b1d5f09bd5295bbbb0634e6c22580b6d357f6a4c95d5311d024eb8006854936006ed413371af8faa0eb3217fe04d0246adb42a3479f95e8e958011cbed49784dc07e5976ae707806097a41f2f809289888f7540c584c8a7811a90ec1bc055f89d021acaf1d3025a0cec9d0cdb3c2a1078a31c458d4a9dfd0a5449c7b49c070423a396431ef3405b3f5153f67581d4cfa97e6c86f71b406c0619a5e0d2a0965ed6b26fc70e11cab00d715672a20e340481d10c678081f165228519b224434fef04422794c9f9ba07e4d64d5f0175a1827d6c001aa67f7a156c08269879a943405aa9fa7b334087261fac027ac0bb0cec10abffb61b81be5252b9d02b557d0567e918224b221c7d760cc327a3876ce118d5e1839fe46d21797c6c025cc94fa43063d1daf4600ee89ceaf27229503b2be957042a69a6517d8c25bd3802743217935e521f5d8141c917fa9105eb81f9bc5e1598ff6934bd02b4993efbf520107a83aa7f5c001ae2b98f778067de61e35020b8b0f8dadf0057e3e47d01c616df612a6063c3f4ed1360b5ddcb059a127351dc0884dae2f3df0bb886c9d0c9421e591a460729ff632990f584809f80301448933fab0824d3ec1550352a7a7e6800afefeb115033a9f2b32f500c1615ac0984e14405bb3c1008dd549fbd3c0338abfe00f0664f25f5e0d20d1a2ca65b027d99eaa5f9a2b1b32c1999e82ed60542d488d2498459e8732afa670128e895bd3d6193194e0d95953857d3df5f81aa60e67ba6928668058fedee015099db43c1ead66cd027a0ebf083a44159538d84f7cf026ec0a3bf9380b23ea7cff50b239de5514fef4f010e3bf6990984da12bfec033c06e5fc4f20e8a94478b70c181b09e8586a995759a777ac5780ba63f24fb59d5b2dd5e5bc06786afbda013a9af2ed0ad0eb2793c9a540e7538ce3c2750a5e508d1fb4f104e8009f9247112c0c4e1e4f84ca6182d52e45654eefc13aa0e854b9b55540d92990e81a80273ab97002753d4aa5eece05fa9ac93f4d776465da62f9af2702a11904bebe001601efab3794794f7cbba3862a63c12ef704c2a0a50ef4de030684dcaaa1cab830b47402e8182b5ba943195c27f9eb5ecd50768d16ca26d30d81e05aa3b8322855e214574e34f99755f33fbdf40ad05ac0bb2d103a10b57d060c2c51accb2855458e6f79b72350e644f3337e5255147d7504302b393da660d588fdb89090abd02e321797bb0093d81b5f89127ba32ef508c88f05da0a6f6b22d50e2ac7d8d0abf5ebe0f6e8b3cb32e375e9f0827724d3baaa59d32aa552a1a7d3c54659ba264e202a38cb9ad05155fd9b2d4093abb6e333a005f4529826776850d1028616e59731688a8489eefa129032be1c978086d5846d09b9092aa4da1e481d9ad00c52cb83ed08f4d24bd98f26d44ee0ec0d605dfd651360427e97d49b26e954f484ba341ea95f0182c4640c349793355dc13857c9a0b46987a1bf9e09640ed337d90278d4f2a58b40cdf0f80b187355eee1310209f94963651b4240060b35433b5f4b93905f01396b6b9b4b02518413f5dbb6aa99403c9e001a34798faf542d60fd18e03bc204b55c1b2556aa5d5a13d0f45aede2cc65996aa12c00b3966be700c7ec463f0174ac9ab7971148844f8711e06ef095a268f5c4e13a606854b00349ddc5ba9c9c47c0b8bf09703cb1fc235027e8c78bfaad8bb52dae05820962fe544de99311a7e65ac6c0c7a9aceb1581288f9f57804d11f411981f9403acb69a4399ab0b20936afba2745298936340439fdb91087d30064c8701aaa225ae7c0138e4b15e02065cda57ca518df4b9990cbdaf3bbac79b9ac13759afcafd6d02f8c9ec43835688a299a44ea5da3e8a303b8940e34b89c45c8191aea496de17ac56f71a9282ba642ad8d32c02a6c2558e2eef481a38527fe9827e48843feab75d593217bca731bb0bbaae76d93b0674445a677f80de7a83742c8c59e8c7dba601e471265bd8395b137f944f17025e0cec4f0630e5fffa04f480fb930898523b8f80d0eb1e306452dc3d296e5f762c4ffe6a98ef2be7f4c42e2f0d5eb1be72c94bebde7c5cf5ecbec9559749a7e1b56f4b02bc5399cf2128bf14e656b51dd2843c831f2f102b773d8d00a37409e869b9eb0b80d5e5fb0060b6f053bed450d8baa9567803182aa9c39e2a378486a2294f0103e0d845a0a6dcc90123e044ed32d435dde3889236a929ff3bc004343d039042334da57443d064157da22e36863f667a5d046aa8ed5b8158b035f586311825cce71320a39bfefe000a4fb8b203e8895fde55d23184ead2f5760b50d22e7709a063acbc508f1a5d5e12d048b5c721b5a65cc8234f6243bdf40279ca1cfdcd0c9001b4ca1340c954e7c98540acdcdb2da0a3fa97f6c448fcf2068875398a40ed32914dce93ce31af7dbd18c4f3d44cf064a292a6a12474d32f81603e5597720ae8bc9e98bd0ad85ae374f611813479bd0054f4fdf76f81a634b01501992a8ba131c44ce67e1de70299253ffd1d09e42911dfe005ca045d3f2a008d9390f7d70103cb60b7bf06982eedf86c355039a59d0430620b375704626df7b7001971e5f201a0c4f45d4a1d826368c1c8002868b9170a16e5d12c2c5d9ecf7bbfbafa44206f49c3793816089e233302e7004bd439dd13289b96a5b43f812aa737fcac036aad584d676f02754e1cb55344c0d0f80e2878627588404f9c2d45c03cdd05a0678def6c133020c2bb4703033346d2c21068a00e57ab02c15c287a753702bec02f1c16063688c3e6fa6ef49522885d864dab4d79117448b53d19013971c3c83b725e3a51281afeb7cef58eb533001977b38f04d09166914bea21ac6a0845d5b30b5bf29d6edf014c402b57801a85797d11686aeb1e6304ccafabf5435b97acefaba10a5f228f5bbdb49c2f0bab724f023104dcac001df268f5d232f47dbde3661790f293b104641646ce0c90ca732efd284b874a6dfd0854494398d002bca2c6891641836f9e60d8365701a5795b7c25545f5f797f8b40954bf8498846489e7c1030014dab0ce099fc6ba51fa5afa87ea79e5d85315bef7851eb57218cc43f950daa8a820980448d5d9505aef5f907a0732ae9e93e6020d05c3f11a82b2a77721981e2fd4e2a5585088f90f81cd0a8b6b38f53804d31160b2f27afc368a29eddea277554dc1fd9b13a149d59eb5580c75c7cb68081e4964eb5adcb9cd5844355aeaeca96cc8c2340dd9088110116e65836b90eaa4de05d011aa690bc468fda27947454f7686247fe546d9ba225b1ed5cc6b12907ecfa8e34a8095f5139b6ef010d9f5d5b8e40867ea704b480f51cd0f56adb77e947d3b480bd2b80c7e29ea8b64d9be0d49c510e6709438d34a8093aa682b5b274a114e60868346d9301a5cb35ccb7698aa378b509a859f06f9e0582d11198ac024a3ae1a774ac0d1223914bc37c5b5564a9ed1f025a06addf3fc08817fc2b21b775ca48785602462655dea5526de324a0897302ae32793480b6245a934171f35914155d6deb829e4a1edf520717dc0dd4f208d0a2b89fc711507db58b0b1645123bd5001c5ac13151f500701ee76a02f0b8f8c7aa8bab3d267873cd0026f8f83a0295f46c19d0f1c4ee19a0a71ccbfb80a1c7dd907eb8c6669cdfde0088705a48f95d9ba0eb852cbf7335227cd04f7c6a0bcba91adb07275f6d9b48a57ce8b94c548d00cf38d7aaa4bec898eafc9c014cc85fbca334e76ae71c50e10656eac82168c63a9c1e012a54eaf410d09890ed272d698d330de2be4e6897b56780497dfb0160426e34bef8a6a3a42dd56f7ac08194cebb1489150b9f3fefb20cf7fc543ad6052baeba9caafa5d289804b49b026c4d6b5d7adac572acf680de86685eda98fdb850f5bba0fc24faa94775d165b9d567fb948cbbe9b53efb2f58bd91fde863cb7d4971fbb2207d2e7b07d8cc557d058809ba12725fe704bcc723c08a7edc4720955ad758d987589dbc1ccad13200cfe8c8bdf3f47d2f85e97d8a93d7c8dde8bb860878d43837448ffe519a3ca41d4b58d7b274439c0fba51d18758fda53dc0c884ea918a3ed4094a773c0006eab2fd0818016bf24f8726a1232fff02b25efd65670668e8a6750b680715eceede004ffc52b9b6c187c9d41b06d79219fa26033b06ef422af528c7680c91842a772c4d1e63e50e782244a27ae250863e04bcd8e48d7d408a5d3fae0d10aeacc89918636db75f00294669e708607579df00f43c7129e51f5bcb0fba5b07b423abb3bc235afef329a0ad70e05700ae227ffd1a6033ce95a43e7a87f26b413738f4234b69d74f027102f1fe0630b0149f1e08043f080ff65a206ad0f9af40f0c798fd6a0442804786fba540102183c5149021d3e32602e6e85b400e38fc017464319ead08041d934c2ff60185a59a6f0a58179b36a380b380f771613f8ae08ba3300f2f1110f19d0be403cbf9bb7a695a64b66cac72a46546bb2c2d0b5496bbb1f628102a273ddd3f0054e416df518ed0a3c8cb51bba4a1727a62fd0c9053db770f18d0c2b70e30f66ab9d3851d9b6f90d172dcc401ace893690ba819f8564f04aa4e91c5f432010cf83017d28f2c1803f59735492c8bcdb0fd0cb0922eef012a2ab79e02ea5ef2b8ad00b610f26e2fb5ba5c4a71b360f8d5911bc934eb3c3e5db7f02e8a3cb56cfdeb67409c1bf780829f3c480b43e4c5bae90b4fc4584c39130114cc19b409a0ce11f22030ff933c524049075add11a84b3cfa5dde513768f211efa8bd57d1b75f059a14d769b50314c863e718605b334eb60183cd7f1818d1a0b7970854fd3bf5a8e0e40e0879db00efb8da003045303d53438561af22c58aa2fb0ce00a812ec5aeb73340455e5fb698bb2842b7244d6bdc05d8aac6c38340e6526637a4fc8b7faabe6c5011e7934f4e0db02a7a644f984c8f46406736480d550499b284b50e28117247c19a8ea9ac9d130308e89577b4293f29df00199ec1410dc8719d0ea574f34904f5b9fb5b81795a85944eb6703e45a0a567ede5090a65cb71676ab932c4b77ac7e1276020b57af70a3092d7b7afa62c9b044f7aed0f5033449f5c45a0772cdb136daf77ec9c026c41e65d122b63f5af9600b69767db012cf1b155bb94be259e4ba5eb55e895cc08dc01bced6bcc05a20b77a1cf5641222cc55f002ac0a7e4519539aec2e714d0e0e4ed48a65514d0d6b74010902ab792024c1eaf6adb2ad676e70c6046e942763dc444f48644fda5ea7282d5515fa943ebab57fe5c00acb6fbf7029963dee1fa1c40f5274ead5fcfff164ffc9e001a72582f642eeaf9cc8c54fb50a0ea599fd35ec039b0953315bdaef38629138dd97553b3e8976780065f6afddc40cf2246026891d8dd07601898852b055af30bcf3e0196fc94c95cd4ae67f2ef5423611dbc60a6c28f01356e7125c50d7104767d65e1d1877edcb67a47af966baa9429a472628019d6c32f81c6ecc741052899cb39fc36c0136baf8096eadf45405deef86ce300eb09a0ef55f4577e12e5f1c6675dd39352740be8d1b151526fa3cf9f69786de7edbf0037cb00db3b7b7e03705898d3258007acabcfb5f5805bfca3bedf86dec08ad50028497ebab835c070b2f505a8314abfdf114883ce56011de3fe790e189962bc90c4dad0c5f493ed09c0b27e4f1f019e15892b6aeb13f23e2772475d9ab13970546f70b9634fe2f521c0b320f3a58eece67f324a4b0013d0a7ec982b47b218b765a45d9d910ab829bf703eefc070b201f0e8c7aa0758f5cf362250e5967701432f63702bebe04298c0e47006886bc014ac35cfa0a5e8aded6bbc90d5f669caf0fa2887c46796a2e925649f5bfadcd301c0e1f66caacff9288fd53f404782ae9f017adc9e8a27aa162f38df05742dc9e8ead9beb69d6d1712900f161703db032c67e2e01bd0f574c25f408f4cf7e406fa36b3f9a03b800df3af478012b0b705686ca25b26d807a786ac1b35830fce26fbe6a5a75ddeb3aae154b0ae18484c29d50c5d999072e6ee0074c2c9446ad955b65cbb2f0dea9ace52242e0056b9b335c088c2bc03625d12dee1b2512dd755008b2c8ed509bbd05ff48e520dd5f50543522a47b10f4133b198c6db3e3831c49509c036e3af9e026c2ff1df4a0424839d006caaf302508d165849c7fa107931677060007763790990e15bee51b0e8b01ebc4680476fefa810d06f0518583a3a96087b5fd6cc18494fff4d994c24d3210401cc8e36808ac9e153d57688adbf9c012c4fe951421eaa91358b4c667ca82d586d5e009649bda7217a682c4d6b253340ebaf490b8736019cad0352c08e03d88eb2d73580c9637d0074c863456a39b804d0ef011892a699cce7e06d83612fe76acc2b96055735e08c654ad6cdee0f20c7413b7d010ca6fc1a4ec6c66637b6e4198caded37dddb00d80aefea01c0d63cbb85fd2893b4c3973a9f0814155315372b001b1a9756054acb0ffa3d0550f4c9947704ff9cfd514b8091c494cfe5083017a94095d1b68f5f02c1a9a39bee026ae6d8966e014e0efca4eb059a94cd0ac77c2508882cf93b40cff8b27e29105a9fb4b51a5058a2ce26a0a47b5cce00b56dcc790578999cc9f404d0611c9b0781791a92facbc20497699c207aec04f28ca8f1730f50b2dcb2b62130ff53537e0072c0e71f6064547f50c1d23a670162fb00d0106aacfd08b43983e7eb3ac0fcd3ed1660fb3db6a7022e218be0f4193090a0bbb498530a6d6f19554b3b004b17db9d013acaf1f90b18287aa6ca659563a666e90630b2d8f6f024101c763a9013887559e6b3c143234f7a02703802f509c0636176a680ceb6654971b38eede9d399743d4f3a16ca6ef4441ebbc7e928306f1995a300e4d61b7e0003eef985543b6f1a9639d6de05c218c5f2f507c05612f7960da09677142c448d6aec54ba3e5f8091c466478010b048c8bca3cb195f5616be6559b41583c5fa15a0061cbc00ecb36fcb00a7b172d249e982ab8495f22f06e81eee015031f0959247183de90dd7aa4b19a3d7fb4781bce64c84fb09a029e97395400857e5089ccb4a859720d3a55d40a927263a9923fc5f459ffbfb05d8925e3a024656efeb0b81caa6c2b7a485659b302fb5d70052d6910f3e0026b1e56580630a69eb1d604a37a5fa2e6e615e02a44c2096bc23f8cd4c412f7ca9b20af25037fd5317ab2a9b43f9bc00b46cc8bd913a54b527becdf949182b4919b917083d8ac193afb4cdc080f326e012628f5136b94e7236d33ecbe4d46168e0b38940903ae99503a0a6199654dbba292c6c1a0125ab1ad536c0120f5e0e058209669269153060d7b764c742608ed9ea7e010516e646456fe21cfd8ff4749effa0cf7eca0437956717d6e725a063efec4ce5684247267e919e36a1b1f59552dda37136a7e48e00290b105bf6448e47bf57003abcbe512ad5c65379ae4a81c21264bece05e67f7ae213e00099ac765bf736dda186fa17bd6ef2d2b666ffcbce3ea045935f3dc0a2b52d75f536c8546dbbc5579cf9da0fab800a85f152cbb905666642326dfb8265d26349dda57622d7a8d67759457076202be5e67f32c1cb004bb2c9d5a35c35d28166b2fc2ee8257b246e009d6327b96a1b3c381aaa2e0c50f403a9946b2b66ae5678a2ed0766f129693b0e12d0037589d5bf7903d43d499cb21fc1a52108b8914c7daced442ae5abb4226a94fdf08de54cac6b24f46dc2846af203c846e6b5cf008eb5a4b50fc0c0ee38ad8b95219eb339c75b40c5213ca3c6ca6ebef5710106bdb48bf374d7eaea5d34e30fd2c22e2f91d8b2bcbeae4a39cb64f51de099849cdd022cf658527fe98253c3d2400f28b1c99a960bb6c2c6ca8b3d80c7fb4ca41f5d889248a05a029880925f400eb87800d8daeb0175697bb3eb1a4e421839086c3580867998c76b40ab9e3d996abced7c8ed5befa0304db26eba04ed875e6c35c2f02efb28f91d6b64c4e9fa7767ea104d4cfff6472a40e7d9dd309773b408d0897f4d93e44d1f8da8058fdbd4b408393775b02acfa075f8081287a4d02ea5d3290a378013023bd3a038c988b56dda38ff2385e0198c5add46ffbaec1dbba966730c4152b9d76520ef30528f5069e289c1653269d946ea82d6b6f4346691ebee92b6f470698c55f9d1a18f0c6bf00296083af04e78ae45a556e1812ba69a9961b535b7dbb51338c71c0b997f28f85fde4542ecb58925c3bf1ab00f372563f01962df7330246c0a6ecd8d8d8a144c90ec07ad405056b460cfd85ea12824406ad17d56534794cf0e9465ff095a6079428dd8c9f78c7f996997ae518fc667d655cd4a54ae2a94d4305180845c789c07c239204742d50e408a87f06d811907fbc74fe2701ad017acaf1fb21d0642cfbd4298085a189ceea0cc0e693b5272000db63f57a26e06ccec06d012ce37fa534c031812b4f0012fd26ee45a01b08efaf1796ae4aa3260f47808e75f5415f8959f2d3d9b6405510dffe2d032a405708d4ce1652bd01c72ece6381c6321097ee045a9bccb878058ce8fa3b5f09eac06ce092019c2bb70bb0c4e9658aee6a52abb76a80c37eacf4023ec1edc91e003906a5e5a5be2f392beb4fa0b329e889ca91a596ec537c0bccff16e0f351a04ed1c299130845c7a9690119e55831500eec25de0354982dc7579c1994f51ed023a0153eeb537e52be002c8f3ebd01380ab6f100e86bf2b6d472d95830783e2cc6a82acf3d734a0f87800eb0aa82e5c10f52d17fa602f3bf0538b90694ccd12fa937e4c199606ce02b6d86713c7d00e4849179012858b19aa9dfe651a6172f00b396174f808c18e8e0d9001ab4bc0a0846480a53012cdfa1e2a5be20c37dff0e50d2d52be4e19b923e274dcebb8ed16350372dd2962dcc1a1baaa26cd8fd54df017a1aea2213089d8c937d56010581669d083435ced5b607784cf0e69e01967dcea563456b7b684e78c2d9d93f2b15a0c6bbd8d80558e03de12bdd884129d572c590e019dc2fa2826a1edf1389eb897944aca21faab665acdc9607e4ea40139d6750cda337bccf0d81d6b26e96ee0196367fa1b62d9de54cbc9e020acce7cd2ba0c733d82a0d50fd4de958e9ed6081ed7d812e6b883c17de4555c535be4e56aa4a6d7cb9d64babb8a7e87e5da070f8855fef003b0ce846ea5059b03ad1c69c6a9e7aced103cf00cf4484d2f7abc53f99ad0fc04056d6a70454d5b99d052deb10026f966c724a1afc531c5675e42aa803a1460368b1a7e30e602078dff807f48edf2b816060f595d54340ce4f1a8d40219a3577e31780c59d8e8b70a5aa6352fc95ec7a9d0e6cfcbc97e90bd10b13bb3752ba7ff17ea6a2d795e57e7d4ae9eabac0d275b20e756325fd5d0214c4a66729a0c706dd6a44fe17de67f7808258ec9582855054057b398a006bb90b68981b7f4d0c30ddb152031c525fde04f42393b2d28f3a0819bf702d027d65631b6033cebb6adbba4bd96771adaf34f3f175019ea552cd7ca24e32556d9b28d3cb2740cd3e1c9deb543541edf4d29f6580cd4c7caab19b20758e6dfe055415c7c1f093da7e72991ab0ae9e013c9d7057a36913ac27e7a0ed0046a6e46fa50e8db3d5a60b9ef01927a56dac1b601e77632b02f5978d0d40dea330eab74d5750d2e7c1002dd74ad79bde0ee169358a35a31d9c77bdf0c6439733f76b4c00d60ca57a655bd87cd0fd930196c1ee3f002351d2aaac653bffd36765d7db3ab166b801c466580234fc64536ad9b629d661e519903315bef403b05d256ba7808158fd48526f9d9d43b2bc0618499ddd9026b73e27bebdfa05d826c556adef8a9470e5e10f50d209efb70015cec4e3216040409d14c6558ef5b9e5dc0013ff9f72485c5de207b5ef007ae5a4e7b335a3d8b452d15ddb30b9f3a2ee319f54e1c0983a02bd74e50660fbc4b734be386f2ecba83ee7a3a5fb913c7c6efb5f6e7a80856f0f6a7d5fd41ccdb9311308211e5b323588fbd06df544b30db09989dd4780ad8b9d4b837c9d35f4ec6740c34f96a4c9beb5cd0a05057339b3923b7b8092d67f3d019880922d809d18bbac2ee67d461a4ef506b0d31b46bdb48be3eda841bc8b87bd8c37003b23e20110fa0b464995ebe67ff22e468166a0fa850c4ad73afadcad1aaa8b9a7cd7031ac0c536a0c75568ff0c90159e4be93a4fd03cd1945ad5758d9df3ad0ed4cfcf7e5263abbff431dbe5c11be07cba4e02eacb3c63241c000573f4ab7214fb189b661a2cfaa663b66753cdd0b7168bdd1e013adbd5aaeaf7cee2976559cbde5b3298ab00ad7e32e934bcf65dc649cfdd17a0b6c5b61540cf2cdca8ca0dffb27f8e017d4ea69be43114a901556e08e3ba0cecf91bc0b3deb05c03868a2d77cb00b396456380a4f84d9574682afaeda6068ba1ad18a2b7a585439447b20d2809bc5f28fa7c56564a27cf60080330f3fc97800cb057017a12750ae4e10740a6ee31f40dbef6b9f474cc1adb33227331c6748f7b35c3589658877b7e525635bb7caf010ddef8aada766c120e45dc9c021a7c9825f90e636b09ed071a9246d78eb4be8cd2d8d9c4ddcf62c6a84ee67f7ac736a0464f339e686cf6ebf71c509306bcfb25d08e8cd9b3a940ec847b7f0007584a00bd9d89500a84e0952d6613801ddbbc674f900f33e92858c7783bd101d30178c6caea54a0b77d6bd70b85a9ff4d995caae869d991a8f3fc00b0b493f5038110d0726ac22b6034c55d12a8ede8f88d09a0ac394157f298ef3c206ea80096e6b9cb4f9a815cda2b0ad6da85304b8f02716ded651fe0f18372553fab124e6cab06809d4ff7742530ff53d17b81c652cd3727001b1a57df04da84f34f2735c0d1502d9f8d9ef415208c0d28dd8f4037e0e55cebb3fff6152812aff3dc4e36be3911889196ae7b09c026323f37059a8223a95e468073b2b84fc7809e30a15133e49699313d904ae52ee1a8d2173eeb3a1cc5f55b016f51c11a4f78dfb094a6cae51d07f7ce3e6a40abf876a2a5c50046d4525beeeaf9e6045c6bb56dd1d0f7a7bb2ae93cbd94972e016af6cf2d493fc200c4bcd4ab7a65e113229cbf2d406d7b463ca0a16d974e012df2583d02984aad8f002e40997da803155dc7d44d7b2f300c14fd5a3f29ffed1951df2f639feb25a03284d5ac01e702317eb9e71d658fc35a9c0984589cad1992d8629958f6a305b07c3de9d52e6593f1c4c7332067634ee90128ee44530401984332db0278c0a68c63d97a06e05a9db07499c5ea27808e35be57dee17abad8aad4b2f4b6d52d411ec14ab1aa416dfbda4ed59080aa983b7aa38e1c2722a68f09a0c15cdc4f0123e36d722350157624b7b43038e758fe9c97ceff1660e8000d8b18cb2780010fe543950b9166cb3ae11bc0cee96d8f002de0ea1d609ed2f117c0036ea94b9c2d5e7a8a40d6b2da8a80e46b2a17fc514ea0929083cbc6b4cbb15aae9e1f2ca192aa2ea11d489d5dbb13a82c5b7f7d0268c887f991d22dfea99bde45c05ae3874008d6f4d27400586d6f28475b93cd3059177096035f8e80cee6c78e01031ab4a4860aaa4ebf5d3a037893c735c0969eeff4d9a628d90fb4b10218a8feb37a4313148403fb7962fea74e28756862431d5c02469e58d9138819223b0dc0d91c8a946e7e623b8701a9e88db7b582ad1c50137aadf3593f208f37f5ec10de6183ca0f40ce14d2a9be324fce27b7471ad4ceff164f64bb02c1d7263a79110844ef78d5f8d2c692de692808213142de5449dbaee0e4da92cff676efca9b464297e52cd66797803e23e959adef729b94bdf1000b239f64715d95e239fa1660a3facb07a0c47eecdc002c436457463ac4c8e8e9ee6d047ae915efa8ed7cfe2f29ae6b32a6d337a94b183cb01f7cc555b8a34b9f00a6a0a793338065ebef1c0206daf6482390f336b3797902b0d87483a27736cce7faaccfed02a527153d9868ecd8770bb055e25e52f7c1f2a3529b007304363f012303df8b0ae6e7e717a86dd5a37c97db5161061c5dbd95a3e8fb94c594f20b5057dc00a2cfceb7fc93b72537b08b29de2f32285d18a45a8db71a9242444836d4c614d061e8752b53dd350d02fa7a0338b6ee2c69e0eb42337084db31c092e277d41b3aeb84132f23dd7576c0f4ae7c983e984fa6c2ef00a6a777f250fac267f48642a02cc80bbe95d7d7c7d5a69b1a604b259da41e467d3af2f231c06e23d0e98475dfd839df3a5a2f006b86338d1ebd33c53dcf00a36db953bbf43e65b078fd0064367af0d2de518e56ef9827a393d6284b37942973b0838cc160d1fc4477b7cc474aa6b1dd27602036fd4c059a0a8704cf7188953b2a01d6a3ded5a3426c3ab0e6a9a20f5d47438dbcb4cff13f5a35d4307081c1f459951b4b5b247f92168e619ce77c7e402807f290068dcececbb99b024606ada58f0838295e2a35fa94b5c6d70d408e90f77e01055dfd3701f4f86313998b714c08ac0e8f01a95d2cf16080bebf9146a09fec7c03327eb2b56d809fec0d003b51f861314fd724658a063dff00e895d3d997806365647a7c0b70f863ef4b003ba06de94520787dac347b802d71be3e030a727b5eb7011503dfdf1e6030214f0542db72945c29305a34bffe1501299a3b0093d85e1f01d16b0630013deb8934abc8b87b1c012d974175eb809eb9be67153d2dfb9cb9f135812a6355e3760230639016027541ac9eff02ec5ab31f35433aff5b80935c208c166c85dc020c38ceef270251a6078f80ca948ecffa91006fe541a033a9e7b5406feb1e79037096caf30df0a415ac7f0a84a088737a6f01d650475b11b06abe2a101b6abf88805b779208b8c74a8d9d85e85d3f7958073842af477d250b9a4cc6dd35801868e28f010ed51e2e04e2ace4c63320a5199e7705821dc3a048a5e6474e73744902183892fb4f22cc82d3cb56c81660877756bc2384b3a4686e0358039e7d00fa94bc8b1da94336f408f9e41b60a1e8ce57047ae2fc0860523f5a89003f593fc94b368e4f6b3d9107b56424bc11085ac876a80190b3ea75760e68d1f575ded1f4ec9d5d968ee5c14125a091b9c8e310bdf42ee00b1c925703259a7cb205304ddeca00a31dabf926d0db9af8a5f4231f3ac2d995bf083846611960323d4c2220fbf82602f667f39528e47bb54b31cf679008a5da456de1ecd7a9c0fc4f23a18c63d1e61ccf7775071818f7db27033db91bf702ae44e92ede018d6d33791508129326bfde002a4438e189ae2112cfa59641076d8b3b2f1d1c11dff971049c89b00eb0a068bf8d8053cece23d04ff6ae0126f5d52202ce416b22d00411252de7b750a967cb2697a13b70d3840a5686e85e42aeef01762ff1cf1a60c4417bdc14986f5750df2f0036c7f6a2ea9755c26468ab4e58d625cabf2b4d2ee3a9801baa7ed9360cf399cc78e93c4bad4b5298d2dbae92550d6b65d7d0b3d7a84b37b2cd75722030b48830798c403f59e12bb1a1aa87086828aa1f9ba1911dabb29490f8ba00587eb2e62d031849d12ca4855588d6b00e1ed0e3065ef18e7cc404a7d2f5aab4abae0f25d3aab66d26d508e898aaf8965d5f2cce4be92847e330e35f4ea0cdb90fb8bb00d4d63d7a8023b758516353395be678575356de5289df8f23e01c813b4037326b2d99565d450a9e8e3b6daade9195955602435db30fe72f0256023a4043cb9df908c82c6f00d6b67b7711c81f3b3c01389eb81688e73b4cdd1f80969b78b57e5de5a8765f014a3b36515dacae5b56bd9635582c264016e0436d5bb709d7452d7f02ec8c99cf2f8065529f6f03ec98af3c15700d36f95896bf9e1f7227d55e3160972024006ba88a9286eec1c290fca0daa43e3d9b464058bd1a01c77b52f4207512ca962220f04e22e0c0dc1160cda005bba629ec26f8e60b30d2d50799bed0e990e9133fa9ec988d5bb56d13d74e0e0f00056b6b2faacbe2df026c4af99bb620287a93c41a9fb1aff17d17d098277d1d0141e2a301cb0f927e347d87d37b20b56c86921168b50454c8636b2b028ea5b90298d4d73f2220e37f110335f36baad9e7f90cf034e5ad2c4c1be5f1ec00259e749a033ca9d53f729ddaf9df02fc1d0ab4e6c02707009bb9fa7c00146c745c910fd33a3b79f24cce44ebedfc8f4d406757934cd4946ddf62b5b37580a57a656ab976b0c4b6ad3d40813c36f208f4d2fd7f80cbd2cf22d03bce7a80b5cbce4704fac9b32c9d2b1ad4f24e320da199dd82786180b8e15642763118595743055f82e1e4eb18e088094b49ccb55cf6335d3900d8593799f4c33956bc671f324acee79c85f47e04b0ad7f279b062c26a4a45d32d050f7800ea9971a4e5c6f5ab8c53b064ba0ba5c0144995e44c0c2e13ac0447825b3353fcd42a0909efac2b6316e48ea3ef463668b77011eafafd288ecdb041ff7f31090b184557680d2b655b400dbd2bd720e30076d55ede25d8e9e6ef3596707e7dd6abcf5518435751952e4b15f014c40072e02ce2ead01394f9c9f44c0b2e037a0e08956019e1f6dcea053afecf28a4b431e25e4ae1c193d3a19a5aeca6c7e4c6ddbc5be9ff0446df9da8374acb32169f6e1001df9fc7f32e35db00538bd3ce15b6ce1d2a5405c9e9cf0443fe08eeefc1aa06d3764d8bac102efcbe50808675723d057da09c0849c3c47407c5b47c0c9b5f613a43e99ca04f729774e4f5f24a0bee83943e44675e9ff2d83a9abf7950dd1b75380f5ec6402e0f2a3c944b1471fc233e6728e010de3fef305a0e726927db54b3f3f9845053b0778cb2e1d236053afc6fdbe2bec762899e0be4f984edfa372fd88275d6968ec075b9c3e9844405d5e2260b5a90558bbec7c46c01e6f0730a9cf24c2a1b0ab7befd52e43d05386688d954354cb1739f0c3fc6f013e3434862ed8b25952bec3e06c882e9f01f693467d7ff09cbf3e3dd90758bf3dd90078c0fb0c604bcf4747809e0d755ad26b42d444332414ac6f885fea2d805d30de4e014343d6cd7104a4efef44c0b522142c3414329d44c0314ebb113085a4fe32c486aa0f0035cd70854c0767c7034b3fc6b4b374530d9e63569a4151eb8f558e3d3de489da0e352b4e00962d976a101f9b8479ed819f984199e80af200cca07cd7809144bf3fe9d8d856d8e4f60d607906abf24f4757d10937a5fca3b79b8cde8e0176f0f75d04a4696d48f9c76e643176e5d600b9d6ca309b6f4e670744eb011d6153be02b0c63e3c8d802354a84b6cdb7a330276612d4c5ffbefce14772c90dbe5e017e70285edb3785c13a80adae5f11150622e74947e003d6a795a0b84489b44f22740433a90e2b9107924d8f58f4b408708df1f047c8dd45ff600d65fdebc4008df981b7f13e81db56dbb08d8a8b40cf080b32e0252ef5d049c94760ab066586a23d03b8e3601d60c271f1120534438908138d131926d5a149ce8f7fc2d501604efeb3b80cef20b4b8110f34884473f024d4217cb0d14a4ce0efb008bf88e3a408be94b538047617eb605e67fea1eeb00c7ed83bf3ce1ec44aef60b608b3a179247ea1d1966e785014cdf1f05f3761be3c10360306bc9673b5b46df93d2a5bd854dc913c0c284c34b80e389ea36023d91bc02acb12fd700d694e7b308f4c495bdc37a543a110841006bf353801d6e72b10c20c779d2f193d1d4e17e61e8dbac4aedd8b33f40c3a8aea4d610f0d4ccc00f52982c36e5520ef0c4954f3c31ff53bb7c02728eb1be3f13f00343f4eb108114f7a500d856c8251983ac1b70cf1b297f169a816d59fb1190ae7e1f81d65ea74b006ba8228d80549e8f08982c5f03c496b3cf5a0255aa6e9a051f4f3f795c98cf36af5ae2b95ba9541e87f92b152c6f7a66267ea552f95c002afa078049a6e9c719602012ff91808244ed84e506d09ad9fa05d8b577cd1dc053db970b40dc6f7a1801b7756e0974e9c0a93c07809cd1e36f17d0eb2793299fed2bbeb2e701b5c044972f2e009bae10d0bf865a898049952f406b898f7f00b374cf87066cd0ba1118edae9299c686a24af0f91f9600ccf54d1f1f00662e1e76000397533c6c47c049695287c57996b21f7c25c4ee24729d1aa0e53e35f0152ee11805ff0dc83970fbf7166011f06b2510ac143739f3136f29233a91ab2d3aeb405a386ce787dc69a27bba0ca89047f21e01870066002436d1add40b80eb44d1ada1a667546eb435ad63f5a832add8cd51682828e797a3490b25f532889dc0ea45a0b25d69baaa36809265f4936781f974b98ce34e04ace09d025a26667e9f009e55e21f79178b935af4042f6dedb2e3756950e91216869646406a679851306749589b1f8092748f1f354339bf9e52fa31002a760dbcc85a965d42173b6c0cd8f882c4ba14e7bbbc01d8296777256064b6f88c97f639e17deb00a4ce4e2608a8b78c8837bda32a4a56350a59baaaaa988878546dabba46f99b2d80251c3ec9a0544dcbfcfaf9b701e63f9ed41b16fbb2d46f330388f0f7063030ef707a2de0727cba4de9691517ecb21160773fbddd033a367e66bcc35b3654a91e55053b26906f45800dfa026478c1a7bc34f8c96afddfdc0023502e4daefabc210f2531d092a9720228581476bca32f6986953b032327d61f01ecaada33a9e5626f869a41a6afce2c0d78a697d655cfdadae30a6030c3760f18015b1a70e6b732ab7b646aecba491c4763398085e63faaed22d34f76ec1bd03314fc6a28a8631efdbbba58ed2b16dadfef008e9fbc3d00ec6ec1778d2f7568178e6d5e3360db903cc036a0b6bf80d26e21ba06b09832d1a565218a4ae44a4e5c0aa0a1a657c863b0e4da6c13d0b19e5d6a006e923ee10af20d81ac56b6dcc469dc6f62333ca8673735329dee6ab0681abbadf3490db59861960855f4c6d9b522e71aa21bdfda2e1bc9a309f68335f11b8009e82503d8891867f7066cee730228e80d879247d36708c8f393bee660b45319b61024dbf674553f846b1c4a544884c153e428fd4683565bdb6d04975298796628465a3679f14fcaafa8a075054b9c27d2f5d63bea72ae92b69d1dbbfafe03c850989d1d408ef9bc99001a5645b31b03984f6dbc088089bb69bd0b185a9249af00b6305453f4b1c00bbe51ebbb783ae1830ae66af3940a5918d7d8ba7a2e950ace065b98f7e5c03b9760fa32d5c5795b9e3cda33803cae46406f5bddd4502e080837f01460696b27ab06ac47758002896dd94f4a6ce1b503d874fae111a0b3ecf402d023a0a3ed0898a9913ab8de0ccaa87eebe32956fb3206f3a970c9a3df055484a2377f802864f5281f37b23dcac2f8da6e837ea8232089e20d60b670225df7f3bf05f890b9f02ec3f257324adef73c91c8e2fa2e67dfc9d9ad01eb842900f76b9a758092b33b8e4e001552af37008eba6cd84b7b3b03711f605aa8cb28e7fb5151873b4a3af4d2a089d738d7258e6302af25e42e6e2239ce001e8fed49d1eb7c4737f3c95298ae4a395bffe10e5021a07d758faee9d8e8783503f4388ae7bb00dba0fc2c4dee8203c6893a0e50d904c0268023b9a7bf72043a977004f5199ff59e90e7b030803c2a8a1e676ade25c22ed48ef33f960196167db90130a374b404b076b934e051ed2dfb49c7d0f8abd6effa0cefe28cea0f96279daa67f7999de996aa607d5e73a2ceb9c6b9bef024a31faa6707d781b9ad07d9d3795c4564a1aff4ada502fecc003de1ca8994ae8f1eecabc6a8be4b3831e5e01d609a7cb2023001adf1d2ceae6b38953af47dc6b178c78af7fb31d744c464228b3bcc3764abe8325b436dc1ea97c6b961fe27c5e5099f699c9b4cd7018de5b16d021c99195369f2d025846f6fcf06e840efb7003b61a8b09fd87ac3d10c50d32b0f3a80471d5e0f011d1bfab3db088809a574c39011695d3d01c800986809ab1d63a6fdfb35604cd10fa9e55826b64346fd65ac6a36f43fc89e8ec199220d47e3cbd878a6a0ef3701766d662b1d1b836963abfd1160243bac948e8dae20e4d99c016c7e6c99277cca62ec5707b01b830f46003302d3420665ec4acce7d99d0192e29d3d519bd94a22d04ff6334043439d2c013c523f9690c7c1160f86857570ff4e287bd815a853a2a4fb0b80dde47ce4013de3cbfdb34053d0c5be2b81f99f549b77c4ad7f9b6f808ea5929d3f81603fc855e01d2156e738dc6d81be24d927690076d3d5f6c2b0b934f3090793dc0bd819bb53e70163a6961b128158fd9b06600b76cf13813ab1a3e3f9496de7499faae8696b5b449e7f051c77954cfa1700176c4dfc23c0ceb5f6eb00879e2e6d017a7693ae53306f8724bcaf023accc5de2bc024b6bd23603d7be27380ed256ed70d50527701b0cc8cf51f40878e6d51fdceb633bc2cc64a9715766bd7ad849c4511de1780c1e9a5bf33813a67c1ff61008ce858320a3476c272790ae8182b1fa5a7599be1b29cef014a66e04fab08d8592f5d9f9fdfc7bee84f806d62fddc02d80d753b12729c729d78de11cca78cc1ce2bc06e82576668686a3b41f7f80f5030739522a09e648ed9c796012cee819a211b473b31565a9807456553efa6405672d2d1d57104ec6acd04fe65997402b15d1ebe003d43d2c3450464a9a9fa799dd9eaac34289f6f3510e0b34dcf18f507083d97f30b07406afbc413003eff44c72686ff2ded20d21ad062933fc70854d25d7ba9671be3c9bb801f5acea7a3fa7e24aedc7c3540f738916ae7b129ef1c80d30aa607f7005b08599e027ac686f34b0318d82bf5863c44d16ceee189dececa4a7b802d62cc68ca91938ea65b0bcbef8aace640e51b297f119bf2a615f867a5be00b63afba0afcc2fa1a26dcf01159d704d5a58b47670cdf78dc0fc4ff6630d609ee3b2fa6de1397576e253805decbdf90230212fc96c155d8bc41abe1204c48cf33ec0bac74101b0ebb2ddadc090e14c9c1d001a5cb80bfda44c5b9b77d06051669dbac74ceb958bdb9059d4d901d80e990775b1325e237ac313b55d8131f0d2b81becfed00032bd57172b5bbb3732b905d882dda076599c0e2d5bb80ca838ecf6fc4c204eff9cf395e0c0136797808eeeb12ee52fbb92667838019877714a39fa9293b074978d2ba34c8f1f013dfed8a96a5b65794292ef16a0221df9588a5bcd6f5fd428a68e5c156dca1677b56d55dac5787732d2555571d7a28e0974f3e3e7bc1a6a4520981c1cb499011a6a2c007681c1c3bb019eb857df0f3192b5cb4104e4a0dd026afca042dda30ac3383bfc7f226096b6016496057d02a81c630305f30d1da87a8c802ce84b004d39dd4462b1bfbcf3932e613bc3926c72d577cc8d4f349c54434e4ede9df4a31a3354ea5c6d5b6776eafde93aa0b1f83603585ac19a0cec3c299c0900b57e5d179e8b46bf002d37c4dcabefd74dca60b12a75a85bbbe6ede817d0b32cf8acca2db6f9caf23bc08085d9943ad4bee276065f025a2af7776380fc31770eb073379a6b80e56edc52db107be05a1f098c25cbc6a37a65134f18da92e56fca8a7d49c732064d9d622d8ff7017616c1bedab6696d1ef7e405d0319575f90318b0fcdf52a9455aa7ba183f09f2605dec0430e290ac49c8f36463f21c6f00353a36e52b41c7a496d35580b9926b6b061891379f04ba142dbcd800589fdb7300bbbb6583da76052f7d41409dcdc11e1d024ceac7528726d820a6e5a4fcf3fc2856ab17b1ba6b8b9a66b8d5136d3cf160eb17d0db4d356afdb66928e9530b6831f40fb2c96d3c7efe57d50fbe05aee4c923a0a4ab7ff393f9df02d47cc5d9453d58a9d6679cedf27b0420e77ba283af0270486c4f426e3bbb4168a3009808cf1b404b583da1604349df2fa6808eb513dd8fec5c82919e1ecb480737877bdfee34ac85219995c41799be307c702840299f6e7e0900699eb2b8ae49489e7cbc00b46660f701b670f8288f2d48198b7b5a02ec2e8a1fc0fc9ffafe0ac06e933f55f59d8feb733dc0ee9f5b5933c0c4ccdf15c05b5c2989b9a8c9e73c11b5f09092068f8d21495dccf5092b23276ab9e08bb75ce424a3e4465b291ad5d8fedf6173ea73ff66695345273ecf79428b5c2e446f25b1d83ac0ecc73d3f996fba934ccf009e05bb7d35836f1b2ccc8b6cb27729b3c54d0db0dd1c2f4f006f2120ef08f64352d70eff00724ed36a1a40e34819a160a119484da060c1a07026a49c5e1fa5beb70230a99f2711741ae6a574be1f19c5cee419f881a2cf94d519403d728fa686a42e1990e9954c4e57d936f91b07b023dc666afdae2e5916bcbd05d826f8073565e84f6872c34b4d625337003a3bd9e70b60c62055493b6f3368c97d041c92b0043021ff1d004a7662ac6ad0ea820805366e0096efb0af21baeb2bde31ca11e86d927a32790314660c24f53e2fb91d4ae76db97e7e359e8cb424d69736aa3fc87ef4f39d9ed2c253c0805adeef0146c08e74ac6f6d675b5f026c55e35b95eb1d7ef2a43b01d88c80b22a5cef6d6cf8e389f9c591d231c9b48f0b766b878082721c1d00464b5b535386516ec4d7ce22200193eac7f4974fb99243d511f05e6a2818ea9623325634440f6d4a22d7e3ab019563d229021e62e57e5e2220bb437519ba11cbff2a3d0d0321076eef7e023a669c6b95740cce373edd0ec0562452758f31f7ccc36ca9578eb51da7adf30c02e89954799490c750740ebe5a01d881b9f7cb005387fb5740895a3e50b0d6f3c48b06f171feb700b9f4740c769dd0bc02143cf1614f541ccbfbbd076838d6ea4e0ec9d879d60a0ede002363e51e9fed6d85f7f51650706948dd00ecaee754a36930ebf8fce9e2b33e991fc8a62ee60ce0906c7c0a9435ab3cb34c205a98e729a0658fe6cfb780b7b8323f07642460eeed00724ded4dbc3d6102eab70dd86d483f0658ae953d0da0c43a1cce000d9ffd7c35407ad4d900b04995e52b81e0f571e0e51da0647dee9dca75956d56a0725d4dbfd576069f0497857de235a06361e8e20f30b46c0059f4399f26199a7cbd2c104f6cd309dc3eadec82f1c98a40f0e025f5c76381d604f47805b082e553802d603e790197613fbe1a81f99fb4300164d6b38f0096a279f407a8f8c9d609c08e73f85d15e8ec6c97cb438065ddbc4be9d2def6581ded036c9beb8d81c14e575fd80f9fc5f3d84a0939ab5aae33d5751e01d841e8b3d40069aff74b026d85801e2f23606a8f77b42d4f3cdc0246847c5a08b88238eae81b50b282f72ba5cbe67f1a3c3f0039ca7ff907283cf385a71148621f4780065bf87d0768993259f90138dae58272841090dd0bfca4b353bc37a94b57a1da333543e8935c0ebe75658086d26d37f3437acc65d907544c96bf2d191848d2536df3e89e2b21c4e7a55d0d3f48ea795c80f02a47de5418947b7d360fcdc0fe8633809d5abd263dcd5d46fc32483fe66723e15d64801a50af031a807c87001c63f6fa32a0c721d9e2275d4abb2cad0172334a3700db457146e5fa0cbb3e4a4ff3c174fd62094022e864baf0507c115c6b7c18d5b6984b48866d225034d8e4413daa88b9d68f5298629e1024b00c709e0977f586c56dd88b27320f6801df2700bbb7fafb1c3070626cab76293a3bbbf4ef0f609b267664b5e7d730b382b770ae7c193c58e66154b97f374b5e008a8cb6cdd509cb3a21bb435ef0fc462e1c92c939a06372f8bc03d886ba41e34b1905749f001a74fd81cf9a80a6f7bf004f5dbe2f04e24444add60f5124e1ec770fb029c67a0fe000cb6ab9b2b399decd6b4043273c92192fc398cd427b0ee06a929936c1fb7270da9e3ef11aa2cbd17b4e24576dab7879fc8b44580511527d3554354f8150f54b400f78947e5421b2a4609f004f0edaee0660c03f7d1a05bcc562fd15a092c426fdab01bb9b7406686cb5e9c200f1edc737c0d350fb14cc77c8f449f2a87acbec3ab8035826c20b95eb6b46e4d72f8023f96994c5ad2d9c9d4c54db3a4d88b4ea07c048afac359ad6598d3bfa287b5a071172cd8a6c723def536ab909c046e4b36f8045f3ed6b04acf0528e507d746cc380f54a7b875db8fefd05185868ff953ce687dc91d579002891fadfad0156df8e297a6f17a09ccab0d543c1bde6a30c4a63970d4ea6f2a59a203135b6db06e46861adea3759cb883ca80335f1b4931f3543d3a4761d903a611317645e78c7fc4f2a1501123bda0198e2e61b000f38cc0083299dba47d3d946e9cd11d0a252676afda6b7d4b7db1380e9d8aec6b966c83a82f70ad012691df38ea1675672a2866a83803863e63b02e61d7e0005c0ed004a647afe2c90e3394ebc2c7f5b95a48c3c68046a9b8400efd103063c944166bcb559fce9e13ea0b3e57cdee1e3005c01cc5a569f06e8d9ee0c3020d38cba7439cef7da00284816dc944d6efb821c92a32b03cc4b1df2d9de4e5c9a208f212723e206990e05a0515d5c1a05b40b6810e1a08239bb8865a2cb7dbdab73bbb65bfd653ea34a0828ef627e963a97b8c98c07db8895fa39019880d6f8898f2771f295a074388a0f004b6addec008e0c91cd1ee0c952db1c2220f140c6d1f5761943afc676268f892e82f373679b93c0d53d7c0c354a9e08713637e4ee005a8e3ec23886518b45ae54ae93af12e2ec73493d182de683be6a808da627fcc433e04c1c4f84d08bc5d82d03d8b1637e3292593ec151ecb294baaca819bab9ef28b002b0bb16873b40e7d9ea760830ab5d5c0006c081a4de858622917c27020e86e72bf3ab475539c551dd9832bb512da6e47d9fd995b9337d256836b32cbd24d6cfcf7d536da5747d5bb2edf74bbda19fffa9477d01ec42a90fd5a5ef12acf6a70758ced5a146c2beb7c5faad4bc060d32e0a45fb2121b3fc84a287ba9060a7a160085227a7770f50d30c95aa3f04771cdf41467a287332330699e07856e75479287ea8eda2af4bd9d3603d495c7a91a51be60ba5b2633340c3eea78b1c604b8b971a3d86307e7070de3e60f0dcedf30418ed1e4d69e110da56e5d8a3e8c1e767ab3d3fe90a0e543ed0e039f49633b1f705b09c89ed6dc0c84ff6d56f87206459cba91477ccb28409e65f409d3063b40fb06bee1b99ad31efb818cfcb21199b9cbccf1bf5ec71be354743920a36ba96449d44bd618c51e3770e18b163979b02a1fa02cb0e9075d8d33340ce131f8f8092eb2aeb0ce089a35ea4c9635f59daeb05a0b3fb3cd5c5c621b3a4921b40cec135e542a65d92711edb64da013adb51f62b907b3265ffee049ad68e2b7c1298c74952fe11d09353f30d98ffa9720f80aa238ee22b5d83fbf5be02701cb0d4da3be269e2070243c12cdc670f68d8dcd335801630e32ba34dbba48b6edaa5f3bb8cd4b307c0c056b7df3d8136dec7f708e0dcafd9c7aa80277f6ce27847dc3ef8742f30ff935d3f006480fcc2009319450eb061feab059428ffe527c0ae38f83b058c08b9fd11084689a317f705a2c45ea9dc60139957af808a00ef742230e698e071a1a75d1657ac1abd23cb7a3c03a7af647941174b5700a3b90a6a972c9ed1fd772dd00e24627cab5d3267dbb2bea702a17a52879f0a90e1e57cdc032abbec5845cffa82c5a5b403d43624dd00eceacd57bed28f0434afbb025140cdc25a7679d6729ac5f98b40eecc313a8880bd4d570255c56479c14f2a521227935b81ba644ff3ed0018ed60a32f0197335bfc752930ffd3005c026cdbdec71da0411e450d7076395606f0c8b4a800b6e97b674ba0ef18d62ed481f221b559da67c0c0216f93a708d8ab81c4463be9a856072ab2865cfc73fda428fa849653bb1475ced2f3cdb7409bb154f2a5da162e6521f5770bc0799fb38f1e602b233f528762fe2701dd021ae661b04173c0a8ae5e590c29cb3ebb6f808c8cccad73033c71bd98dbeafedd11d2e8a5659eb0f173a666288b86316a2aa52b1bc781426bfa6cd9daae450534f39c2c12850f0f05c2888b814d05e67f7ae911c06e98fab801b454ee407dae0c95a32e67809c1c81d71540c5055b4eaa5d1505aaddaa2e55653bec9a9508d8bce105ea91a48147d5b66a1c2784bc380167067657d6a1f2b6a17f4f3a36bf708d0bd73340d5b1cdf50c5013561ffc1ab0bb162f000d4f7c9f45c03d127c3604ab18946380b39bad5b805d1f5e4b0be719559c04fe09e851fe03de319242336d24c23a6f52664896050a9b649a9d010a26ee1a8d2ff5fc72560d6b32d275dd3065f27c0ff07420e45187b89a43673478d6ce66f2bc6a5b079f4ebdf2690d30129c3da95706899acfff00a83b8e1ef806d8ecf9b3daa58e4bf13399cfe08d7285dfd50bc0e33a1d9c088ce45c4d74d575d71405b981ad8c5253a50445cd32a0e0dcd1ba03949c0e54f7809aa4e7b601d8add4376a86268462aaed5209e8f9ec93d4b2f1661d748bd9e2803212755e002371e595ac76d3dbcd5fdb324acd50706866b50268e9738eaf04cf594f5cc8d037c141c5dd9080da7f536a7f0241404c531e023c33465ad30ac0d21b66e78091d1e354050b068665b02d49acadaa8c3994474083088b5d80b73332d7007d45c6bf743d7885cc4b6dd6809aaefe2afd689b84c5a57399e0b6b51b1d4bded1f66cedfa5e057082ee7449ead0bacab25d2e01b5dd92790de8a9ed8e14b7f5768fc40fd59fffc97e1c00ec7697eacb00338a25efe80b7cedbd0f80b90afb883036b69b01ac6d0ff8cad862b50f4e019e316ab60eb0b390aea552ee5f6686cae1fe293f4fd476dfeb44e5708d4dfcdf48622e9eec732c8571ceb26eb624e479628e9ae149d5779d65a86a99632e1ea64cbe1dc07524617d1b607b98e69402f0c42fdfb7113067f06cc07694ad013a7ef261e5e868db5fd9b1d0b47614d43aa06939554395f3a5f9a787b20ef39b47d95aae66f0b5dda87423a5f36d4e0a8d6614e7fb0dc92dfe1e0023dba1be55f4797a14897e4b8016437facd6f796ab307dd1d8e0838965eae617c08596d3677e32ff9308cf013d4f6cbf0106e4f1f70ab0bb7df6e5e5f8bee6245fe55a8798d116ca6e8f0de0b2ecbd47a0a2eff2d2c10e465b7d01d8e995673b00539841fad1fdbb023401780ecccd78a2368b5bbc027226229a754069971e4a933b675b1174c0e31c3046ed4ab583d8719c771e012313dddf1a1abb7f131153802d2e6dad005a22cf8d320212868e009e716e18001d4f7c15801e67e2a23780ff91493fe6e74a92e97605b0d3b4aee5afc724ace985dc8dbe4889c49f358af555c96e8e5641625fdb5915f508682b3c4759edbe713a7477a65985ae6fed70a441c3491f538ace653efb987276c83b62d6efb706e03ec61e930ad011593cf50093c78742d1beb7abe25e0171247cfd0538c01d951bedf2e751221c12bbf7be968732149ded5cd24f42b0c6f460aba61c82ebc49a850334c462b93af250e73607fb0130116619c0b395ba7803d8b90acd46045c96ae4995a1cd39494f99e501d4f8c9df33806d617ed25030b896ebb3861580b5cbbeb470f01937f53eaadf0e9d0d7c5f547ffea7af508e20302e1c7b04d81955fb328e43e8ea18833703acd06c6f026abbf8fd1ad00066547f1c79e9280b33c6298252cef71803bce60830249c40350246729dd63589309623b7dc4d34468d55c296cca329a04a99f9965a8ec1aee3c1f2d9ba6291bc6d017676d8054f04970e432f1b34ce776ba87205a06687cc035f99df162695da007834e898caf9d672e114038dc13324b7e710e068b9f373408fd5fe4a01d694cf2f80d14017817e524b83c63034723eee266030ab2d8b1b860a5b13cf0076d2f3da01a001dc3c1b6006edf509d0f28e99f434343e6b5ae5a22e7d527071c0647a2b50a674d3b54ca0e2cefa898e8408c07a657d2d30bf33471de853a02d0923d5d87de22c2a383e055418d8dd4380dd0c97fe0146429ef55f81d08198a74b05e67fb20e9711480ba73303ac01bff3d2be2438abd6012d8ee2db2aa023e41937058208398def1bc0deeae0ce088c237ed0b50494c6b1611c052c9d70e255b0f9396064ed3d00d2940351ed89860eb4bb0f183139a9849c3619aef5650f28c8e72f0f0dd8ed837904cc6dbd036cab6c7a2610022b56abd57269346cb71250ea5bc6fd17b54b3aff53affc0370ebf0f4dd012ab2f67624d334a836fdb603e4b65ffd5960b4a4c5199f1d2d29ed8092ce555942961666316773bb1408b13a11df8940d932377ed10006b6445c49a582494a192bef04a2bf7ee801057e507d23d03476ccb901b3521d9f0d312067bbf0d910bfe9a50f6b02cee6617480df0210597c002c687ed88c8089880a60c93ec312c05aee6922d059bb7c1f034a66597696013d362893ae67a1eda4c94fd4658e045623601ea607d8a96fbb2f02c14ae14b5d025a40c567079bd8d5cc5500bd6d52e41da3cd6eecab607955b03abbff08187069db2202ee05548fca1bdb96752aa9e7ceee90791c00e67fdcbc47a0927eef0af8829850f7f1f57967538c4f53408190973da046a6df146cfe273d5d8a402b12fdbb016edbebf20838ab8292f605ef3891aee7966631bdd64b0b9bd99c4c65618ad26eed2afe002ee1180509a8f837226f034a3b86e54b20aa765600ecd4ea63c9a368bddd34a1de30bf1e89c9ae0d8047f9d75701a31dada7ee517425c3da630be01ede8957f50b13d0f485baccff643e4f012552ffb806d869d11f5d04cc19dc032cd5dcc96a174366f3eb147db0e3e8f63dc02eb2deb09f3816a7673b00ee169c1eab6dc370cb9688a93e5b062f98ac0ad5a50ca117e7c3ac010a36396bd2be9fef4756bbf4aa4be90ae6509e3488973ee3f08ad55f402e6330d3314efd7c4e9ad1430d557676f1fbb72a57f6ecce9f7eaf45c0bed753407447d594651010eee806c0e471fc0118ec0621aa1f463515fdf815d0b02e36e3b3c1ce63e8d5fad53f432f835255233e9dd26ffbaa4eed5ec01ae088c5ce5f0df0c4be645a3595dd3cba1401e7d448b5abd64e291ad494959d67301d7869ccdbd25904019464763d2706ec20f43700bbe3a68eba38bbcd645fe35ce5537204b6652d2b6b86e9fa96017ac313029affc9c07e47c0b9d6d7003bb1fec3035a62c2a204749c82b726ffa31a3c4fbc528ec1b22a3cf21806120e8fef01968d7d29e358172d31f2964a5a572cf84f7b59febace3816eff90cd0c906cd3e5e0103ce95e6a542549d935abd7d0468cc9554f5438c6827b57e4420997a7ed2b5b6ad93cff67659589f00ccf99edd45a0e596e981818143001b80b9e7ed8b017cfe557bc201fe26808e4cea4d8db7f3297935c3ea2dc0ccd6f225c0d6097791476ca8cd8bffcbde7975b7ad2b51f8c7e8fd5beae551bd17aa4b6f9248f52eaafefa4b8a03c5891dc7b1534e7c79ce5e59f4160bca263800668007e1e4b6981642cd135625fb8f48f2be73493424de2e9a331fa547c301795fba2121c25273818110b23927a58210baf8e4e9ce53a291a1b4527de76b1a7d7c919d88103d1af34bc7bb751242d59c5f1e1b8ba835ff9c328d0ec262b0ee2b420ca4e3ad1b8a102b78e1584a56fb220574be38c4a323914f0be197c9c7e8508880cc152c960f4276838e08a156f631a53c7455eaa6a108b52fa0d3d047adf7c54987b300b9458ce505ea3ba28b8574992bc0b1722cc351e692a22d21a2f2118f6c851077530f7345f89d422ef48550732739478531f5be68e65e88a1589f86f3bec41eab9b767b42c4d412a1152154e8df54526ab563624cc81943351a181642579b75146e423c2ca5e38310579e8c1062397af4bd22c4300ac96375439aada25c62a8d5a3b6612146626c3aded816a14a3de5bc40b171486e5a73beea836840a2d1438e920731b55ab4cf5190bd36a5f8e421c4505c02c619210c290f31f20683b18c5cad9cf2b0f72b74cab4e41742ed2cd9c90b31928ef7c0c9fee031b2b9760c817bc4a5f3663b5dc08111931192ac21c4481c0f924e4b370c05d492108eb1390c7bc550ec38cdf830e215c1644f42f8652c87ad106135a3a9084366bd3c4ef687d1987c80a3392106126bbe9d0a3194e19fb55340c3d8406eea776a6ef8286463ab08712be8f685f04bacd7c811ee70189499d58233dc317ccc596425fbb609ef88ae28842ac2f0e441c8760d2b2186429cd242e822989bbaa9f2518c381fad515846d0e83b753bb2ca54360d190ae113d7b741521161f140dc08e1572b825e848889f342c9d187bdada853408e77a93e8a45a5e3dd3a0ba13683ea3872180dc2323392cc08a10295464e658f861119bad142428cc51e5b3b0534b227c19d42968459268cec501710222a2d6ec52b44cce9bf68665a88817c2b8d991023f9cef5fc8a102b27223735d4aad5b98e10aa1a221145886d992e0ba17656d848998ebdf2ee171c8de9a1a0ccdfe2d8857ac42715951f0b119071ed68531132ef512a0a1195b57e0da79fad3fa6f44a092186e26a5e5067a80562b3bb0721cd674708a5a08e2e84aacabe637fe8d6674e9ce39cf7d6de2ecab947d5a96cfbaed216c685d0a55e0a2345c837aaa03f08d94278f52064bcb0f620c4b5a9f3209cc79e324218626c6a927d2326933ab5981003f9125606428cd5fed9cec08c3e566ef31147c94658b50e51ef831063d323c450dab18021842ed3e85927fb865595b2b4efe441884bd14c11728f42e041c8da0cb707210af23d08b1a53a0f42e61afb0f428690f64204e5231ef22a42521a393c08591d597f102298db83904545560fc2796cc1ff20641d92841021796ce5fa2044416b45483a4aa50721c25529557bb437ba0f4256be4e3e08d977252c4444cea8a9940e7db2cd8af37935ac8f85e843eac5b2ad2434232fc4583e161bb969cc27446523c448062272312124fc9899f36d301ef1ea0bc70e32ec39df3be195cce9aaf39e6f284235f43c08e729277589ec174db2a20815df707d10f27a38efad61a81dd94ea90721cb4949a93f0622b252fbd67fce63e74ef36958ed98cc014bcd8d03f294be63b18d435e15c9e534d2e3b0da8bc2e7bca6e3881af8cf4f85508269c83dacda170fc4b2106ab3c188f9209c33d23121546577230f4216d1483f089909283f08995e383e08f99a9e1e8474cd5b4228079956ee41c82aab092162f29a662f0f42e6b31b0f42569eec0b3190335ad90721a1c32a734345441f840cee38cdf838aa3abc29a7c919c7423274b391ccc5d438ff642bc4409c17223321d4b761e358f4f61496f4c5bc428cd49aa1529543af9458a12b4450ecf58bdc74a47ce02f1d21d4ca3e5ea71d1b3fc4bf91f2b0ff773e0527458870c39707216f8323fef11769d784f0c9dbe0bb97a9e10d4b4793c058085d1a94a8cf21222a94ba121742edb31a6d0ba16aaeb6116220fac89e8518aabaf53d08594f7af9206402a223c4482e094c1c22aac694a6198778ace867161d623892cf7c66ef10a3917c910b920eeb032cd6785808d5272c6f855056ce55eea12bb7b5b5a4d450735a05e341c826b2da8390050eca42a835664eea0c593e9ae14888805a1a3cfd20c40a5e3f08a7d47352ea864a58baf4209cf248ad1c62ec53db56c514a196ea883f087991ef1a337c211505eecb09a18b3ea272466424ddd9504c085d06ff022321d41208d9ab22c44eee0d1e8468acf3209c9b466b0e110dc8eee96b27a5be5858d291d939c4d027933a93aa10baac7771ee3984ee9751858a3c450f88437b41126619bdf2ce49e6acea16970039c3fedff99c741f8404f4b71f847c4e4a420454ed271f8493b0be1490d52576ea768f10125e4a56ce187be592e152089f7c5f32ce53fc11af0cdaf79d74f8add7438ab0fb2064c78bde8390a089b8107eb10c7c292102b2cf6a6f2c4458a27d427e21227ef1b972da0fff4079dd4cca42a8b7d277154279edcdb642c8ba4e8c9c52f70f03e2fcd4754accaff66f601172085d95c749d2a1ab1dd82b272182e26e7a5e0aa11c31f29a10620868a624dd502b84c4270fc2a9db7af841c82b263735d457fd54144299c54eb0f59d90cad68550959d927b8cd59a5dcb9622c632d6e7bcea81c8404a3d8c1023b1c73242447dd27c86a242046479be9e2144c82f2d6e4f88a89c114c091193a88181d36a0762e2294ba32484b2d80ca7c50d3cfafbad8b10eac3b7765418b04c7e8905740a28a07ba57b7f735ec2c0e305aa971e846cde2a29b5ca4c2697124204540f67fc20a490874244a471ec1e85180c64e42a27c4586634d392b0473564870f42a2c1e642f8d516187521d407d877b7828da065a0c9e7c4917630169075598ca3106a978892236d3bce429c9e9b0e31f48a7769672c44405e8f99dce3b1bec3da11bfa57489373de942c4e4c3d76e08a1b679db0485183b0bf66bce020746d06afa64cce02484ae669b9cdc061faf873115222815758b3e08494741889022ea0f4296e34f3c0871b0ab091195d7a33f78104ef6d372d347bd543b42a8550274e7cd0e45c6e27711765ec250542d6c5449081192b6b0b6152222af47da115de8b1af57f0284454b47ef30aa1cb3c50de7909438f1541b3fb07e124ddc809a1daf5cd4c0865e5c48342181222d2725418d2fde22a5a9074581d16f1bb90dcea6a8798b8538421eb3b2611875d4548a3548a0811504b318c1e8408662c846ac7d6f258fb7fe7adac3d08694feb0f42b615493e0827b7f3e883906830a917232cfda8535e88885c62f2209c33faea92810c1fa7160e31567db1e15511f269d42e4204253434eeb485e190ea45a79c9486237ea98688d3f485a3464066789d84856321a9974d4b08d5e11d3b1fadc7c4a187bd106aa98e75fe41c8d09e63b284877ed1e96c2a840a4f771ceb8db0ed707a272e35210c7118ba1c84180b9172ea366ca8e5f91647219429e9ed0a119216f72c49b7ff77c4af3f08593c5c7b10321d571442d5cb292744548843ec41c88b8c1043a9fd9c14e158c504e84ee622115de6912b4ebd44a243d95a311d14c29035a9d3ce173912f30765552fe79b1d1984c50cac6c8550eeb729e7bd8d8c6212d19e880aa19651d84b3a74bf8c3b8cfd42a8380bff4d08d9a55b73a227add2104f37922721826a8e6f23842af562f241c86ca43a431572ca274444d9ebc907217e17d107212b3f49c21ea57e883e08191bcf0a11933306ce473c3256317805474151abf9144fb78043c494735c3a244430282e895121c232afbe725e53abad940d618c8d10cac8f3cb53ec958c9c8ada09111662eabcb751e527cd662a44c42f1b7d391fada8aec21827920e5ded6731b828420676678f33e47bebac0f63116a67a7c14108b5b49e7613427966cc1d69471f0d5bb62344583e8de7ca83109780db8390f5e8d52511694fe3910721a13ba6106a4da673ee413885dc927a7954e521f2206449ddeb8310c7d8b8100339e3107e10625d488919431981efa9dc8ec4c9c671c133a2e3800826d1162228f748a933d48e6cdb8822c4744a391fe058d890de7cd029317bfb41690c2e4218f222a79ce63316f3ab79b1881051b500a8632ac4068190d33accd242185169c69d228c0dd5d8c526f4202488c41422e89536682f84210ebac6f94188ff87d38ed97b92c9e8861056fbe15c3250445874ea6c18647b29c9acf959ce30d46eae054987d53f9135547b42c8b7d2330a0aa1e4705e0b111322137f10b2b6cb428847ed871e8444620c85180ad18b0aa18b67682ff2201cad0fa5a21e72d8ca258fca2e49c2c631f966d79cafc760a03ec01ba75e0643bf7c5e4b4e6764f058ed64e664df6ac5d542d77e218662f40e5084ea7b8414a1d64272deec816518c9b06d44085540c9d48390b8f99510033923187c10d29ede84502576083e0859f8dbf9020d1e0514cf0aa1deca9ad3f40d63918038933a5fe4e120288b688c56420cc4b738e594fad0ea26c886eb352106b2705ed7f97ad82bd9c8ebe108776815906c0fbd1142ed3233907be8639517a7e68646401afa5b5a8881344a89d18390f7b62884f2da9bf71521edc7b120c4480ae8747d104e6e8f7b2174217a6121c662d3397bd75ab70c4a99eea480c66a4da6dd5208b506512123c440c513568430c4a53922d91fab01b388f62064d4dab1c74603b5b073f2288472a149f5853064ee75e3f4e74643b556d660a908d9ab75e3c872340aa8d859a75e46fa406a7f650a6188f89dcde3adf2527b629cb74284a42f963c0b1155bdb5891023a9dbe3480855c887c0839025102473862144cf79a3ecd95919869a0af1a8868510aad497ce6baa5befba049fcf84d0c5c9b7e598a3fad0108d19ce5ba93f561ac87b840849454dc24248003b958310030942db38b9d5ed758b9c743809d30daf2c7938ab3d08f142ea0b11109d2e8342a817d9180ba10b71ac3e0871292a08a14aec680831969b269cefbe3e8e8a0ad37921942cb3032186d2c0265a42a81637e824dd18c8da611e8e4218e217ec2ce96f13f2699c392935866a6bb496532fc6281094eeca41083533323b092121aa949c77dfd0bde2dcb22c0ba16202661521d43ace13b987d5a0884399d3f41986daae6114132220eb6ded824204a5613bef85500d8ab72d842e4421f9209c6ad0d53d0c21e611454811760d21c64aeb7e454845cde5a696b4c56fdc49e9383a90f1b1b853a656af41ed73761542979088a873d3f1488d3b6cb24204957ba5f39a8eed290887f0091191c19d83478898f83aa533422897c4b33ce591176da108c94b3df2209c8a3ac825d68b2c7138be07219ff9a0106ab7ac4d42889010b57bbd8cbd564f4b5cac84187a6509fb4dc3216c8f10a761bb2942a66c6607877884aaac734284a44b3c4e2b4286a136f2147b617ca741b93884a1b6780cad85088f65a9524987a1d683f50484502b2f646242a88d573792d22f05d47f104e4a4792f4b14f4afde055849c618e1f8423ba794908558469e7a6bec7ea84a5aa438c22b2234a242184da3028e364cea77b9557d65e113294b59e0ae1975ed23a234458a60674b987957d595d3daf08991971b633b5888114d039e910aa3c34d31442e5f6141642ed63b54d09f1e8267485d08528de3f05637f4cad64d37492eeb71a36f9005f1d62141162e3e4c56fd5be6c057612428dc11a4d8750d3719a13576011e2064ce120845a27efb0106224a3b4cedee83621412437798a5d00cec7e20b217138652154f64f9707212e01e107212b0d4c1f842cb1531542e9c3f1c51f07623109b50fec1cc2f6057432371162200e76d9ba438c945b413424846a83027b212242687121c62a8646eea1abc8fafc40113277b2ce3a84e1952092d95808153d79f40aa1760bdf0784188b1b9fb7e51076213a857c7c103235600a115085bc7a1052a6f50721db13e41e84781f4b015976a1d81f77e36a1c1c0464118dbcf3aa07559fd083f3d8a02e4b5269ce5250e3e0175b6a2d84ea156cc642a8d580a7412194a9300d09a13e4931a7610b3e3c44863b21d4f68ccedea43621a3b4cea66577c249fab0f12024b26d20849ab15a951f84b8f0d6845045b8c83e08092d8f081154ae804745a842ee3d0899c19322b484eb1043c9ad2a75064e5e4231bf6c963e580ba1e21a1d2fb57168e093913c3d214440c6fac24ee642badaf2c1e715622821661b470e960d2ca6f5ec2c84b21da64b2194153cdb09a1eac5d925d322541f68b67f10b27ca3a3647bc459dedbec839058affd83709acfd94411a2647d2684dae67e9e17420d863a7b73dc09271ddea622c6325f29297d94fa2cfe206485d4aa100ff1dfbb09e3b0d5d1760ac85993c9220c09ef8838f708eb23e99aaf9d220c1b2159ff63bd13222ac1c5ebab103159806b937e10e2a9a22e19c664d321e77d09ab8fa7079f2224e93779acdd603805741322286fd4eda00829d381ef41c890fcf241c8446a5d0835f7ea6cde7a27e49d3315210dbdb312e79d9011f8d48390c620fb2044fc3321c2928efdf54148cb7f79103232317c10b2a87b5888a178ca669c1739120d05c473d8790923b1817c1af34ecd450612954671ae08b51756578881ac2c58371521ce60d9a6106a62b9b71542b968669cba8d8c62320a57683b842e8b9b68ceda941661a81055b987f57995e50a9dd72362654fbec8a90721de2e92dbb16c39453c2384da65c689e5b18cf1a178417b9d228c0efd625ab77c4204c443a4b95484d8a77a5c11e254e21d09119469f44ae341883e8a428424bed259c7d92222b2d64d7321845aa638690aa10ab9e7643f6a7da2c594ec0931921541f34ed31735d41e87c3b4107eb160a3412164d16ed68ea4a2963d2e5b60b484084b97d8337a10925bc99c55aad28e4d8588ca62843327b7b1b05ff2d2735ee4d85016aba49313c210d704fda688804483394f898dbcca863908a11623ac2b42c58b251511148df97a8a90ae46ab2f840a84d5af8a9085489b3321c2ca6555523a523eacf5dd8310a7f882102afed6ab2b423e5a9d8c106aaba7ac644e57e3c9d98322c472f4399fb598a12e098f84500bc4ee9d263866d58b047e0684884934d8cc49d8c02a75f946394a1e8c621277520a0a31926fe5a82b84214bdb382e1216318ec8349853a6033d20d590d90aa196c7e964855023029596102a2f19c7961a8cbd5273d180106a7c6cdf1442c59a4707420c24da67e9bca643eb0be4d45cc7d1baa52859cf20d51142d6fca3e51542a930d810c2109d961cfb6338565e48e1a11001091c4f758508ca9276c1ba10aaefe155444cde86db458881d44bc2f9008facee8a8c187985188b4bc0b2e210c3b188ffea985fa34707afe7086664a8ad04839a438c7d62d1171742f865359c4a5311129714308508c9ebd19c0b3114dfafc84d11f2565e3642c83680249c46490faa324d3a29d543aadf903085084a9393d809319491cda453627a58ed7c3e731a473d1291c7c647420ca5099e9585500b6ec79d8ad2ed593fe70c47857acc27998b3b0ad2077e599b21e1345bb62a25a51321d45b999809f118b66d081191d54e66192162121e760b0aa1b6ef9ce584505fc25b4011f2ceddfc0e31f249b064522e19c9123bccf24244a5273e4b0a614855ce9c965fd7d5464e49b9441f48747eb220845a8ab2e754a53e0e4ad27d7d2122f2ee7b0d2106223aaf14e15835175e4d11326c1b380aa1cbc656b5bc2264c6ea3251848488249cf6c3082b07ddaef35537863e31031373215483d21a29429c6c928eb40d5dadfa765b091153b3c48e0a8d87ebca4d1722286328d78c1011f912d61d691bb6ca9c46692d84daf96b9f7e104e4a2f5fce90b94627b7f68a4b2229e7bdb5ddf7a55eb40721b33c4ec2c6e1a87cf7131b218632b59874dad371d427d33ee999100319fd8ae310f6d6b44e6ee51e562f49a605c342a8f7b6ed14a1f5ea4b9c45622c845a17ff1652840ccbc53d428c24b23eb110e2d118948450be2c49e7adfc32b29996948e94a3f06d2d84dabd2359144297b7e1e6538444d6df24a5ba5ab9e56608a116214e3bc21d1b5ed909be6b0ae193f8fd6b4e08d9c999db520835d855ca28427a6bb7a1100311ccb522c450ed1132156224c361b79110ba8c8df7451f865a71bae9b41fe3b1aa06edfc20649dabb9104121ae55458881d62e0811922081db421132189a969ab30c0e478557a917ab50c5840b08a11631f7aa848d2500b55a7e10ce5a044395b0f15896a6e04188b3202e5c7c3eb8e276f169e18adbc5a7852b6e179f16aeb85d7c5ab8e276f169e18adbc5a7c55bc4edd1cc810b17ff0e3c6f17b775f6d0858b7f07835f2bee9166ea9a69fced5cb97031fc85e21e6be64433a79a39d3ccf9dfce950b17c38f8bdb6aa4179ab9d4cc9566ae3573a3995bcddc69e65e330f7f3b6f2efecf6129d6b40ede2deea3669e34f3ac9917cdbc6ae64d33e39a99d0cca466a63433fdb7b3e7e2ff199662339a99fda05992d3ccbc661634b3a89925cd2c6b664533ab9a59bbffaa6966fda5ab1a9ad9d4ccd6df2e828fa3ad991d85ae62de786d4f33fb9ae9fddb59f894b014ebd34cff47c46d293ba09941cd0c69665833239a19d5cc181ef078f00cf00cf18c9e5f8847c763e019ffed22f838be95329ec93366fae2b5786678dc2eca6f82a53dcb66f6bd5fdc7896785678d6783678b6787678f6780e784c3c473c273ce797aebae0b9e2b9e189e34928be8d27892785278d27a3cecce2c9e1c9e329e0297eef4c3c253c657549c57a67f054efa7d5f06878ea781a789a785af74bdaafdffc49521f6776f074f1f4f0f49f65e7793bdd7e924e2f1e1f1e3f9e009e209e109e309ec8fd9e51a7d5c7137b31310c60e06130b81f5b78a18d70f17d0c18e8a8bd077f5adc0cc60c260ca60c660ce60c160c960c560cd60c360cb60c760cf62f5d786060de0f8e0c4e5fa43038dfc90b83ab3af3c6207e3f4830487eef4c062906690677a10fb20c72eab4fc9d2930283228a9e3f2eb377f925425ee418541f57e507b969d2f660903edeb3b5809a8ab3b341834ef072d06ede7cf7a31310cac7b7619f418f419b8d6cb4fe103e266e063e067106010641062106610611065106308430fc301c321c3976c92a1ced0b81f8c194e1c51da52184eefe48ce15c9db960b8bc1fac18ae1f9a78e9cc0dc32dc31dc33dc3839c76170443f3e9f10f6ffe24a94adcc323c313c333c3cbb3ecbcda720fd55b3abc7d790786f1e7d77e2731d69f09864986a9bfad957f0e1f11f730cd30c330cb30c730cfb0c0b0c8b0c4b0ccb0c2b0cab0c65063f86d6f9261836193618b61fb0eabb29ff7c39e349952e53d86fd6f7efdeacca197a18fa19f61e095d37e7873864186a1fb41f8c9cd230ca30c638c785688af89fb4baead678d3caf5cfb7262460346d6bf2346fadfd6ca3f87f78a9b91c168cc68c268ca68c668ce68c168c968c568cd68c368cb68c768cfe8db016f4626a3e3933f4f8ccedfd4f417558d2e8cee86c7e8c6e88506ef2b7d8c128c928c52af9ff6facd19a519ddcd9b51d63993518e9163dea418159e15e2dbc43d2a322aa9e3f24b27bc9418cbd41e596f4595518d91f6b7e5f26fe1fde2ae336a306a326a316a33ea30ea32ea31ea33f232f231f2330a300a3e7f2aa310a3f0973fadaff028c228fa1dfdc5d041f7a00fd09fabe76b7de82374fdc59fde7e7374037d8c3e419f8ab8f519fa1c7d81be445f3dcbd1dbc4adafd137e85bf41dfafe85139e2506fd806e8a35a51fd14fcf1ee4e215bc5bdcfa19fd827e45bfa1c7d113e849f4147a1a3d839e45cfa1e7d10be8c5df93f417805e422fffeea7b8f847f0119b5bafa057d16be81a7a1dbd81de446fa1b7d13be85df41e7a1fddfb075ca9d07de87ef4803ba4e042e143e20ea287d0c3e811f4287a0c030c0fc600638831c2d0310c8c4f304de3e25fc4c7c6b9ad2619638231c598dd753cc75868a6a5ef25c6cafac9757f75f1f7f05171bb70f19f852b6e179f161f1637c61a6383b1c5d861ec310e1826c611c31db772f177f141df12e38c71c1b862dc30e21889fbbf498c14461a238391fddb3974f17f8b8f8c9618398c3c4601a38851c228635430aaf7e31a868651c768fced1cbaf8bfc5bb27718c26460ba38dd1c1e862f430fa185e0c1f861f238011c408618431227f3b932efe3ff17e714731628c61ec613c603c643c62ac3336188f194f184f19cf18cf192f182f5f7af6a789c4b1f2be62bcb6ddfdc61bc6dbbf9e1e1777bc5bdce31de33de3036393f191f189f199f185f195f18d719c71e2fe6b92718af10bc1949f2612877186719671ee7e9c675c60fc7e8f83efc5ecb8f879bc5fdc25c665c615c655c635c61ae33ae3c61d4dc62dc66dc6564bd665dc63fc6df4ca678ac461ec65ec7bf2a79ff1179f5bc641c621c661c61175ab6f4372548e54ccce38ca38c604261e26ee08ecbbf16e714f2c8c98e84c0c26632613265326332673260b264b262b26eb3bb361f2ed97fa3345e230d93d8d8364b26772f8924ec78b75623239aa5bbd1c92f32566677252076726cf63235cbc11ef17f795c9ed8e389304932493149334930c932c931c933c930293229312936f3df53e5324ce4be2ae3c49a78a3f1814d5ad5e0ec9f912b333a932a931d1ec13262f2e1ce0e22d78bfb81b4c9a4c5a4cda4cac3ae8ded163d267e265e263e26712601264126212feeadacf1589c324f2955932897e65963cee3f897d79e8eb213953987a9cab7e66950817dfe0dde29e0e985aff8e98ea4c0da6e3af31613a653a633a67ba60fad568c9278bc461ba62ba66bad19c0ee574cb74f77810d3fdfd9c035353ddff472139d323d3d3fde0ec8afb0378bfb82f4caf4c6f4ce34c132f21c934c534cd34f3ad1a3e5b248e551a59a639db8a985ae27eaa7e4bdc45a625a665a61575ff1f85e44cab4c6b4c35a67557dc1fc0fb474b964c1b4c9b4c5b4cad2ab4eab5cbb4c7b4cfd4cbd4c7d4cf34600f874f5f8834fb4df8ef45e2b8d2fc8bf8c8f4fb34c434cc34c2d452708c19cc3ccc06cc86cc46cc746606b33f348cfd5f8dc471c5fd17f141c7a9d984d994d98cd99cd982d992d98ad99ad986d996d9ee5727d7858bb7e357f87333db333bd87e543393d991d989d90b4ba8b970f167e1062bb8f8b470c5ede2d3e2dda325b30bb3abc2edf9ad99c51f27fced4cbaf8ffc4fbc56da936c12cc92cf5a27cef27a4996598655d7dbbf81bf890b8ad1e649e59e1fbe22e322b312bbbe276f137f021715b6d76e52ef1ef89db6ab3ab7789bbe276f1e7f1fe0ea5f1c4e6fe01bef3ec4f1389a326f36735661ab35fe2c7e7cefe7c1c1f5fdac1966f835993598b59fb7edc61d6bde3b506fbd344e288ffc9acc7accfec57cd8fbae2fe387e8db87dccfccc02cc82cc42f78330b3c82be2fe4c9138f65366516631e63cc9e07792fd86c01ce69e275b917c2f72c7c50ff14bc43d1f30b7aa64c45c676ed8e29e8f994f5e13f7278ac4b19f329f329f7d9dc1ef24fbcd81394f6ef5e2092e7e885fd372b7efb0343d67beb81f2c99af5e13f7278ac4b98b7bcd7cc37cfb2483df4bf65b03739edceac5135cfc10bfa6e5de31dfdbd6f6fc70ffd7647e7c55d99f2a12e72e592bcb27e667e7957b25d9ef09cc79f904173fc4af11f7fc092e8f1112e62febfb9345e2c839f31bf338f304f3e42bc97e63600ef314f3f42b27b878033ee2cffde2c0df3cc35ca6249f90b9af2efc6c9138ea6ef33cf302f322f3d2f792fdc6c01ce665e615e950be1cb9e3e287f8c824cebccabcc65c7b5820cceb5f0bdd32519acc5b7f6c12e7bf1789f30ddceee09fc487c46d75a43accbf1dcf66de63debf9fe065ee63eeff03e2feaf46e27c0357dc7f121f12b7c63c604bfc7bd3eff320f3902d7177faddc55fc0bbc53d0f3f313f5e9c5978323f3f8ffeed7cbaf83f841bace0e2d3c215b78b4f8b0f46bfcf632c60e1613160f1d733e3c2c553bcdbe65e8c58e82c0c16631613165316331673168bbf9d25172e1c7c641267b164b162b166b161b165b163b167716061b238fe86b4ba70f153787fcb7d627166716171657163116791609164916291669161e1ee63e6e2efe2fde2ceb1c8b328b028b228b128b3a8b0a8b2a8b1d058d459fc701fb3cf1489d361d164d162f182cfead767be7e9fbf9e97cf84f78bdbaace2e8b1e8b3e0b2f0b1f0b3f8b008b208b108b308b1fb8d57fb2489c7b994459285f3fcfe49533bf53202f5ee2e2dd78b7b897b0f4b01cb0b48e472c759606cb31cb09cb29cb19cbf92b0ffe64913872ce3cff642304452e172c972c572cd74fc80dcbed9ddc3d795cfb7bb973f12ebc5fdc7b96079626cbe3fddf13cb33cb0bcbeb9db9b17ccdadfe9345e2a83249b0fcf626f62396a9fbafe92767665866ef07b997c5fdac1c5cfc3c3e24ee3ccbc25dd94596259665961596559635961acbd782c03f59248ed8dccb06cbe6b30b1f8fe87d452e5bdf905f89fb59ee5cfc3c3e24ee36cb0ecb2ecb1ecb3e4bef1d3e967e960196df5d73fef345e2bc94cd0f89fb473777f1167c48dc21966196119651963156b0f2b01ab01ab21abdf2d44f1989f33d92952ed1372be309396635b91f4c5d71ff367c44dcab19ab39ab05ab25ab15ab35ab0dab2dab1d2bebd7c3f79efa5923715e245999ac8e76df71757a429e595d585d59dd583d7f635d71ff127c48dc0956495629566956195659563956797bc07b5560556455fac3f9f9cf47e2a874aeca62f9acacb2aafef5f47c52bc5bdcab1a2b8d559d55835593558b559b55e78e2eab1eab3e2b2f2bdfef49f7b7f84722711ea5e76715601564156215fedd8ffb7fc5fbc51d61156515b3b1c63e5e7b9e61c0faafe7d0c5ff2d5c7f6e179f16aeb85d7c5ab8e276f169f1cbc46db01eb1d6591be841cd342de66fe7cdc5ff397e8db84dd663d613d653d633d673d60bd64bd62f6c93eec2c59fc22fd96475bd66bd61bd65bd63bd677d606d6258fa3ebaedb78bbf875f23ee13eb33eb0beb2beb1beb38eb04eb24eb94db78bbf87bf835e24eb3ceb0ceb2ceb1ceb32eb02eb22e615886f82bf3859f2612c72a810aeb2aeb1a6b8d759df5eb5148ee8cfa9fc1af117793758b759b75877597758f759fb597b5ef9596fbd344e2b0f6b30eb00eaa3f43ac5f9b7474236efe147e8db823aca3ac636c60e361336033b4c5bd19dd874d5ebae41345e2b0d1d9bcdcb5601c651c6302130f93c1b3fbff20792e3e865f22eecd88cd98cd84cd94cd8ccd9ccd82cd92cd0a63f5a265f2992271d8acd96c5e2e99c9491d9c995c9eddff07c973f131fc1a716fd9ecd8ecd91cd8986c8e6c4e6cce6c2e6caee85613feede6f09f2912874d9c4d421d27eda89c8d389433a932a931d16cf25978e50f93e7e263f865e24eb3c9b0c9b2c9b1c9b329b029b229b129b3a9dcc7049f9cffb92271d854d97cd39cababa630f5683f1d71e39a25bf04bf46dc1a9b3a9b069b269b169b361babf5eab2e96158564a1fe3ab2ed4278bc461637d9a7c6cfceacfc013711f999eee076757dc7f1cbf44dcb6e11164136213661361136513630b5b0f7af1f93ccea78bc419b21db0b5fe1db1d5d91a6c6508886995698da9c6b4ee8afb8fe39788db98b0b530653b633b67bb60bb64bb62bbfec620f9ddf85722715cfc11fc22c729b61bb65bb63bb67b3c96b80f6c4da737a9997f42dfff56248e8b3f825f26ee23db933df6b73ddbee81867570d14c0fdbebab93942e5cfc3efc3a7f6ecbbc667b631b576a36d926d826ff4ccbedc2c533b8c10a2e3e2d5c71bbf8b47877f4fb36c536cd36c336cb36f71de4d916d8167f4fd25db8781def17b7a5ec12db32db0adb2adb1a5b8d6d9d6d836d936d8b6d9b6d876d976d8fedf3657f5db8f8dd78bfb8ad36dbcbd6c7d6cf36701771906d886d986d846d946d8c1dec3cec06ecfe7a3e5dfc1fe2dde2de8dd8e9ec0c76637613765376337673760b8525bb15bb35bb0dbbeddfcea78bff43bc5fdc3b76fbbbac0fec4c764776277667761776577637767176097649762976e9979efd692271d464feacc64c63f6dac2e47f2561cf8eff4ff0217167d865d9e5d8e56d537b5760576457625766576157bda3c64e7b51dc9f261247fc4f663d667d66bf7d7e14cff4a712a6aefa3f0cfff990b8ebec1a768772d764d7b23b94bb36bb0ebb2ebb1ebb3e3b2f3b9fddef7c26eecf1489633f6516651663ce930cbe2dd93b3fbb802ad2208b98956c3c013c413c213c613c9127d77af1f8f0f89f27e679c80f738fb3e5c31d4f33f2a6847d0a7c48dc217661761176517631f6b0f7b01fd8fc7ec87e64b7d97b9dbdf182b83f51248efd94f994f9eceb0cbe2dd9ba8ffd98fd7d21fafd94fdecfe6b8341f37ed062f034b2a1febdc4fc28e4e76946de94b04f818f887b3f67bfb07e62bf64bf62bf66bf61bf656ffdb4677f606fb23fb23fbd20ee4f14897317f79af986f9f64906df9cecfd99fd85fd95fd8dfd5d76c39b6a713b0ce34faebd7e2f313f0af9799a91b726ecdfc787c49d609fbc8b3bc53ecd3ec33ecb3ec73ecfbec0bec8bec4befc5cdc9f2c12e7ae0c93f989f9d991c8cf257b5f615f655f63af7db976e479fe942705f86d627e14f2f39ef2fcf7f12171d7d937eee26eb26fb16fb3efb0efb2efb1efb3f7b2b7beb97ebbfdfe46dc9f2b1247ce99df98c7992798277f2ad9ec03ec83ec2d5b2eac1250645452c7e567697e21312f86fc304f314f3fbbfc27caf31fc787c41d611f651fe300070f8701872187d1ddcece71d0ed36fb6070183f13f7278bc4798829cfbcc0bcc8bcf473c93e4c2c0be1d15aa3afd137e85bf41dfafedba7bc949817437e98979957beed50fe4cc2fe71bc5bdc8729871987398705872587158735870d872d871d873d87030793c3918325f1f39fc98f1b89e3e2093e32fd7eb870b872b87188734870487248714873b07eca72b01aefbcdd8a1f0a7f60fadd8dc471f10c1f719c3a14399438943954385439d438681cea1c1a1c9af6b4e5a1c5a1cda1e33a4eb9f81bf8b8cbeba17b776d7d09879eebf2eae2efc10d5670f169e18adbc5a7852b6e179f16ef17f791439f8357a17f87ef0ebf82ef4efadd0078177f03ef1fe70edcb51be410e210e610e110e510c304d383755feb1c7384a9631ad6697f3b9f2efe0ff16e719b63cc09e614738639c75c602e3157986bcc0de6167387b9c73c609ab82db78bbf80f7b7dc3ecc13e619f38279c5bc61c631139849cc14661a338399c5cc61e6319ffb630cdd489cf73de5756016314b9865cc0a66f5cf3cf4bf8a0f89bb86a961d6311b984dcc16661bb383d9fd5adcbd17c5ed46e2bce3293f04661ff3eed93bb79a1bdf071ffa8fc7efbcdf2cf1630630839821cc306604338a19e30847cf17711f071c871c47cf4acd8dc4c97cefceafa7ea3b713aeab9f31447fd5bf2a54b5e7aeef33cfed3f13bef16f7d1e038e638e138e538e338e7b8e0b8e4b8e2b816711f371cb71c771cf7df3cd88dc47992c1676135afa6ea3b713a8f7a397034391e399e1e6e362f5ef2d2739fe7f19f8edf797fcb5de078e678e178e578e318e798e098e468b51c695bdc474bdc56cb9de398e7f86c37023712e74b1a9e85d5bc9aaaefc4e93cd577916389639963e5954b5e7aeef33cfed3f13bef6fb9ab1c6b1c358e758e0d8e4d8e2d8eed27e2ee70ec72ec71ec7f3314e846e27c9dec676135af5efb9d389de712f732a9bc72c90bcf7d218fff74fccefbc53de2e8e3e8e718e018e418e218e61811711fa31c639ce0e4e134e0f475b1ba91388fab5e0cab79f5daefc4e9a812388dee9d0deb40ff62f93cbbe4f973bf93c77f3a7ee723e23e199cc69c269ca69c669ce69c169c969c569cd69c369cb69c769cf61c425f5deb46e23cc4fd6258cdabd77e274ee721ee032793d391d389d3f97b973c7fee77f2f84fc7efbc5fdc054e97bbc4aff63ce5e9664f559ee2f7a94aabcd4e704a724a714a73ca70cafe99fcb891382e9ee02b71ffe0d4a77fda4381a71ca73c274be5454e254e654e154ed53b6a9cb43b69fd54b74efedd397123715c3c83650f3738356d71736abd82ef78051a77a7a8236b7b1bec275839fcf37dfa5cb8f853b0c4dde6d4b98b5b2fbe02d7e5d5c5bf86c1bd5deebae276f1f9e08adbc5a7c507c4cda9e7c2c57f07bf52dc2e5cfcb7f16bc4ed0e89b8f80fe2c3e2be6f13ecb1bf0b8671df0c3b626f226cfcd37ec02e3e073e2eee531fddcb7ac9c97bdff2fdc6dac7c9c26f9fb871e1e2557c4cdcac0d8ca5adec4d5f33339c027613bea9700a720a710affeae4ba70f1767c64b4645d66d3b35b6b0beb94664fc8473845f14cee2a8f717eee1daaaefd95a17e2fbaec7ca6004de58a7dfeb1a7ebdb0aea3fe8e4f43bf011719f07ac75cef703abb536169c479c75dbf2de8cee3f19f70b5f78f02f0df57ba1aa3e5980e62fc193804857dc3f16f7d8ea44da0db6d57e9f279ca718ba6d70af53f6bf96becf33ce2f0768bc3dd4efe5b8c3e582e592e58ae5fa79557db200cd970af0478f7eb6b9d9d7b772c5fd63715b4df592f3ea8e35dbe4dd3e89d86db9a36fcb38396f38bfb07df0db43fdbe1b58b9b4231258a65f10f7e70ad07c6296ec9ea4f0d547ff60733357dc3f16f79ef34133b3ac8f9c4d1bf6c1fa8e95ad75aba379b698d38bcf7e63a8df8f022b7b2f88fb730568be547a3f7af40f363773c5fd96d192f399f3e53e5492e57cb5cf5c8fec9141dd6b0f9e9c6f9ce39c13afa4e087a17edf51c377c5fdf902345f2ab71f3dfa079b9bb9e27e93b8939c53f716fa6a37d856cb6d89dbb64cd29c2d715b8acfbdf8e03786fa7db7f2563ad37bb8d4caf856dc9f3140f355f24571bfb0b9992bee9f9fc439e7391730acdee4c46ac239173997389739575e79f01b43fdbe5b792b93d5d1ee50ae4ecfc4fdf902341f3677f5ad8f7e69733357dcef10778db376b7b3eb9c1b9c9b9c3fc1e8f24b39750334ff31fc0ac729ce6dce56bbd2e56c5978e69330b3bf9ebd5f033740f3dfc447464bf420e7beed26b54e71f672f6b15ed8b00f74dbc9c4fac93ae1ec3a99b8f82bf868cb6ddc1b69d35230c6d836bb6d8cef8236ef3fb9deb02efe16dc6005179f16aeb85d7c5abc57dc772364c679ad0c0fd7fc70f15fc3bbc56df5264f3dce81fbace4d29e8f3456b65789a578fb6457eb2efe3ade2deeb525e5a0ed06b85db3dd730e710edbfeae96dc4f7d4be29f6928d0c5bf890f394ef96d4fee7384759f73d4f67a3d45ed79786372f7109cb8fa76f157f17e711bf6609fedb41de302178fed09682f1f11117d1b5336b7579ffd5f0896f9c844b49aebfe6a13337bb69ccb80cb90cb88cb37d3f5bf2aa6c6c55bf07e9bbb68bb49e97d2e0697b11d4979997099da5e5376ecd9f2ee3e65be627cff1782653eb65bd7dd33e4db4dcc9ef8a25c665ce65c16cf7f72f147f06e715b8df4da679b22174bd6760c2597b5665a4df8c6f633b1daefcbd6ea657ecf32f98f04cb7c697d374969532f3b2e7b759fd7f60dd35edac4ec5b2faecb818bf9e24f2e7e3fde2deecdd5b6b06d111fb99c6ce35bc43db16df1cb99cbc58e435bbfec69f41f0996f9568bbad5d65eb9dcd4a35fdb374c7b6913b36f6f38d93fbcd5bf1353e3e2f7e1dde2b614bc1e69a6e7aee3b8dd8a8b599262ede592e092b4a386bf6376ff478265beb622ac8f4f9a4be649225fdf37ec854dcc9eb5dc592687177f72f1fbf191d112db8724600f055e725cf2b63562582666814b914bc9e63d9317979efaef04cb7c2dee32970a972feb4cfc68dfb01736317b26ee1ae31713e3e20fe003a3257767a9953dd46dab59e352e7d2b0cd15eb606b35e74d0686d5ad7cdea7fcef04cb7c79caa5c5c532d0bf8ad57f7ddf30e9507ebd89d9d76f8b65c177b9f45e4a808b3f80f74fe294591fed751d2efd7bcb5db48d93cd8ad35dd3f6e4a555bb5bdb6839afbf79ea7f2758e689b82d53caf73042d4dd5edb37eccbb54f363193a1c089a569ab64025c825f9fff3ca6c6c5efc3476628ad66fb12b257c17426deedb9c9a6dd72af757b94709bb4a7303756772afbc766e3dd6019174ff0c1e5d46cfe3ee8b1b9d982764c9173dff1f3b62fbc87c4ff0171bbc1322e9ee117b9bc3a560a97b01d86e386deb8f84fe0d7f973dbfa3626aeb25dfc67e0062bb8f8b4782aee4be415b8e276f1af61c025ca25f61e71fff5ddab5cb8788a8f88db73d7b70b17ff0a3c4fc47de5cdf0701d701d721d71d55db8f8afc2d2e7f02eeeb77f028cb9edecba4eda139357c3858bff282c7dae933f1e2df90ae7bebd77d9f67a8f51f0b870f11f85a5cfedf567c5bdbeaf9376b59775b554eec2c57f13f795e37f52dc2e5cfc3bf813e2b61da0ff763e5dfc1fe2b78bfbeef0d976f5ede2cfe3f78afba16c57df2efe3c7ea3b8bf51b6ab6f177f18ff7887f23ae63ae13ae53ae33ae79cfbf93b2cb82eb9aeb8aeb96eb86eed3586de78adedbfeebb2f25a773ddbd1f03c30ef5d854de5302dbab1dbd6ae87680c85faf8e974b78cff5c0d5e47ae47ae27ae67ae17ae57ae31ae79ae09afc4d8ffe3de276f65ffdeda596e29ae69ae19ae59ae39ae75ae0fa5377b0945de25ae65ae15ae55ae3aa71adbf35f1a7e6ddd1975f82fb6a029e9f2f8406d726d796bdccc645bb2f7367fe4435fdde0a6a73ed70ed72ed71ed73f572f571f5730d700d720d710d738d708d728d71e39727e0f788db98d9216727ef3de4ecf794e0cdc36dc06dc86dc44de766701b739b709bfec4136f336e736e0b6e4b6e2b6e6b6e1b6e5b6ebb375dbee9c96a44b73db7c37d07ac1fe166723bdab0833ccadc4edccedc2ef67df4a0bdb0e8cf96c3dacbedcaedc62dce2dc12dc92d65cfcf9d22f6468aaf5f7bb9d8df8d5f5929e927c7196e596e396ef9bb94efb815b8156d7ddf4adcacec57b855b959c5a271ab736bfc5a91fc1e715bc56a15eeadc9adc5adcdadc3adcbadf74bcbb1cfcdaa571f37aba402dcac820b710b73b39e1b7df34d62c421ee213e203e243e22ae1337888fdf74f9796c8b323e213e253e233e27be20be24be22be26be21be25be23be277e206e123f123f113f13bf10bf12bf118f134f104fdaf7b117cc08fd7439584d753c453c4d3c433c4b3c473c4fbc40bc48bc64afe768bb4b182f5c687d28e265e295977f7d1fe255e235e21af13af106f126f116f1f613748877efe811ef13f712f711f7130f100f120f110f138ffcaaf4fc369b7b63e5304a3c4602121e1203124312a35f76ff844ec22031263121312531233127b120b124f1b696db6ae0136b121b125b123b12fb3b0e244c12c7b7dde12eeec489c499c485c495c48d449c44824492448a449a44e68e2c891c893c8902092bf125126512151255123512da5ddc5646eaef2a8a06892689168936890e89eefdb847a24fc24bc247c24f22806761bf095bdbc0b557554f04498448844944ec89e75f50235112319290f4901c901c921c91d4491a24c7242724a7246724e724172497245724d7243724b7247724f7240f244d9247922792e78f27e9b789dbb0927e217925792319279920992499fa65f74fa64966486649e648e64916485a64896499e4db7a6696b893559235921ac93ac906c926c916c936c9ce9bee70ba9b25c92ec91ec93e492f491f493fc900c920c910c930c9c81d5192315290f2901a901a921a91d24919a4c6a426ecd7b6c2b6efb23b8d05a929a919a939a9c51d4b522b526b521b525b523b527b52075226a9a3bd7052ea44ea4cea42ea4aea6677493f5e23a938a904a924a914a934a90ca92ca91ca93ca90229eb04ebb965521552555235521aa93aa906a926a916a936a90ea92ea91ea93e292f29df0793f4fbc46d95b59f548054f08e10a930a95ff6c521152515230d698f74c8d203d243d223d2fa5b6f9236488f494f484fd54d66a4e7a4176fbafce2b95fb224bd22bd26bd21bd25bd23bd277db0759c36491f499fec7f2db9a7cfa42fa4afa46fa4e3a413a493a453a4d3a433b6bbcee55d4561f56dd259d239d279d205d256be4aa4cba42ba4aba46ba435d275d20dd24dd22dd26dd21dd25dd23dd27dd2d6e53e7bd9de8f5487f566a6fda403a4ad6c8648874947484749c7c840c64366406648664446276390199399909992999199935990599259915993d990d992d991d97fb0c3f69b3a9453db2d2b73206392399239913993b990b992b9fd9a4764e264126492645264d2643264b2647264f23f7113eb35c814c858772b912993a990a992a991d1de72b966da43259cea642c34c834c9b4c8b4c974c874c9f46c895bad78a66fff6bc93ae325e323e32763914132213261321132513231db1dcd6a53ad3b6f3df608e34f8d0c6621eb213b203b243b22ab9335c88ec94ec84ec9cec8cec92ec82ec9aec8aec96ec86ec9eec8eec91ec89af6ebb1fd40d558d64ef648f644f64cf642f64af676479c6c82acf56b8a6c9a6c866c966c8e6c9e6c81ac95f212d932d90ad92ad91a598d6c9d6c836c936ccb7ee13f2aee6c9becdb3ec46fc8a46dcf65bb647b64fb64bd647d64fdb6b8b301b241b221b261b2bfa2093f9b64a36463e420e721372037243722a79333c88dc94dc84dc9cdc8cdc92dc82dc9adc8adc96dc86dc9edc8edc91dc899e48ee44ee4cee42ee4ae6f4d80bdc8b7f5e81bb938b904b924b914b9b46d9fe432b6c473d97b3b7db5ed905c8e5c9e5c815c915c895c995c855c955c8d9c46ae6e2f8f619925e791a56c7bf9979f6ac50d2b770d724d722d726d72d6a3bbe47ae4fae4acc4f8c8f9c905c805c985c885c945c845c9c5c843de437e407e785fb3f7cdc388df203f22af9337c88fc94f6c59e7a777cc6c7de7e7e417e497e457e4d7e437e4b7e477e4f7e40fe44df247f227f267f217f257f2d6e5d65509f21f1a02bf8b3b9f229ffec85d446af64a5479f219f259f239bbc1ce5b7f16c85b992fddff2d93af90af92af91d77e41ffd2fa6ce5ebe41be49be45be4dbe43be4bbe47be4fbe4bde47de4fde403e483e443e4c3e423e4a3e46314a0e0a130a030a430a2a053307eae762f795bdcd70585318509852985198539058b595258515853d8dcb1a5b0a3b0a770a06052385238513853b850b852b851885348d8ed5fc1424a338fb6c7fd4f94c3d51e1b29a42964a4d92e6429e428e4291428142958bf962954285429d4286814ea141a149a145a14da143af6eb717e6fa353e852e851e853f052f029655b05e2a710a010a410a210a610a110a510a308450fc501c521c511459da241714c7142714a7146714e714171f991ceee5ddcc515c535c5cd074476b587478a5b8a3b8a7b8a87bba60b144d1177f148f144f14cf142f14af146314e3141f117cd4e155314d3143314b3147314f314ada75b7c89629962856295628da295c83ac506c5e61d2d8a6d8a1d8addf798779bfb28c7c9ca4b8f629fa297a28fa29f628062d0b6522cabba18baff1ba618a118a518a304250fa501a521a511259d9241694c6942694a6946694e69c1baf47389292d29ad28aded66bbb4a1b4a5b4a3b4a774a064523a523a513a53ba50ba52ba518a534a504a524a514a53ca50ca52cad916d14fd7bef5dc3ca502252b19a52fca76502a53aa50aa52aa51d228d52935283529b528b52959a9ed52ea51ea53f252f251f2530a500a520a510a537aff47fe2eee5294528cf2bbbaeaf66a9719ca1eca03ca43ca23ca3a65e38e31e509e529e519e539e585e297b6facb2bca6bca1bcadb5fd084977794f794addb9a948f944f94cf942f94af946f94e394139493945394d394ad0467efc851ce532e507ed774dd5ab7c57db42e2f512e53ae50ae52ae51d66c8997eb941b949b945bf77fdb943b94bb947b94fb94bd947d94add3029483944394c3942394a3946354acde6df6e71263cc39b5a978a80ca80ca98ca8e8540c2a632a132a532a332a732a0b2a4b2a2b2a6b2a1b2a5b2a3b2a7b2a072a2695a33d6afeb3c677e544e54ce542e54ae5f695b22b712a092a492a292a692a192a592a392a792a052ad6b5252a652a152a552a352a1a953a950695269516152b47ef3798efe2ae74a9f4a8f4a9787f52d9a65d10151f153f950095a0c8b712a212a612b12d934a944a8c2a543d540776e32de704a90ea98ea8ea548d8f5ae1d531d509d5e91d33aa73aa0baa4baa2baa6baa1baa5baa3baa7baa07aa26d523b310d513d533d50bd537dbd94fb119d9e2360b546f54e354135493545354d3543354b3b6beabb93bf254add3ac7496a896a956a856a9d6a86a54ad731a549b545b54db543b54bb547f7ec26b7da4daa7eaa5eaa3eab70d926a80aa55c85636c3542354a35463d4a0e6a136a036a436a2a65333a88da94da84da9cda8cd6de37bfb335fd4da82da92da8adafa2b9ba4b6a1b6a5b6a3b6a776a066523b523b513b53bb50bb52bb518b534b504b524b514b53cb50cb52cb51cb532b50b36efe935fb06fc55d2b53ab50ab52abfd8cb2d7b6b34e4da356b7c7b36b0d516dad49ad45ad2d7648ad635bdef6b195ab2eb51eb5be48dcfed54bcd47cd4f2df0a1f6bb66a524442d6cc332486a116a515b79b5181accda681eb401da106d84a6a3196863b409da146d86367fcf43d73efb11da026d89b6425bdbb2d636685bdbf8d676687bb4c31dfbbb07c911ed847646bba05dd16e6871b4045a122d85665d9b41cba2e5d07e66cce781adf594025a11ad845646b3daff2a5a0d4d43aba335d09a682d34ab343a685db41e5a1fcd8be643f3a305d08268a19f36beb5305a042d8a16fbd2725bd6481dea1eea03ea43ea23ea3a7583faf88e09f529f519f539f505f525f515f535f50df52df51df53df5037593fadb26d4be2beefa89fa99fa85fa9b1b30eb236e5829bb518f534f8858eb49bb79aea76c6b24ebb3c97adad6b47582d3665b643d433d4b3d773757ee2f433d4fbd40bd48fdfdef2875ab282bd4ab77d4a86bd4ebd41bd49bd45bd4dbd43bd4bbd47bd4fbd4bdd4ad94f8a907a807a987a887df25a6ab2dee7a847a947a8c06343c3406b6941b431a231a3a0de38e318d098d298d198d398d058d258d158d358d0d8d2d8d1d0debaa030d93c691c6e9cd15d1b7e7cfad56663db2f72a9a26689c695c685c69dc68c469584c92468a469a46864696468e469e468146914689469946854695468d8646a34ea341a369bb9d18d337a5a1d1a2d1a6d1a1d1a5d1b395dde8d3f0d2f0d1f0d308d008d208d108d388d088d288d184a687e680e690e688a64ed3a039a639a139a539a339a7b9a0b9a4f9fea1eebbb89b6b9a1b9a5b9a6f76a3b10c92e69ee6c19e80144b63620f89a44277935ad91e569b6dfd6919274d5318fb272bc5479a27bbbbe990cd33cd0bcdebfb8d93e68d669c66826692668a669a66866696668e669e6681a6754e89669966856695668da646b34eb341b3f91e5f59bb108222ee668b669b6687669766cf1e2a497aed39c8669fa6d746da4a9e8fa69f6680669066886698a6756194668c16b43cb406b486b446b4f49f10b7eeb5374c6c19f64075bc44cb3a9ed09ad29ad19ad35ad05ad25ad15ad3dad0dad2dad1dad33ad032691d699d689d695d685d69dd68c56925ec7dea5a495a29ce6f13772b4d2b432b4b2b27cd762b6fcbba55a065fd6aa5aa4cab42ab4aab464bbbc33aa8d36ad8b26e3569b568b56975687569f568f5697969f968f9ed5d68de278956e02eee569056885698d65bb56577225b515a31d16b1b5bbe563bfd54c196dcdb1ebb61b61aeff680f6f02bdd5b6f457b445bb78753ac3fad5bb50dda6ff3587a51dc6deb7153da335be2ed39ed05ed25ed15ed35edcd1d5bda3bda7bda873b69d23ed2b6d2767ee74cd8f676b7b9fdb42fb4afb4ad34c4695b4f4fdab26ea768a76967eeb00eb2b473b4f3b40bb48bb44bb4cbb42bb4abb46bb435da75da0dda4ddaad9f11b7651d59396dd3eed0eed2eed1b61eeda5eda36d252c403b483b443b4c3b423b4a3b46073a1e3a033a433a233a3a1d83ce98ce84ced45e6add6ab9ce57b609fbb3f09604746674e6741674967456b6b83b6b5bd69d0d9d2d9d1d9d3d9d031d93ce91ce89ce99ce85ce95cecd9675274e274127492745276d8bbb93a193a593a393b7978f7a9f243a85bbb83bd651894e99ce9b67c53a553a35bbe36889d532b8ad36db32b51f8321564b6c75283b1a9d3a9d069da6dd7db4fe2c1eed9ff245f50e58f96cd926b8a56feb569d369df7768d3b5d3a56a1f4e978e9f8e8f8e9046ce575ace75a77b61213a113a513a30b5dcf1d03ba43ba23ba6f9eaeff06e7a1fd88ae41774c7742774a7746774e774177497745774d7773c796ee8eee9eee81ae49f748f744f74cf742f74af746374e37413749374537fd73e2b670ead2cdd0cdd2cdd1cdd32dd02dd22dd12dd3add0add2add1d5e8d6e936e836e9b6e8b6e976e85a17f6e8f6e97ae9fae8fa3573f0d3e5d00dd00dd20dd10dd38dd8e2ee466d597763f4a0e7a137a037a437a2a7d333e88de94de84de9cde8cde92de82de9ade8ade96de86de9ede8ede91de899f60635efab9ddef12eeede89de99de85de9b6deede8d5e5c2ce65e825ef2cb1848c6b49d017b2911b1d560f7ee2dbaf5a7455aadb5658d58a297f63b6e37f9bd8cfd92f4b2f4de651ed8e9b19251a0671d94e895e955e855e9d5e869f4eaf41af49af45af4daf43af4baf47af4faf4bcf47cf4de5b7c6bc316772f402f482f442f7c47845e945e8c3ef43df407f487f447f475fa06fd31fd09fd29fd19fd39fd05fd25fd15fd35fd0dfd2dfd1dfd3dfdc34f27a66fd23fd23fd13fd3bfd0bfd2bfd18fd34fd04fd24fd14fd3cfd0cfd2cfd1cfd32fd0b7ae2ad12fd3afd0afd2afd1d7e8d77f7a9e72635dd5a0dfa4dfa2dfb6c5ddefd0efd2efd1efd3f7d27f3284d2f7d30fd00fd20fd10fd38fd08fd28fe105af07ef00ef10ef08af8ed7c03bb6f7a5795fed88cded9de09de29de17df3a0817781f76e63785778d7aa4399c7bbc1bbb59be4877d6235dbdedd97c16f4bd656a7d33242bc7b61bc077b18d16abcbd26def7768dbd27bc56622e78af786f78e378137893785378d3783378b3787378ad145a0fb2ce2fe12de3ade0ade2fd9931a2a7b8ee647759af86b78eb781d7ca6c0b6fdb76dbf776f076f1f6f0f6f17af1faf0faf106f006f186f086f146f046f1c6f081cf836f806f886f844fc7f7f33ed6dbb83d14e81be39be09be29be19be35bd8caf62df1adf0adf16df06df1edf0edf11df099f88ef84ef8cef82ef8aef86ef8e2f626193f276eebb9097c497beedd97c297b645eccbe0cbe2cbe1cbe32be02be22be12be3abe0abe2abe1d3f0d56d65fb1af89af85af8daf83af8baf87af8ac7b7af1f96c03e943e2f6f9f105f005ed6ddbdf78a52f6437cf96767d61fbc0d2a8d56bf445642652ec13039f95f4984dfaf9628d58adbbdf630f175a2f83f5a7d5f0fb073669ddc7ffded7d43fc2afe337f08ff14ff04ff1cff0cff12ff02ff1aff0aff16ff85f7b57d6dbb8ce64dfe767cc793f48c41df3e4ecfbbefa4da4b2c74b36db0930ff7daae474df3b83fb016d271783efa2bb0b82ac4862913c2a5615abc86ac8ea89d533ab1756afac84b1d1dca167aa0e0ec7dafaa305f51d5df5b40175b3d9a036899e5fe93c805c19beb31ab39ab092930f561d5652eb65562bac5659adb15a67b5c16a93d5162ba9ce5c8ea38967b5cb6a8fd53eab035687ac8e581db33a6175caea8cd539ab0b5697acbaac16582db2aa581956d2238e953c1e58455669b67245d21bd280a6a6c93485a651e57bbd437345734d7343734b7347734ff340f3a8b036bd5666479a3ecd806648f344f34cf342232f7ca319b51b2dcd1beef2096e33a699d0bccfd0cde683a6a3e03e79fb04f7aef0bda4d1ad7f46b6595695c3aca86e3d9d8affc477a259a559fb04f7542997179a19a7e5fee067836693668b46ce77687669f668f6690e680e69a4298f694e684e69ce68ce692e682e552199cf4ff2934697ed1e9c17ea63164cc8d1746916da8d9537353452a4a0dc2336dff85a2711cd224d456368a4be8ec6d3041a69a8444b5ad0d6b499765e97ffe05df16d1bda2bda6bd546ec0ded2ded1ded3ded03ed236d8fb64f3ba01dd23ed13ed3be28beed2bed1bed8876760b7b506827b4efb41fb41dda25c5b7864cdd29d9655ae16495768d769d76837693764b65b6dda6dda1159ef768f7690f680f698f68e54f279aacf885de69c16d4f69cf686731e6ec05eda586fb09826d57a17970a161803f9d217681765141acf1246315e7a29cc8cd3fa17fb4aef7eb9d8bea331133d456b466b60a58e91247eb6903ad7092e84807ba9a2ed315ba86ee8aee9aee86ee96ee8eee5ec365fffc929748f740f748d7d317cedd9a0ae5a8025b457869f7096a5310d4f9f0daeeb32c3cf4e9067443ba27ba67ba17ba57ba37ba11dd986e42f74ef7318fcefd93e4eb721dba25ba65ba15ba55ba35ba75ba0dba4dba2dba6dba1dba5dba3d95df6e5fe5b73ba03ba43ba23ba63b51357ab6ba4bdb9ed29dd19dd35dd05dd275db78d78e4eebc8d149418b745290a1b3748eced305bad852a2273de86bfa4c5fe81b951ac3a52f83db5fd15fd3dfccf0a48cb3fef673ea51740c3128f7bce2f527b805eb7be10f555b64f699707ff707b8fdbd3e228ffb07fad6f3ed7bb34535f83efd807e48ff44ff4cff42ff4a2fef91778ee9271aae2d90ea1cd20bb71ff41dfa25fa65fa15fa1f51907e8d7e9d7e837e937e8b5eaecca512a860eefdc863bfd1c810e9ef7e4f37a2108bd3ef6aa09f7495dfa3dfa73fa017ae8ee88fe94fe84fe9cfe8cfe92fe82fe9bb7382bbffd66a478ff40bf48bf415bd146de91dbda70ff4913e3190010c354366280c0dc315c335c30dc32dc31dc3bd6e9f3b5bf57b2a65c303c323438fa1cf306018323c29acc3f327d0c30bc3ab2ae57214bd3cbc318cda9331c384e19de183416e5b62586ef7c7fb7ab24258619831e455fa29ac31acabde2ca83d2baa70878d36526aea06595217e14fac4f6779c406fd3c9786d864d862d8d66f43201e7618767f754aac51173dc31ec33ec301c321c311c331c309c3e95fdc1cce18ce192e182e19ba0cd2dc8b0c1583bcc4323806cf20fc4786c448c6d97dab034536632d503e9c6ecf294d24506b971b6d65f98a8ac398190b63c378c578cd78c378cb78c778cff8c0f8c8d863eccf03ee69c8f1c8a83a34ba601c300e199f189f195f185f19df18478c63c609e33be30763877189719971857195718d719d7183719371f6c4b37197719b71877197718f719ff18051aa7cc478cc78c278aa3183f18cf19c5138bc64ec2ab2e302e32263c568182da363f41cfb2f8aed1fe08eb3cf0b8a4414b53246c6a4b3eb89aa5e8b8d98f0a958cbb980fea792ad7ac81a53fd634af28d292bac05ee2b86a930354c57337ca9e99ae986e996e98ee99ee981e991a9c7d467faabd85de9fb34647a627a667a61929fc2c38869cc34617a67fa60ea30495d969966cff59c7686225b34904ad76998162a17075d25b13be5d34dab4cd20eeb4c1b4c9b4c5b4c52971da65da63da67da603a643a6d9338575cff235159f63a31331a29ca463a61326e99433a673a60ba64b26b9bec0b4c8543149cb5b26c7e499025354119ea40b09f93f4756fcb003d660060b7463f32bf01abc016fc13bf01e7c001fc19ebc9ddd737000dd88fa097c065f40b1d0dfc09186ef7e474e7e0beef984ffb80b8edb95bedfc176ba7141b8ec2858d54c5c51657aea0f99aa25972be0d2e764bbba02e5e6e516df7db4f9863345a241f3f2d6a119389bd0a403b9b2030dbddd03f7ff35cf3dd152a07171723c82c6829c40e7becfa0b37617d02907a9d78cd1914dbb9ac5d251bb65f88f85537465a2feff26e9d445689d0dd47814e340d44c511164a4481040e9bf1ac8f3805b25f79d1a769ab68c76899f479e3e010510fdf5ada5259dab5fd5b86de00ab8066e805be00eb8071e8047a007f48181ee80feeb03e9cfe61d7e004340ca7d065e8057e00d1801636002bc03724307580296811560155803d601616913d8d2e5286488fb8ee56ebe9043a9b153d22edbc08e06068aa8b68bc02eb007ec0307c0611b38359ebab7812395e57a720c9cc84fe0541e04ce80f359db11b8002e812eb00048b91560000b38e0d7a2a0046a084004126a2aa8ea1a75465d50cf65a4eb4eca47bad0427f47a38e265ea136cead837541d592c926ea2bd4d7a86f50dfa2be437d8ffa01f523ea1eea3eea01ea21ea27d4b3afce336540c3a74cebc3391174a27e41fdaa525c6a24e270b0ad34761c1d73b28dfa0df508f518f504f53bea0fd41dd44ba897510bb73d75f2cc818afe0aea55d46ba8d7516fa0965a6fb5e09682a4d01dd4bba8f750efa33e407dc8c119ea23d4c7a84f34ff4891fd1d4b4d7c4382f0501ae214b5f0778efa02f525ea2eea0555c10fe4e2a2a6de6c6ef3482a59f140fe64505b5ab94d9adea30ea8e3afc630fc19dc751201872c62ae9e9a71c819b92037c8bf36a209b8f335f20df22df21df27dfb9207e447e42f880d553fee75dba0d129d7e5857d214e96152b229346c7c803e421f213f233f20bf22bf21bf208798c3c417e47fe9813dc4d2bbffbed982e10d1ad5d8e903b2ac5073d75508aee249f9f1cc732bcb45184a3c051574f26c2d812f232f20af22af29a0afef93ef271eb2c1a4babae236f206f226f216f7fe23bef20ef22ef21ef231f201f220b9352fa899a0ac38f6f5ca2ec3bb2dfa7223c9f229f219f235f20b7d8cd5de4059ecbc545e40ad9205b64c7d388ec91834a351dc4e7f94c91e52509853aea961a25a3149406e50ae557a3af506e506e51ee50ee511e501e517a287d942f64dcfd99345d7a5de13e7e6f4fba6da143942794679417945794379411ca186582f28ef281d241f99a2d35d5f5c5be9411636cd5c414e5517deda6a56b1d55c6ad275ec6168d98fd31c5a11b6e5c6a12fe441a7659d136370f57b71a16d25f405941594559435947d940d944d9429176d841d945d9d3558126edb4e8972dc8ff43dfb7b443ab62b6c951529f7d940394439423946394139453f929220de54c9b5b5bb3ffc56f14e51ce502e512a58b22852ea25428e6d75f8b62511c8a470928112589760a31843a337a796762bba9d16434054d83e60acd359a1b34b768eed0dca37940f388e69ba4972ac1cbadadb9ae127dba93d1d4ba1524891aa30ef8bf2aab7deaabeac1b8a7e5aa9a14754dc381fae07524e97775101bb2753876d533a11188dfbfa6e4bff912c66b8768fa68066886689ed0ccbe8ccb581e7f41f38ae60dcd08cdf86f45b6525f003d41f38ee6e3afa8836609cddfb5aaefff0fa96fed4dbe2bf5e7a8f9319de77a6c370ffb1b579afd3707f76ffa4dff9a7e83fb37fd63e937b87fd33f967e83fb37fd63e93ffffbbffee37f0022a768dd</data>
+ </image>
+ <image name="image5">
+ <data format="XPM.GZ" length="128996">789ced9dd972e338b0a6efcf53741cde9d98e048a2c42526e6c2fb6e97f765622e0082fb4edbe56562de7d20fc495ab259d57697ababab079551923e1104b12412093045fff7fffae3eacbc11ffff5dfffe3f68edd25fe1f7eccda3ffe4bdc17c5d3fffadffff3fffcc77f4e6cfb8fc968f2c778e24dfe98fce77ffb8fff3cbefbc3ffc318a97f733656158fe732e7ecb167953eb8ecd99a737a4d3c01b3b8e7d99c93db9eed39e775cf8e4abfd9b3ab8e9f2b9e74d7e397c4947f7a416c8d3c95ff6ecf4cf131f114e7e71b3dabeb8997e3beaadf65cf62ce51d47330e7b03b7f3656edc3f6145b5dfb1841cfea7a628398ca1b3e135b481f3ef5ac8e0bbb67d53ee931f10ced115a1de3fac94ecfea7ac91db13d56f9194ecf5355deb59e55febc2276c6aa3d38da5fb6ce88abf638eb78acda37deee59b52f3f2476519ef82bb1370e5579be289e75ed633e13bbc8bf367a56ed9b5ac4de04fad6319ba8f22729319fa8f216eb8aed11c3f5f929b14ff53de978a2cacfd11f4ea70fe698d81fabebf1959e55fb2505716829fd8da11fb2b696ca2f18f5acda233489c796aa9f112af64621fa27b27a56f947fb60995e9d9f97c4134bb55f9e134fa7eafa26f483cd354af113b10dfd310c620fed1b108fadb1d2e77893783a55ed97853d2bfd8a47c4337076446c4fd5f9e64c31efda2f5d256663d57f1ce381cbf4aafcc63eb133c578bcee59952ff47b56e9b39b8e67687f93d89da9faa7382e7b0bfd9b5f105bd04fce88bd992a9fb1db33c65fdeb34a9fef11b3992a4fec10735c8fb9c462a2ea9f42bf853cae388b7b867dd823f6674a9fd2a867f42fef59a5cf4a62612bfd0d268a83ae7d23b457309e8d55f912b4673899d8aa7c428daff1a8ef8f2d6297ec8d0796f963fcccc0d2f2abeb850f8ac7ddf962133cf6d09fd91a78623bca3e324eecdaaa7ee29298da9ba9fa8ea57d247b7b4dec8d707d0b3cf11cd4ef96d8477b4787606b0c7dcd943d1b5bddf9c1182c05e53f03cbfc94fea4bbc4cc51fa1bac13fbb6eaef08f59bcaf2617e62c4347ecc11b10ffb6b986029b02f57c421ec4fba0f9e0847f56fe010878e3a3fb9ec59a53794bd1ecfbaeb870d3187fd8d9ec1d618e54f58cfaafcd941cfea7a51416ccf305f4f15db5d7df83331d527098803d8d30cf571baf4e911b183f9915f1087987f121f2c354ce9637e039e30d8bbfc096c7918df19dac391ea05fba4c6c7d8edcbb74b1ce07a21f4d795faa7ea9b6e1007d0ff3c065b8eabf493a17e5e975f84fa487b0a7fc080fe7a137b82f2dc13734be9730e7df5acc056fa23a02f4c6aac6adf18fdcb2ce1c27e6d1287d4dfd00f2edb07fe04f4974f272ee6e3afc49603fbabc6fbd89fcc26b0678c9891fd877ef8d389a7d878249eba2affdc067b6caccacfd19f42f697aa7f8ef120c6e4ff981e31cdcf02fd21269ea5cad7227fe171f40fc7f80ebafcd2756217fe9b80fd08e40851f9a72760991fe6ff33621fed1bd2f1a9e7a9fa97d0f7405e4fe517648a43d923eafc749338447fc7285f38756da57fe98c9879aabf2ad8bfd0f3619ff376ce93defe254fc4fe18fea70396eda1ca67ae80a5030c7d58054f030ffd77481c7aeafa8cce970e8bba7ed1803d61a9eb35117160a9f45c8dd7893490183f91416c63bc4467e0a96fc3de297d98cced25fae3043c26ff364ec1b2bc6a3c678962ab4b9f6f82a58154f549736281f92712e099ec6075fc91d8417b167b60265b40d5e794780c7fa4d8e918f63e50f679329d30d8c33824e613f8134f1dc37fca03f0cc65aafc31da7f36b128bd059ef90cfa57836dcbc6fca2ecc5c4eee68368021eb3912a5ffc052cf50ffe0dda43ce764ce55fa17e36b3307f97eb1d633ecb703d477a502a7f03fde158f614f373d433e607d4cf9931ea3fd4c7b12da6faab2cc11ec77cda3e83990bfdcf953f3d71bbeb05b8be2bed01fc4d0eb65cf86b0dce97ad87f9bbddeb19fe1eeaebd93683ff89fe66d202c0bf457d991c01c8ff1a6c7394b7457f3236427f2428bf1cadf0b7c43eb10b7b91b4c43ed20721b1a0f18df6e0d678a2fa876f1173f8b391f2afe4d90ce9c51eb180bf1e33e200fa1ea0bcfe2c84bd2ea1bfbee7a37d9b73309ba13d5a9f983ba82ffa4f4cc8dea5681f61f968dfe808ec584ce5578fc08cbbeafc36ec19eb3365bf64e97cac77529f5820ff868ecbf260be50f3cf24ecea937062f22782c79e317fa1bca1c5309e2bd80f69ef70bd8af26381a3fa3756e5978b8380c663464cf9276b608773a53fa507eef22b6fc1b2ff55f98a03e209fce740ad17e7ee17ca978e88438c87ca04b329e69750d94f6b3212b43e77c1d614f63a9a120753f88bfbc4945fa6fc0fcb722daeae9fa5c43370a3dacb9a32f2472b9477ca2d4ff57f39219eb9eafaa1d2474b9a1f8ef940d947cb96e583bee2fab62c1fe6ff43627b027f43adc72db91a467d22073ca1f56a6a802d0bfa1c9f124fc109da4bcec6f0c7c42e58ea3feccf1ed826ff226ac0ee18f54d4be290abfe6cefc14c9658f5d711b183f925447a6fe663be8b38d8b339c697b207169bda0efc2be80773c6e01af933263d20557e357e2d2efd358c47f407972da0f237be82bbf3cb827802ce5ab0c7b8aa1f53fe8ce53b16d617c53598710be3afee19faaefc414b3853a4cfa14f82b9386ea2bf83996dabf6aa76c0fe88a9eb6568ffb06bfff419ec09aeca5740bf43b92044f91f7a56f947aaffa72379be6aff3a07cbebabfc8b73628ef56e7d4dec83b99a9fa6e3eefc80d819413fd32b30631cf652f9bbd349975e8c88c7b41f14805d97c15fa1f45d7d9a1330f3a0bfb500730bebc158b5af1cac6c0cff26044f2dd427da00bb1ee6e3aa01b36ebfc222f6a11ff555c7982ff329984f6dd83be5af4ce70d80f6437e53d9bf2abf7642dc9dff402c7b50a547f9a6724252e91bd467ea5b1ef61f6ec18187f9d3b8e819f3f53931cdafb5b257d3d984633e14e7c401f66b580a9e06e8bfe8063cb3b15fd0a2feb3aefc7540ec8319da631638f0478c6b6217e5f173622a5f8ef2d8e390f66f9ec1727e817ee1fa76d7de654b2c305e72a763b41ffb0a0e66f04759436ca33cfed79e71fc8298ca5b287b3095a39bf60b33f08cf64ba255b037c6f82aa0cf8e2c8f1a9ff5d79ee1ff401f1c39fd63beb18919e647f30c1c58d85ff353e22998d5c4541f3fec19f618e5732dda1f125be0990b7f8fa3bcae3d81ff5be07a6ed75efc0e1c907e9b9b3dc39f2a8927d4bfc8df93fe39f6ab2fc1d23f51c77d0e1621dac328c0c108f9b1bb9eb11eb925a6eb65180fac5b3f24a7c474bd00edcba4c38afd53d48771cf57f5f71fc142405f7c8338a0f2543da37d2c622a6f86f1c7bbebc7b02fdc9e79d02fe823173efad77861ecffe5c4d4ff26cae3cbf914fbf947603b803f5533b03376d5f5e3bc63d4af40f97de9c0a13f6a6246d7bb24a6f92285be8baebd12624b603f8061bc8aa987fa060760cfc1fcc8d0fe424e38d8bfbe2376a12fe679cfea38bb25f6707d76dd31d2fb1b3dabf409ec57e070d4d740ff05c2c6713fe919fbbda7c4541ebfe8591dcf602fc2aebe1ce50ba763dabf3c04f3998ff463e2c0c77e27b198213fdfe959d97f5fd987d9488ce1bf738f783285be1df58cfcce892d1ce713e229f20b54fbcfc69d3e30033c9d59f0a7127067ff8b63301758cfb116ec93bfe89b6031c2f57dd1338e3f1153f97d464ce58d71fd8945eb1b7e067626f0ffc30aec8f7cd8c3965860bf9cdd1307584ff83e3195cfb8ea19fb6b5fc1b23cf0b70be209fcd36a9bd8e2ea78b34eec70ec27297d9e598eeda13e25d8f7511e7f9f58e07aecb2671cbf26a6f236ab60993fecb5d287999c7f611fd808ec7b980ffd9a984fd5783171bdd97806ff581c806dee607d8bfc678e87f2161bc4cc83fe401f66be4bfed2b867355efd75e2eefa5b3de37846cc68be867edab6c0fe2b47ffd8be3d55e3cd3fec19f6f18198ee4ff069cff037bbf31d1ff9b9c4543ef6d033f6cba1bfce9863bf2cc4f871261cfb15f90ad8f268be427f3b33ba7ef20896e601e30ffae7f8332aef1a31d587553dc33fd8048b11d6f781da3f93cb1f07feb7b088c9dff491def527b81fe3df125bd80faa309e5d41fe7482f6f59c10fb950dc6bf27d77faa3e75461c92fd833e78fe08fbd5fe17e231f139315d3fc4f860ae87fd2913e9991770ac67d03e727d020eaf8905d90bd487cb0914ebd15b62b2efbe0de602fb5921fa934bf74df56f750296e30ff71bd47a5caa978ff1e7633cf99c637dec5ff50c7d9e11fb389ea27ffdce7e6427c4be8ff529f4458c7de84bb4036602e3314479c57cc3459d8ffe16bef0b15f8cf11138238c3771426c83138cbf8031dcff1231584ee8b08f1eb1032e30de03dfe6c84ff963b350fa6fb06fdbc433629798f2ab611f439ff6b3b3636297a9fc4ca50ff6c8b55ccca75b60e9df63ffa301fb13dc1faa1f881d942750f6ce96d61cfb4b510c765cdc7f09cec08cf6ff440496ee3efa7f9598ae274ce229b8bc03fbdc53f945aabfedc934a0fd3965afe4e2db813fc147602666f0e7368803f8cb660e96d7c37c9f113b58cf844abfe5e44ff7b30de43795fda5fa5f24c474ff50a8f16fcf6623ac1fea5330b3501eb325f6e06fa74aff6d7bec41bf0ca4b79947f71f5d6281f1c467c421ce8f94bdb71de90e603e53e35d4e3e1ce35b84e0f90d63357fac808329ec65a0fc619bcd3b44e9e30d7180f54e88f6656c84fd8e1af5658183f1c1d05edc99d8281f8e4b7717f3490cf6a721fc07e6811d017d1038dff7840dfb8df6133301ff2440fb04d203c0fc0ffd0a2d81f561780f960b589407fd15ca16803ed3718f51f9547bccb78b70ff46e4c4b68df5b80fe616f9ff05b18dfb952d03cbee807d54fd29bd11daff2c4ec1d2dc203e40b5a763cd6ce8a77f06f67c5ccfa7e36c84fd6a7315cca7985fe219584c7ccc8f6a3c3972c183fbb522007b13ec37b233621bccaf8905fc977c02e653da1fa888c99f8defc082f958bf2affcb9106cdc77e3eca677bb4df652a7be6386c8aeb3531f10cfb75a1b24f8e2b0d3418f5f1e4fa15eb150bec09d843f302cc1cd42f75c022c0f51b1c675dfe35fa470e6faa1fda9fcf42f8fbe21eecd27e5780fee3d27f55e50d72e2109c7d05731ff341a8e60f474e7f8887318fc0738d56f923bd2ff387ff33057b1efc1b6110d3fde71aed2bcd17fcbbfc9638c4f504fa4774d763022c4704fcf76db027e09f15285fc019fcbd5ced5f3ae1648478a9fc19ec8ea16f1907fb138c7f5f95c71d793eca2fc063a95f984f1bb0c7c15cf9ebeec49e60fd281ec06ee8805d30b3697ff49498637eae2fc152dfb05e51e3cdb53c5a6f09d57eeed4b6697da3f65fdd9937433c012b895d70ee818507fb18ec8203b9a250acfacbb5a58787f1770c96f541ff096281f2a76afe739d8947f67e053cbfc1a6cebf077bb6abf22f67604ef75302d4c7158180fd56fe82eb75fd290ab0377555fd4ad4d70bc7489fa2fdd8c442fa64422c509e689b38c4fd23f608662357e94348e94588fc22f40fb7c6148f7606168eaffa23c0f5fdee3877c0b27e984f52e290f2bf01fb13f85fd51db185f110a3fdfdaefd4b35be5c614d907facecbb1b4c6ddc8f88c660670cff38db27eeec3dce0f6479703f08ed1d74e325c5f583ee7a39da3f94e610fb95e8dfd0a2783b03ed1176f9e7eb3d633d0c7d0fe5f5707f52f9ab9ef4de60bfb9414cfbc7460b66b45f1c297df1c6960b7de111b84b2f1ec1decc55f648dc123b8867f09fc16c8ceb0757e0be3fd5fce6599d7e66288fe5ce703f569c11bbb47f5782998df88c9081fd00f30957fd2b8dd108fa9b3760d7467ec9183cbf81a6cec7f566dd78304ec06c42e317e96742a0bc31da47ce2e144f83ebd92ecd7f11ceb7035b20fe46f597e75801f637eb0b3077d05f31da47aef6e07f646a3ef2a441417bb4289f2bd3e3fed501b187f93a1d133370bb0f1663ec2714ca3ff0bc2edeb65d25a6fdb6c625a6fd1c730ab66d8a3fbc01bb1ec64384f697fe97abf4bb15c41cf35752818587f9b655e3c3635dfc6cb9db33f6e39b9e95fe541631e977b40e96fe10f68bd1fe723d86eb15ca7e7bbc8b176d2a620ff15d35cacf8309c65783fcfd5188f8a4c20677f196cd2e31c5371453629a1f8c7bf0748afb19e904ec0af8dfc621586a20f6c71ec06cecc1df1c13d3fe6046d793d313ee372afbea892efeb285fe4bef10ebefea8698d6efe565cfaa7fda8d8eb1def4315e859c4eb1df730ce623dcaf493d70e0e2faa5b2c7f3ed62ba3ec66730a6f8b9868e8f03acd7f30cecd17a23aa885df82706f43564538cd77c0b2cd7932a7db24d2c576c4adfa00fd23ae078097d0de5f056e797aafc6cd4c5ff7113dce51fd371b9c0457b297b2b173b140fd726603961c31eae83ad09eeefa63178ea419fd81158faa3b0b7cfc41cfd2b4ec1f2fa586f8d891d4fe96bb90296f329e2078e891df83795b21f6cd2c59795fbe02efead708967b4df8bfa4aeb04ffbddc00730bf6ae52fdc1ac2ebe2d427d2d36c378ad50bea91522fea8f2c15dfc98790896e31be577c082f6434b5c7f26a73fd8af1db0b487ea787b4bec503cc2297148f78771bd9933c6fc239ec0ccc3fabd3a034b7f1efe0a078b29e6f706fd6977f157ed16782a607fd90c3c1b51fc5a0196f305ce57e395c9050ed98763628a772a13628a37aa0f8829dee896778cf5697b0d9e917e64a8bfe350fc4eb0d733d6ff1eb1c0f8c9d09e0ea3784373b763dcff30c39e618fa09f6e17cf54dbc42edaeb3620a6f2e78fe0a940bc5b7505b647b8df1aa17f5c87ee7735289fd7c50bd5e85fe9ef617fab0c88e9fe6684fe90ab53b4e76d426c637c140f607b82fd98f24bcfb8de2db185e319f44ffa93b41f83f1c6a623ec6f09e80f633eeec78a963844fc5f7101eeec451b1087585f54c84f0e47d4e716edcb27141fd85cf58cfe758939e227eac39e61cf5788291ea7f08929fea6757a56fd5fcf8843f45f5b81ad09ec4348e92d4efec22a31c50fb51e7108ffab10e029ed5fa5d027ee507c7d4ef57128be8b537a1632a54f0dec81dfddef6ff63b867f5bc23ef5f151a5411c62fd51eef58cf939ea19f5dd06cbe904f139d0077fea933e52fa19ed97c518afbe4df148f109d8a1f8fe98ce77e87e9a28c1b2ffb1ff047df0032ea06fa8afe8e28918f455f82efc2d8ef209e9af603d8ef60ba62ee6f314fa13f4c7d5fccfc22e5ebb9e82272ef4a3b90477f13d05ec71283d7cdc7f57fa36ff7903fc99e08198f6fb8a5b70e808c5b7cabf95ea4abf7f686db0ac0fda9f8ecfa447a6cebf07bb01e249aa4be210eb1bb3024b8b82fec6f9d27ae37e41b20176a83cc105d825fdf457c07c0afb911f830381f2d64a3fa53a0b8a577a02cfc6b0c7e535b88b27c9943de053e94f613e74c15d3c88e980858bf9bc50faca677d7cc716d8b2d1bfd50cdcc50bb497c433ecc79b19987b4c953753f64daede5dccf7e206ecd9d88fcc947ecad99a8e3728bf330be13fd447e0ee7e7589fc9dee7e797d424cf7978304ec4e61cf38ae27d7038857f577883ddc1f4839b85b4fd4549e7044eb51353f71b7bbbf1b7d057b0ef65b4b0b2c5b08fe9c1a2f5c8e1ed81f13fde77186fb37f908dcf983b59a8f391bdb589f27b8be9c90612fe373b04c8ffdff13e250c0df46ffb27086e32daec7bbfb77b7c84f2e6fb03e67a8bffc077d6ed57e30f79d19d63335f453aed7e9fe861abf5cf4d743fa40ea33fa1bf9cbf535f507f4319c8e307eea0998d1fe67a3f2f747130bfb4da50feef6fff90ed81dd1fd400bec4f18fca7f59ed1df3158da23c4e79d13fbe042f5af3f96d32becfd3e31edf70b0696cb6df8b728cfb83bbf51faee4fc63efcc596389ca2bd63659f7ccb9ed17cb50bf6a6146f661333f287b7c03cc47aa83804cbcba9f4b5ea4fb9fca1fdefb000db16e653f3122c5b1cebab1cecd3faaa447bccbafdef3603f331e22dfc53f0fc9b391b09b1032e50be999ceeb11f89feb03d8178dc06ed6933babfdda07eb69c5055ff8867b0fc06eb071c97eb6fa44f513f279c20ff02d777bbfde1fc08dc1daf943df73d8b61be4eeec1d23dc2fe6703f63de4dfaaf9d4679300f347f315cc7cd49fa13de788f55a00169cf6af511e39c108f8a3684fded9a76a0d6c3b881f4a2ec09e83fb0fad09e68ce2774660f90dfc15b41f172ee21b836d7077bdf62bb107ae717ddf9f229ea855fe862fbd5bf88311f45738f4fb4803fa2b3afbd49e80658f607e3e251668ef46d937399dcfb09f6da23c81ec2fc40fb9e0be7c6a7fcb0fe70b1255ff15b09cbf70bf1bfd1d7a145f573b603ea6f18ffe0a658d54fb9563b0e0b89f93aaf953c8d511e643e316ecfb284f5182c584fc33a56f62d2ed6fb52d78e661ff81ef833d8ef6681270c804e633357e85d5edbfb517e06e7d138ec05dfc4685f258810dfb19abfe10533784fdcf4ec11eed8f65e76046ebb192b8db4f6b7cb0a0fbb1c616b89b8f4a353f887effacbc22a6fdaefc0eec4db03e098fc1b27bb1bf47e98300e32956e347c8f917f6a58ac1cc63580f6e80e5f853fd6db8c4336a2fd59ff3e825f857cd26586a14f4eb092c2cdc8f8a50bef97c8af17c446cc3be664f3d237e56f96b62ee9ec03fb2c18cf6636ed15e6ed77ee1182c8703ecdd0e58e6077f5ad90fe175fb1db1d277c13cfa3d6788facbd919fbc9d153cfd84f378839f67f18f4657e7b18fb8fa80febca1f29fb2fe6c31ff67f0d2ced13f6bf56c082d6ab0571c0309f981658faa7d81f447ff8ccc5fa31467b480304fb61a0bfe7db3df03f707d3f18e1fe62b80aeef24bd11eb242b41e45f9e6f16fb8dfdc100bd42f417b05f31590eaaf6b6201fbe7e37a810860ef128cc7a0bb5ef944cc497fd47a4184d319fc5113fa25574b881fe1c71dd3ef3d717de95d533c2aca1bf6eb85823884bfd6a07fc260067da84e8919c543a9fe0e46ae8bfa442d583a50184f5fc172f989fb436b1da33f932b62dadf2a4cb0f0a12fe1141cbaa8af50f6241877f1ce994d4cf753330196164a8d8f5b9338c4feb97f020ec6f0c7f21938f4a93f91df8453fc7cb80deeae9fa03cf3f804ccbf3bc414df9e35c43edaa3da050753dc8facd01e5677bd0af599ce02d8ffc203bb743f26dd03f300fa2456c0c114fb8f85b207c1cc1ee37c63020e687c8a9a78067b52d071693f607f1931952707dbfe88e2b99fc0b284c8af22b631df445b6039bfa2fe4a7f02c79f527c31aeefc86f703f24ee19f1a9687fa73b9fad103370adfcd3c0b569fe09d07f6e77bc52f37fd0fb2f09aee7f9f4fbd07097d8c37c186f74ecc0de3c82bbfc0af40f73693d99a2bf99f42771ffe212dc5f5fd9838073fa3d6484fee4b23931bf203f1e78b89fd33c11730ff7bbfd8e7dd88ba067dcaf38008702d78b94bd91def408bff708b688ad19e617357f04d240a13c02e513624c7c444cf1456d040e2cf4473521a6f55173030ec7986f9a8098fca9f09c98a37c2df2970d46f13d0f603983637e9f10533c8789fe93ff70bfea16e337f468bf39467b4afb84f343d43f0c26343f1d12d37a853f1207b05f09a597e583bfade6db701e4f85fb0f39b1057f26f6c0c2c3ef59838e397ebf1c9e1207f0dfcb1370375f0516b18feb15ca7f0ec7ccc17aa2c6f131a778b4ca0677f359b407163efa27bd270e68bf76031c8c11afdf3c80c311f6c78bdd9e51be2d625a5f150131cd27a16a7fe99d04a86f86face7f2e87fb8f7b3d63bcc6e090da3f38279e427fea8ec95e461d537b94f7c401b852f35f6875f63fc6f5e6f612f7430f8967d8ef6f42b0ac1fee97ec134f103f50ae75ecc1be16c4541eb64edc95c725a6f2346afe0aa75d79980f0e26d8dfc8d68929fec0fc0a96ed8178b8805820bf58d9cb7016d8d8ff8d6f883dec9f97cfe06ebf216c89e9fc16fa26d77fb85f501e11bbb047cd16b18ff880e0091cb8f03f2b8f98fcd162b567cc17db3d637f9ff29b5b40559eac631abffd71da4f2b8839ee179a5760b9be81ff7d473c0527949f6c7fb4ef3eb17490d4f857fe61e8c8fae0f7d0e89f7efe080431c37e586c1273f44ffe85d8477c627ade33ecc92db1c0fd9ba206870ef6dfaa9698f4a1ac7a463c31c69f2b2d1ce6e79438c4fea0c9c052dfb0df87f27b6286f62c66c464cf9a3d628aa76c0b621ffe4b35220e31de4be88fd7d9bf04fae08523ecc7a574fedce2a8f6488969bf27e88e4fb09f60d6c4640f8a6d628fdaa3ec19fb1d938ed17fe521318da706e9e71bd498ff2e88c9be34d007164c301e18ce6721eda7c4827842f14b2bc416ca9b05c453707142cc281e6ead6394af4a88a97c594e4cfd59627cf1ee7e76bb4eecc27f688c8ed1bec52331e97f3322e6185f01f48787ddfeed3531fd3ea139236658ffd665cf583fa4c41cdc8e7a86bf7edb33ee1f5df68cfd42de33e2ab7a46ff9a49cfb0bf2bc4646fca9d9eb11edc27a6f66a319efc2efeb4b08843fa3d24e6235fea239e477442ec623f841df40cffeb8ed8c3ef6df23131adbf9ac39e713ffb4bc7e46fdc1053798363e290fa17f5179dbed77b3d633f2022a6feaa1f896ddadf5a25f610af67d8c40c1caef70c7f68a767ec1f793de3f9206b3de3f78223620e7fddecceeffc877d6281fcdbed9ee15fa51da33dfc71cf8867b07a867dedd2537f6653626aaf02f64bae37a14f85434cfd13d6c4148f9a571d53bcdd61cf580f9ac482e28bd67ac6fdda9498fcb5f6a167ac9faa9e717facee19f1bd7ecf680fd133f627c6c454bf5af9c761d895bf7a24a6f265b39e11df7fdd33ecd98898ae9f653d633df5d433e2adee7bc6fd8bbd9ee19f1c1287b49f53f70c7ddaec19ebcff59eb1df72d033ea6ff4acea7b7ca745cbb2402f4c438b9617d17aa16548b45e681912ad175a8644eb859621d17aa16548b45e681912ad175a8644eb859621d17aa165483ea017cce4a63f7844fcea5a68f96cf9805e04666846666c265a0ffefdf201bd48cdcccccdc22ccdcaac7f75b9b5fc5cf9907fd198ad796bde99f7e6d75f5dee8fd57151de7dde83f9683e99cfe68ab9fa92cff7aff2ab6bfa79f201bd5833d7cd0d73536ac696b96deefcea927f4076e7a2fa6dfee9dbe9f696685fa63f300fcd23f34bd7565a2fde08378fcd13f3d43c937a716e5e9897e6d5af2efb476bba50cb6bf3c61c996373625afdb1a9395b3ac396df39cbe72f581cd7f4e49b613083bf3dfafaddf00d6104466844bfba15dedf5a7faa17be111b89911a99911b85511a9551cbf7c6688d5be3371a218b7a61dc1fdf195f8d07f9fad81d339e8ce7c5f4c68afc6ed55833d68d0df5cd92c531368d2df9ba6dec18bb6f8fbed18b3d63df38300e8da35fdd0aef6fadefeb85f1c538364e8c53e3cc38372e8c4bf3566ac695712de9c6181963636258bfba0eefade9825e4c659fcf0c69110ca73b66b8af6aee3193198c1ddf31fe3607e633c1e63fc88958fcf6e86bbd6089e1b094652cffd5adf0fed6faae5ea4ac6025ab586d9cb386b5ecd6bc6577e629bb678dfce62b7b608fece91bbb1aff3059ead567d9db2b6c55beaebd3ed6a75957af1b32cde6400e5bf2fb6db6c376bbef968eeec9a3fbeca0d78b4376c4beb06376f2ab5be1fdadf56dbd30beb05376c6cea5065c9877ecd2c8d99551b06ba364376cc4c6ecab3c32ff138bd3df413396fa6d26fbcd9ecf23cc797dac4fe3328f9b5c1ee30cdf702e3ffb5ceddef0407e0e7964ac76672e1d8de5e784a75dbe3ce3392f78c9ab5fdd0aef6fad6feb05af79c35b7ecb2e8c2b6923a4853037f91dbb312ee7d6c338e3f7724e39e75ff9037ffcd5f5784f4d17e6119b3ff167bec257d9caeb637dedd7f83adfe09b7c8b6fd3373b5c5a07ae562d7c9f1ff0437ec4bff47ab178f4989ff0537ed6ebc539bfe097fc8a5fffea56787f6b7d472f6ef8c8b836cff898dd497fe2dc28f8c4a8cc7376c92dc5259fca23d77cc6ed5f5d0f2d9f2bdfd50b87bbec6a3e7f481db8e69e6f72cb574f7bf17d5fc839456a8a1ff821bff77f9bf59796f7c9f7f4c28ffdc4a8e733899ffa19bbf6a57ef8855ffab9fc94fb955c9b9cfb353bf713bff9d5f5d0f2b9f25dbd68a5b779cdced9955fb26b357354f33fe5629eabcfb57fcbbeca59e5debcf37fa37d0c2def91efeac53dbb947d5ecad9a39edb0a56f3b1b41c5ffd079f4b4b212d86ffe83f718fddfbcf1fbdae967fb67c572f56fc55f3d65f9333c8fadc42f84ffec6fcdd3cf33715d77236d9927663dbff9dee966879877c572f76fd3de94ff8fe3e56a47ea57ccdb9461c18f3d9e5d03ff2bf98e7feb1ffdbecd768799f7c7f5fcb3ff5cfa45f79ee6f4adb70ee5f30a515acf12fa5d53895df5ef9d7fe8d3ff2c7bfba1e5a3e57bebf0fee4f7ccb9ffa33ffd2bf94fee5ad6fb30be3427a190ebb993f3b5b9862fe9441feab6ba1e5b3e54fefa7a6fe89f08510810845e46f8bd8b745225291895c14a214d5efb007aee5a3f2aef80b266ad18856dc8a3b712fbe8a07f1289ec4b35831d9af2ebf969f23fa77025a8644eb859621d17aa16548b45e681912ad175a8644eb859621d17aa16548b45e681912ad175a8644eb859621d17aa16548b45e681912ad175a8644eb859621d17aa16548b45e6819928fea8558156b625d6c884db185f371aed816dbefbde2e76aa1d811bb624fec8b83cf6b93f71efdfef373c4e1b7537db40dfeee91fb31bd1047e28b381627e2549c89739cfff11a7e661dc585b81457f2fd5adc7c5e9bbcf7e89fe8c5488cbf95ea836d90fcc3f562226bdb3d07650fe7bf7a02c8aa988a99b08523dcee7be105666004ace3b7cf1bfaeb12f0c05f621104411844418cfc832448832cc8df52500465500575a07e4319b4c16d7017dc075f830799ee31787c93e229780e5682d597122fa45cba6ad7b2c15ab08e4fafafd79d196c049b92b68cd5405adb6027d81da8c15eb01f1cccf3080e83a3e04b70fccfd30b16c9729e2c9fbfdcc3c1a94c71169c0717c1657085ef83ebe046be8ed4194bcf1b9aff05f11fd48b49b0f4bc9e601accccf95fd6a6e75a04523b032f34df5268845253431efa8a4418a8f7f0652c2fa708a66124291eb217cb57ed8fed85499876a99673a3efb250ea68588465588575d884eddb1a84b7f47e17de877fdb73103fa617a1d4f3f071f9fcd74f9292299ea43ccbf7157c1fae866bb24f2e97cff81c79ad17c6cebc7ce17ab841ad295b3adcc4b597c998aa11fb186ed179bd7fd495ef4d8a79ce3b437ab17cd59763e16eb817ee53cb2ce5467a71101e8647e197f0383c094fc3b3c11ad07c1d5e84979fd76e7f261fd48b2b593e7ab647b889f35fcd23737db809474ac66f8fbf7a6e4dc8c21f2b7fc0c3c922b308bd175a2faddfbd2f934c397d39cf98bed58b5729bea317cb575d3c16ce427be87abd4d724237f42233322216f1efd520f22311053fd65aef978fe945140693288ae22889d228c3f9cbfd1ee5b206455446555447cd905e2c3e6fe8c76d47d446b791cc23ba8f948d8d1e22d9aad153f4bcdcaa6f295a89d4f35aa335f5ba1ea9f1399f47a2cd686b20c576b4235f77174bdca75cbaead255f6a2fdc1eb75671e4487d1917cff121d4727dfaf41741a9d45e73f430bdeca47d7a9d14574195d0597d1757483f35fe9c5281a4713b61759d1349a0deac5c2f3863e634e89ecc8117b911b79738acdd88859cc63ff75abbea658c4411cc651acfcbba08d93388db358cef7711197736f7239455cc575b012378b25ee532e5d75f12af2583b74bdfeccdbe3bb581e8fefe3afe1fe9fd5207e881f032bf81b9e5aa5f7b5b40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43f241bd78f3b7667fb5a838c9fbf829fed093ebbf1faffbbe9488d08c57e26fb444bc363f4ea9d6ffac3cffb4d8f10feac59bbf353b287befcced2329bfdb06f146bcf9f1b3de73ec7b7aa1aebc157ff7f7117fd2b24997ea9f163bfe41bd78f5b76687a2bff1f769e39de3bb7857beefc9f7fdefa5fcb1e81c8a0632f1370b9723b8e383f8303e8abfc42a82fa25e2fb7564f8723a59de93f8343e8bcf5ff25fce77f1caf145aca22ee3ab58c537c637f1281ebf4ea5f2188cf3ee52fdd362c73fa617afffd6ec50f437fe3e6d3c91ed6bc9f7a97c9f7d2fe58f458553efd8b1d2d6e598eb586960ec2588ff5e8af85e8c0c5f4e777c378fa34b8c84bde4bf9c6fdf978f094ffc44cc238f8336091299731225f1dbf2a95a0ec679f7a9fe61b1e31fd48b577f6b7628fa1b7f9f36dc4c92244db2244f8a797cdab753fe98a8de29c571a2fe02e572cc7552274dd2cae3aab59623be1723c397d321e23ddc491662ff96f35decf1f020b94f540f240fc9a361274fc9f372f9fab61b8cf37e49f5cf8a1dffe0ef475efdadd96f457fab7692b6255995ffd7fe2ce58f4485cf7349d6938d04e5598ab94eb692ed9708eea1886fbc2fa7ebf562e725c572becb794466a27e0b93ec25fbc94172389cea5b71de8ba9fe49b1e31fd48b577f6bf65bd1dfaa9d8e922fc97170999cfc59cacff02f92d3e4ec75cc35e7891c3fc905a55988f85ed68be574b29c2aee3bb95cc87f29dfe5de4aae12fae54472938c92f150f9d4b98371de4bb5f807c58e7f4c2f5effadd96f457f533b491f23a15f547c2fe58feb85bcd63499bd8eb94eecc449dcc4235f6e21e2fb95bd584a777c979aa991b294bfa458ceb73b776ee9533f15298dcc344cdffcbdd0979a0dc7792fa7fafcd8f1bf472fb47c4fd2384d7e75193e4bb45e7c8ea4699aa5f9dff77bb09f2d5a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd03224bfbf5ea445f2252d7fa405de7bf4df1d01fe3ac7df5e2faab48e473fd202ef3dfaef8e007f5d82df5b2fc283b449dbf436a5d89b9798efa5cf4bf1dc8b11dfef7f1af8bf3d027c597e77bd48ef53d9efe943aa9e69b918f3bdf4f9557cf5db88eff73d0dfcdf1c01be2cbfbd5e3ca5cff275255d9df7d162ccf7d2e757f1d56f23bedfff34f07f6b04f8b2fcde7a91aea5ebe946ba29652bdd5e8ef95efcfc3abefa6dc4f7479e06feef8c007f5d8bdf5a2f76d25dfab497eebf7acaf7e2e7a5f8eae588eff73f0dfcdf1d01feba16bfb55e1ca4345ac3f5f428fdb218f3bdf4c4efa5f8eae588eff73f0dfcdf1d01feba16bfb35efcd53a7f564effa608f065d17af157e5df1601be2cff3fea85963f17ad175a8644eb859621d17aa16548b45e681912ad175a8644eb859621d17aa16548b45e681912ad175a8644eb859621d17aa165487e77bd983fb3edf82e3d4e4fd2d379cc9bfc7c661ae9b97cbf482f4d2362f2d3d572faf43abd4947e95f7e96ecdf53cad79ffeee76fdfdf5c2dc4d27b25d2dd9d253f93e93efb6b12a3f39f2932bdfbde5f4999919196371c6ffc9a57cfde9ef6ed7df5f2f323f13c77749611a5960ac66a17c8fb2384bb234cbd873bc9de5cbe9e7ef991cb3197e75726dde9823736c4e4c0b4fa3cdaa643dab557e8da41667092f300323607f67295f3ea91c6eb3bbec3efeb498acef97f8f7d70b65a32f32158b9b3d648fd953f69cad64abd95ab62e5b73ed75faf97bba267b5ac5d41bf7c777c657e341be3ecaf337e4199bd956f628dfb7b31df9ba8bb382ebe046befea55faafcd552bed28bbd6c5fbe1efc3dedfafbeb05dbc90e657b1dcd39fb223f1dcbf178929d6667999cc1b38bd7e9e7eff388de4cc5771ad2aa1b33c396afce3ca637bb0af3ec3abbc946d9389b645636c559e16a287529f84b51d77fb594f34fc66af74db4c5e6cfd5fe5bfaeadfa017b29d67b2bdd42f2932d9bf9923ffbb99777c979bf2ff407ad3c8a5a79723c2fa59f6d9cabcc5d99a3ae2b338177990877924d3c48b67fdd5d9fea3a5cc12f94d22cb921edfc55fbb1c8c99d68bf7977feed1e5996c47353fe7c5fc9b5c7a0e7915cab921af8dd9ebf4999937792b7b5ff51193bdc5ecf93cc2d46f75f2f9d8decbeff3af73af307fe8af62fca05e7ca094b99cc5f2a7fc3997de4ededb8b7c2d97334ef2973c9c8f97f8f7d70bd9621bf9668ebf2db19e6f4b56bf0cc977e5a7bdb7e9e7ebd47c3fa779dab0f9137fe62b7c95ada8b30e558e47f917f57edc9db5f8feb34b999fe4a7f9597e9e5fe497f85d893aff2abfce6ff21ff82dee474afc7bebc5ff2ff277af57b55efc1ea2f542cb3f41b45e681912ad175a8644eb859621d17aa16548b45e681912ad175a8644eb859621d17aa16548b45e681912ad175a8644eb859621f9a05e3c988fe693f96cae98df7846f67baffa599a988ff3496ee5d37c217e21b773478a9bf791b485597c7acb7d440a56f0c22f44b1f0d4a5222c222971d13fa1ab488bec579672513ea817f3a70a1e9887e691f9e5c7aefa597a51e445215fcba27af92eb7d591ba68fa546d71fbf1bc3f4f8abbe25ebe7e2d1e16be0bd5eb63f1d47ff35cacfcca522eca07f562fe145267f1ece52865b62aa662266ce10877888bd562ad582f367e34ce65a175378b2df9ba5decbc7c477ab15b50b44bb15fa8189ce2b0382abe142ad2a638294e8bb3e2bc507195c56571555c1737c54f8a7929c6c544be5ac5c2b35b492f66854dec146823af344ba3545159252ffd529441a9d2965119974999967f8355f9985e182bf3385463cd5837e839c4cb51cac1e9f15d70169c0717c16570f596cbfcf8ae2ce6e9e969e9e3e0077fdd5396a5b414655d362fdfcde791b22d6fcbbbf25ea5f95aaa715a3e96726c96ea89a8e54a2967c272ad54cf6e2f37ca4df5bef5735ab9dc2e77e6f19de5eecb77f379a4dc2bf7cb83523d83b43c2a950d2e8fcb13f97aaa3e9f9572bc9517a58a362eaf4af53cd9f2e6e79472513ea8171e3399c1d8f11de3387b394ad9d83bbe0b9fa43ccbf795019e7631b69f358f905e8c96f562fe1a1e94e372a2d258a51aa7e5acb44ba754a3b2f4940fe254e69c2aa3faa95193c37a815256bcf2551944a5bc8f2aaca22aae94d751a5ca07892a6521aabc2a7e662917e5637ac1d4e862721e609b387b394a791e5b1dde842325e3b73cd78be0245ceff482852cfcb1f2631ea9cab7f388fcb69a6b4b55574dd5aa3ed8ac6eabbb0a36e4b15a78fa7ee9fd5cbdc03c523dbc9d47e4b78f736da99eaae74a7917d17db55aad55b063c78b9a50a5ff58bd7099c74d2ecfe2f4371a96a39423394f48f52ea32aaaa3e62dcfe7916aa3dafc3cffa2daaab6e77e6735a417bb95f430aafd4acd71d5617534f7242a65adabe34a3d6fbb52f6ba3aab947ff4b3e691eaa2ba9cfb9dd5c26f507bbdb8aee4bc508d2a35a3665935997b12957a9e7335add43aab5235aa9c0ab6ee1f378ff035bece37f826dfe2db387b394a391a45e368c2f6222b9a46b3b75c79b5591b35fb3cbda879ede7562dcaa797efb04ead833aac239922ae954daed33a93dfe6b51a73755957755d37b5b224f56d7d57dfd75feb87bf52867794f2b17e2afcfab93c79f90eebd47aa55eadd7648af55a796cf566bd556fd73bb59a71eabd7abf3ea80f6bf56ba432aabfd4c7e55e7df257caf031f9b17dad5ff5abda8f487d5a7de2df6bf969a53cabff96df9dbe57fefd7aa1e5af88de07d732245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb907c4c2fbae79342be9de67be7ff8c5ad4175dcc05f1657d557fadafeb854885dcae297ab31e23f5dbb8f19f2514fb1dd593b7545bf5b49ed576bd10375bbbb5576f37e6621c0ee2351aa3610d1f8a26ff5cf9a0bdd89d0b9e3a68ee7e2bc7bf5b2f1abf11cb7ad1a888b8266c16fe7a7a6e3771235bb1499bacd38bf9eb62dcf8cf9222fc363579237bbf299b8588f6a66e64999ab6b95d3eabb96bee9baf2f792c46937faefc957964a977979eaebd6851d451d7f4e49b6130832f9ef999fad13c348fe5fdb25ed091a7e6f985a45eac34abf2dbb5667d492ffab8f19f27dfd58b8d6653be6e35db0bdfedcc63faaac766291eb4d96bf69b83c53c5ea2c93f5b7e542f969fae2d65c99a189bc6967cdd36768cddc5337f3c0ebc6fc1c3e6a8f9f212bbd77f7fdc9c34a7cdc2af5ca45e9c35e7f2c84593bccc238b71e33f4f649f5e3657cd7573f3969a51336e268dd52cc47e36b34696b0711a77290faf355f68399afcb3e587f562e9e9daaf8f329f0916b090452c7e7dec73a4355a1559fad65e84072d6ffd179ea768451bb46197fa75dcf8cf93369a8ffe366e93014adb4cbee6ed82a7d0166dd9566ddd2ecc7045d8b6ed6d957484b277d1e49f2d3faa17af9faefdeae896fc7e9bedb0dde5f9e3c7e3c0fb16bc6befe792dbf2f555bc5efbd03ebe90d28ba7f6b95d59d68b2e6efce74bbdd9aebea56ece68d7ded46dbddd78a122ac9edacd760b51e3cbd1e49f2f3fac17af9eae6d1a9c1fdf719f0bf539909f431ecd9fb4bd78e6e7db8d457bd16eb72a3abcdd6df79653c823fbedc11bbd5071e33f535a65ebdba3f6cb001db727f2f5b43d5b487f3effe5407bd12efcf582b92664b3f6aabd6e6f5e47937fbefcf03cf2eae9da521776b8b40e5cb534dfe707fc901ff12f7f975ee4523bdb513b6e27add54edbd9db142f9f97e3c67fa6b476ebb46eebdd9a6fe9d6b865857fcb6ffd3915aa24b7e236b80d6fa378c10b8326548fb7f16d729b2e47937fbee87d2d2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb9068bdd032245a2fb40c89d60b2d43a2f542cb90747aa145cbb2fce7fffd1ffff1ff00a5630b2d</data>
+ </image>
+ <image name="image6">
+ <data format="XPM.GZ" length="61912">789ced9d5973e3b8d2a6efcfafe838bc3b31c14fa2c42d26e6c22eeffbbe4dcc050812dc77799d98ff3e29bc4996abcaaea5bbdc555f870bd1921e1104128944220142eefffacf1f5747fb7ffce7bffed52fc422957fc844747ffc27bc2dcbc7fffd7ffed7fffdd7bfa7aef5c7746aff319d39f61fd6bfffc7bffe9dd97fc83f8c89feb7e4450bf698bb10ecfbcc2b23ebfb3bc92cf8fe1eac14b8b8d33ca5a4f3978723cf975c2d98ad89a3cbbb050ff5f5dbcc62e26b3e670e707f170f3cd5f99b42b3b5ac41971f33cf2791aeff7164a5f992d99eeafc7d06a6f2b43c15da3ba3eb5afeca6776a6b6aeff1a3ccaab98a5057d7dd03c27f9b5bcfdae66db0f67a8ef8e399ae9f27ae8d319cbbb66563357ebd3d2ec4e27332d7f3f078ff99f98d55c9757429f626adbe01d66c716babfd05e212c703f1bd8d1e5e5079a036a31fa1be507623ad1f2f41bccf3b9d66f019653dfd1ed2d2bcd21e91bfd7faf391a3843f9d15c89509727c0a42fad9f1afa57d6dcd6fd916f8facebefd01f4a38ae963fd7fa2673726c4fcba3db339d4e6cd457d760cbe7f67660e17b81be0e267b98ccf4fd3ed80a5cddbe450116c2d5f9cb33cdb3217f1d80add0d3faab9e982347cb9333db3381febb05933d6bf9163158043eec578fbfe97ce270f9c86fcf6c47eba33f018bd0d6f254916667ea4e353725d8722d8c1fc8ef04135bd7bf4835bb43fddd1d5844b6ee8f6e171c4c5ddd9e48fb8ba96745b6d647e7800332195d5fae59589685f642dfc2f6032d7fa4c7db3498cda08f12f204b617a07f8e344b6aafb69f04fa94945f5f8fce996d472e39dc65761cdd9eee141c38becedf6c690e49235ade7cc2ec5afa7a3e638e2c3d3e726d7f44aea5db23d7c154bed687b2995d4797a76e993dd4af9281595ffbccbeabdb135a23ebfaa20d66016e61bfca0a30be13e45754be96273e66f6b9be726057b747362343df2d73e0eaf112a991b5fea32366e96afba8604f6a1eb8bafc02fda7ec20407f68fd58139257b74f9a236bf9939239803c51c81cbababfa2fb91b53ea3217f84f115c5ccca43ffe9f65853cb437f240698e4853c8a3944fdf18791f5f8888d9175fba2023c9fa0fc58f7bf650df983ed91b5bed425b3827caa06cf27d04f7437b0a7f51d5e8cace58b56992d4f975fe0faccf2677a7c269b606abf96dfd81959d71fdf80a93eadbf24629e427f6a73604ffb0b9532737dd1707de6e9f6e7da9f59f3993547fd533095afafc7dbcc16da1b9f8facdb1baf0c0cff269391b5fc528daceb0f67cc334ff75f78c53c87bf0def986d4fb7274c47863d64ccae0ffd69ff69d9963bd3f65b5be0d97caef513bb60aa0fe3e16c647dbfcc46867e0f98e7dc7f2db3ed617c5d313b903f3a6176e19fbb39385081ce5f23bf4316abfbbfb965766698ef7c66171caf81a93e9d3f3e1b59eb33d81b19f2ae323b684f7c3d32ecb56276a1cf2865f67cb4af1e19fe281f59d717ee33fbe00ef6e3c889d4fd1d6b7f6ab954bed67fa046c6f894cc1ef7af60f6d17fe1d3c85adeb060a60958f3eac8da1e438f39f075f919daeb3a9300f1cc0df32c807d3f323b81ae3f83fd796431881f3c661ff353d58f8cf96b9f99e3b3e26664dd5f02edf348dfba7e7138b22e3f0d985d5c4f8e993de84b4c46d6fd2387fc1ee6ab7887d9c775c5f5933ef475b53232faf39639f0a1efbd91319e86fba5afc74787fef2a42575ff17b8dfb75cc4bb4d3230f4d3b4cc1ef49759ccbe857869ca2c105fb42b23ebeb29eccf277de8fa52c9ccfa4805b3cff6733232da630c0cfb899f9805c667ec3173bc245746c6782f47d6f616b0fca40f5d7f3cc817c2dea263e6c8877fdf625642db7f0afd08aa5fdf9f9c8e0cfffcc01ca0ff92c9c8da9f191f59971fb403a33f939e5972fbd60766fb7046d6f9e5edc8f0df833c21c6773c1919fef97e64ad5f993347be962f3c675642979f42bfc2b102adcf16e333a01ed6e5671e73c0f670c94c06a6ed1de331a0f669fd2537cc121cef8facdb9774cc21fa33998d8cf1773e32ece18a3902079391e19f8a91a19f4d66c5fd3f1f19d7eb91b53e24ec2fb069c9a4c7df35f314f6106e8cacedab423c14903fc2fa03f2ca617ce473e600e3ab84bdc9798078dc3c650e595f8fcc11db47cbacd09fc21f19e307f196b427ccc5c8ba7f843b32fc4f3cb0c07c793e32eceb7864dddf6ac23c853ee4cdc8c86f8d8cf867a86f2e74fd05da1352827d40de90e4d7fa4b8ec0241ff862648cb739f394fb578c8c786597d9022726f30ce339b60646ffa9e391b53ed550ff5c687b52db2363fecd46d6f5abd591119f737b6c1b1cc623c39fec30bb01ea3746d6facc10df85ce1ce3ad41fdd18c16e0babde8ef88e215cc373db382bf48215f44fad2fd61f8236bfb4b0be629c64bb23bb2be9e9c8face517d5c8f06f3bcc16ec29b9679ef1f5a1fe19ec23e84686ff7a649e838372646d2f528eacf52bdb91313e87f6d8c81fdf8f8cf50ceb8bf489f58760f6b0fe0ce5c898ffd05f91e306babd1dcbe78713ccdf7a7fca52d43e3d5e8cd9c8589fd9cc7370703830ec29be6076604ff27064ad2fb935b22e3fee985d5c8f73660ff6130b66c1f6a4ed7b3621f568fb4c6330c987feae46d6ed3304f31ced117bcc36c66ff2c4eca07f92eb91f5f57883d9e5f1608f8cf8663632faeb84d9639e8e8cf5f5209f87f110b823c3dfde31fb3c5e86f224ae077a3e9c4d87782a2dc1b6cdfdf591b5be0cce4fed41ff36cc2eec29f1983df497b81e19f69d33fbe0606d64cc17ab03c3dee24b6681fe55923940fc1a9e3087583fa8411e85eb15e77766f077fd1558ccb01fda68fb9c59b4a2d0f90bf4af359b58babee28cd9423c9b07ccbc3f27f9fe21fe49996d07f6927623a3fdb7cc1efadf988e8cf1b0c7ecc31e0c7764f80b9687f4017fb33d32fce7dec85a9fe26464941f3307ac6f7be000eb89845921be2d7db0c3faed600f3421a17d0dcaa30c96eeafcc65f62cd837ec73b61c014b5ed4ccf44fd7cf3cacd724df4ff3b56e6f908287f9d8d865667d9837cc02fa4cee4646feed91a1ff43e680f5e98f8cfdb04db03391b02fbeee4ca5ee8f0cfd45cb79b457a1bcf9104fa5b0eff9204f703632e617c51ca0ff8cbb91d15f0723a3bf5c6609fb4f9c9191df1c18e35b76cc5180f9fc815971ff627ccc1d4b627d988d8cf996cb7766e08ccb7364a0f55372fbdc89d4feade7f2fd08febebb0707d399d68789f6db7608f9c5fec0985f9215e608fe28b962567cbd1e59dba3b81c59cb1730d37a16f1f836f35462beba679e4b5d7f76c81cc19e2b1d0f517787787e92c39e1cb260c493183f8e1da13f4c9759b1bca8dfa1faf5fd863d32ec719f790a165c1fe91bfb9b06b3136a792bf843c7e5fd8250c70b33773ec17eb93c62e6f57378c9ec61fd94a37ed7b660cfe92d7384f190de332be676645dbe1181495ef8f3ad91e18fe623233e3e60b6703da946d6f615ac30cf24e69b75e639fa27f046c67ce6337ba1d6673901bb53dc1fa2fce57a1cfb7dd09f47fe53db4bfa087626b0376393d982fd9a1633af2f8cbd91917f6b643d7e828c790e7f282e986d8cdfe0616089f553c8ec48dddfd26376a5b61fd90f1c62be3e62f6d0be241919fb3901b31f8207f90270299843b4affa0076b9fe1efde38533d85788fafd417f29e4f7493f589f47cc837e12e639fad3588cacdb2386fc36ec35b86176e15f7af86fdf57185f29f4231c1be3d5b81c18fec448991dee8f9581d95e4e983d89f5d815b32f110fde310bd88f983207d047b0ca1ca2bc0ae353907de1795dc33c873c12ed1bd7bbf2143cac074cd84f40edd1d7cd736617fa318f0746f9a260f6589e983908313ea6cc32c47e0afa2f7067f05f45c9ec627e6a50bfb468c1a8e583fec6f5ab89f12a493ec42777cc2e73c3ec717f48661ffa31ea91119ff623c31e4e9805c66f50318721fcd30ab30af13c0cfe4c8ef680f243c7477f8bed81b9be236681fe350f99b93f4d8f59227ff0c81ca2ff63ceeff2f82d108f46163fdf0ba1ef68d88f3531de23aa4ff78771cb1c62bc8a8d91f57581fe8ddc49087bc4fcae9c08e3cdb8625621fc29ec4fb953c85787cc02ede9f87a18c0bfd6dadfcc2714a1eaf2d50698e603ec073e81a9fd5a3e738d394479c62a98e4c37ccce551fd58dfe9f97e3e753cac7fcc23305dd7f28b92d90a114f85cc3394679c8e0cf9f8bac7f152fdc0ec607eec7a7068431f26f25377c0be8d8a791e223efdc0ec45d8cf7f62e6f1ddb76031c1f3f454dbdb7c36c427e616f30cfd67b62363bf60601bfeded86776d1de02f7d3748bfe3073b0cbf20b83d98d602f19b307f9f39659a23fc20998965bd81fd6f1d59ce2211eafa8df767d9417f4cc61a4f377ebe0508698dfd1bf0ef907e8739dd983ff285be600fe5d3c0d1ce1fcc81e73c4f1e01cecb1be2bc8e7ce3c0bf1e62698e4c1f3d006ec717b8b8039c07c181e3047b86ec21e3c3708e11f2f07467bcd6d6619e1fc4bc51c417fe20eec4d209f69334fd19fd135b3407d913532d62fcc21cb63405e9fe241c40fb0379fe64f8c978e398c604fc1c818df9cdf9b46d89fd860b6307ea288d9437fc91d661fed8b16cc12f2f5676031c5fad4d4fe6c2e86f656ebcc16e6bf5cc7a3f380fc03fcdb26f31cf1ab447f2ff76fb57e1af447e008ac57cc023cc85f66cc339e5f3d6681f11d042363fdbecb1c80a30fcc11ecaf86bd4b9207fd25c0637d1eb383f1df73fe680a7d14e0d0199e27c07f85a42f8c7fe8371cf425a0bf88d6479a33d873e4ccf0fc37857d442efbcbfc1eec71fc6928663fc27ec314ec5b52db4ba3e7d7b972e6789e9bc31e9567435fa56476d19e723a32d66326d8677f14e9f8ca9e38bcff6d1a60cfc6782ff8bac7f163a8fda5bd3c7082e743a7cc11e6abc205fb3c9f34dade6ccbe5fdbe48db8f3d230d227e2ec0341dc29e1ec0549fe6e305b388305f7e00fb5e84fe359843f88f450516d604fe53c737f6dc1390bf489903b4bf34c1242ff68fb5bdda3679183c5f85bcf40ffb01115ff725fbc31978e8ff5cfb33dbb1f87c5a7604a6f6603dbb0ba6fbf5f82c39bfaf70bd46fbdce1fee80c3c9ce7301bb013c17e0adddfb6e771fc99d5609ffd518dfef1c414d70be8d75fcee87a7c32fb21f46b4e9815fc6b097d097f82f9ba5c61e6f9a7db000fed6f507f309fc25fab8059e0797e01f969fcb2bdc29e022a1fe7a33c660bf15bbdc1ec717d1d38b2112f947afcd992ec19cf935de639c7dfe87f29bc08e705214f48ee10fe19ed0f03c1e34dafffec682e719e237c042f2d44cb037b8dbc08f6541d0cccf66481493f5abe2c61f6793ebc6356b0d75acfe7b6f214caab21bfa2fbf1bc760d2c2cf8ab05ec5d8592fb5bcf5fce84e4c1fec231d89fa07d45ceccebaf728399d7fbb56eaf43e315feb35e030b1bf2e4f9c0ec0ff47cee58536f027b39007b2eeca3be66e678be8ec0541ff637f6c1b400423c80fa96c7a5705e53db9b33f36db42f3807073eaec70d58da0af6afc78b339f5283352fc0339fed7b0ea611017b5360b2273cefdb65e6f56d00f96d3bc0f325e3863982ff2a51bf33b3717e340bc1543df6a70c661be32fef46c6f9d30de600f690f3fd42c09f293dbf38ae6de3fc506a0c8ce7e94501a60000f11fdaeb0a8be361f43f4d6788173394e751fdd87f77c082fd7f7ec5ec221eeba76069217e0df4782671670acf1720bfa01903f10aec47f833d85b8efa850860af998e1f9dc0677b2a4b668fe37be84752fc83f90ff626c95e30de0e9915c6778ef242d21ffc03fa93e65facef023d9f3a91c3fb8dd50c4cf268fd762eb3c4f9bb52fb6747517feafc35f4a3a83c9cb7807e5430c7f3ce42cf67ee84dc2dfc9d64561c6f24601a2f8877f47877a73eefbfe55330f963adaf3a667610df19f7ccec7f9b7570308d74fd46c3ecc0fee3022c95827fd5fa772d9ff7378a8c99e5ab2ec1543ed69b57605230e217b4cf0a27e05ccf8feecce7fdb5ec8499d7d795f68feedc5633dd9e6c15ecfb685f39030b1bf16ea9c72345032ee2cfee001c4ca1ff3c639ea3bd7dcdec4c75ffb668bf23e6b0a7c66416984f231f2c5df8fb4ac7f3ae2b78bd11e878ddf55c8e3fd32db01f40def48a99d7d715eaf304fbd3e6011c38902f42fffb3403e33cc51398f48dfd1de893c20bf4af407b7cba1ffa8d985dcc3fc51a580adeaf803df9a18bf56ba6fda12b68bcc35ea13f41e521ff1138f4f0fca6467f059687f3efe119d89d61ffd8dc64e6f696da1fbad2f2913fafc082d7ebcd0933cf6f26ec357415d6af750a16bc9e32505f48edc3f8d864e6f8b6e8c032847d64da9fb9e46d39bede078736ce33f67c3d52f0d7959ecf5d3597539c87661611fc73057d28c9ebad85aecf1b7f2f519b602b9ceafeca57c0a45fc4b3da1f90f2f8bac8c12efbd7e618ecf3fe74138205af2f9b357010c11e5b73608cdf68060e6d057faee733cf1aca3771dd1ae6abec0a4cf327fcc335b3cbfb4d3d38f414f617b4bd7a33ba8ef3dc297890c7f4c1e114e33dd5fde3cd8585f1956e33cfa18ff48cd9c6f8cf1e99793fa13d040753f8ef86afcb09dadb4dc0213f2f6af4fce6d901c737d90e33c763b9020ff7d7dade3c6736c779b716e5d3f8877c8d9eaf3d9a1ff9fce03a988637d6433d33af0ff34bb0b4a0af08f64106ac70be7bc21c801b1d4f5374e3235eaef7c1647e88ff70bf4ff309e483fcbe2f303e5af49f1ff0fc10e8f14bd32fef9ff747600aa871def49e39843ef3042ce790b787fe849af07ea0b67f724f7cdea196e06006ff536f81a9bd98ff63662e2f3f61b6591f15385488bf5a3d7f7bd297dc9e024cfe58eba38d99397e4b8f9823b657d8b7a4e917f105f447c35fe9f695a83f240788f230fe4231837e1a0126fdc1feb69915ec39457f45541fcef75e80697e81fddf325b189fd906584e707fbdc7cced6f7c660ff14f0e7d2a1170fb20bfa2f2f07b8d2933ef4f3697cc21e68b1af2aaa1fdf52eb3cbf53d31737d99d6973f1112faad77c0941ffe58db13791f2e3fd4f309cdd633ccafd91678e8ef6c937906ee0fc1e114f1646082234be1f7285a7ffe2c98205eccee9867989f2a9b59a1bdc50a584e78fff29299fdc14231f3f3cd86cb27fb437b2c66017f98697dfb73d22fd6030b669bd75336b380ff4821ff9c0c02f397b64f7ff9f81deb478339c0fab959054b89fa22ddff3e05e8586fb728df111eec3dbb05071ccf08be1ed9d0979c303bf0a752db83ef52c48ef801fa716588faf20be608fec544ffb9a10faef4fce293c3c3f98fd6050b7e7ed4a1bd5e3045fbaa1a2ce7b0e7ae0547367e5fd4c11e7c9a1f319ea10f3f98637e2fc034bde0f760750926ff89f58fc3ccf169fb0026fd617c9c82297ec47a5ccf4f7e1004f03f2de4a1e2d0fef61e4cf30fda0bf9a4b460cf8d070e2df89f0efa0e07f933f457184cb0dfdffacc73c4e7d90a33ef0fb739730479aa0c3c8cbf600626fd637f79171ccdc139f41339ce5ccb6f3c817d7efedfa2ff22c1fb492de4277f83fdb0d4619e73bc79c8ccfbb90de451cb0d247d7f029653de2f2f986d9ebf779815f45f1c81495ff0b733e639f4b7c07852113f0f57ba3c31f15cfc1e24dd0307bcdf52286696cfdc004733f8eb54cf5f624af680fc7a7e15d6dc9b61bd6180e93af61f6230f52fce8fdbccb348975795ccdc1f95c5cce3d97c62e6f19a9f83297ec2f366e4277f057fdf1e30dbb087ea0a4cf7c33f9c814307f7b77abe1373c1fbfdcd3d38f039fed91819f158c01c623e6fb5bd0b3b98c05f7482d9c278cd5230f937b46fca1cb1ff437b68b58efe0af5f8178e6be13c5a06f99cf1fe6be608fddf437fb49a843f48b57d088a86109f65b8ee52fb71ff8499eda7ba0153fdb0a75d6697edc965160afb257abc0acfe3f3a7f906b370f07cff124cf68b78468c0cff75c2ecf1ef6b3266ee9f3e042b17fea1d0fe5af8aec0ef433b0f3cf4770afdf9637d057388f2b29c79d0f71c4cf3059eafeb785dd0f214e7b7eb164c11159e97423e1addb0df3862e6f967618243670e7bba6396bcbe867e035210f6cfd1bfd43dbcbe823d0592d74b5dc3ec633f35d2fe5d4857e0bc647e04a67004e70f3f80c309c6539b0d8cf9deec47c6f8c178095dd7c6f3d82b661fcfa3ab4db00c113f573973c4f18a030e23b4afb19915fc4304fb8e5cfefd44017d45d281bef205b3077df6a760ea6f9cdf86bf506282e7292dc6cfd2bf217ed2f707133798e3f7723d7384f3d4cd1138f0f9fcc22198e4c3fca0fb8b664f17f164c11cfaf0674adb476051fd90f71a4ce561ff6b0a961c7f561598f40bf966cc5c5ea6fd4d40f10defef3087bcbf56ec8129fec27906adaf60ee713cdc28e608bfdf140e98e61fe4d7e32f581ecf05ef8087eb62054ce319e7afb57d937147b0a706fa73fc898bf5e384798adf83660698c27facff4b308d1fd8fb2533f77face79bc0157c9eb8dd05cb19fc67bb3132fadf058702cf873ae8d78d260ee6d75b664761bdf40856537ede067d78be85dfcf0606f3b07e407b3c8a57e1afa11ff23f880fd43d38b4b1be53d0872ff87c707a019612edef72300518781eb10e8ea6687fadc74320243f9f68618f14bec0feda8ed9437b1625333f9f5202aca6882f15ec3370b97fc42eb3827cf531d82393d0d71fc064e1a86f134cfd87f5f81a38e4df2b9bda7f0492664c9cb746ff48b270ec6f304b07f141b6cfccf1813a05871ef4b710cc2c5fb90a8e383e290e982944d18cf2c248802bc81f05fcfb9606f22b9a5f74fbe3041cd8787e9ef3f5e1f79cbd0f8e783fb4770646fcd365cc0ec673578f8cfd443dfee56469207a7ed805870ec6fb220453f988b7cf991dac2fda05b3447b822bb09a810ddd7e5a1d291e3f3d98f263bda0c7bfb4e4f0fce88959b0fe6fc0e1101fbacc0ecfaffbe088f7630d6dbf7226f87c6abb0d0e793fb23b06471ccf440158f17a307c609ec15e3bc8379753fc1e2a3d6156585fe76b600ab8b11ed0fd236dc9e7e7da75e600ebc3760b4cfe12bf9f40fd7634c17ca3747f91f55100afedbd610e517ebdca1c815bb47779dc16fbf73a5e90ae2f6cf4cf1e588658bfa7d0a71b5a687fbec3ac305fa9164ce317fb9b7a3ea0d5bacdf6abed5ffafe047f7fa316ccd246fcbbcf1ce1ef7914b02f3f9ac19f887b661bfe21d2fe4d0adfc2f3ce9a993c10ceabcfc0543ffa639b59e0fe5acf2f321013fcbd8d1ef635c6133df411440af6d11e0f8cf674d0fff21fec15fd2987f56d77091eea13da3f9336797eefa05fea0e3cdfeea1cf504d71feb3bf64f6e08f6a3d7fca484c6ddd1e057b8ea83cd837da43bd8b786101fb8bd404f3498efe5762cefa7f62b6e12f0cb49fd64f7c7edc648e107ff6683fcd0e36e6bf98999f5784e85fb53c50a7ebd3f61a527480f2cd6b661feb8756324b9ebfe6e090cfb7190fcc92f7af66605a5fe1fe73308d3fac27b43f59de0dfb495d661ff69e5ae0e1fe74ceccebd77e1dacf8fc6f7f3132e4d7f155688533c4a36ac6eca0fdbd0d8e787ddba523a3bf0bb0e2f35ffddac8e8ffad9161af8723e3f9bb8e6fa8f6395834cc21af57569915e697f604ace6ac9f1be661bdaffd3395c6fda7f698d9de825b6601fd19e7cc21ef07f660b2379cb7d6f17c6887bc1fa5f699f9bc9cbc62161cef296689f12012665e6ff5cc8ae3a700fde5487ebe2551be3394a7ce46c6799503667ededa7f0047119e37f6d09f43e5437ef4b72b78ffb66ac1cb0851d77709a6f6e37cfd1a73042ea11f8abff87935ecd71bea576b23e3f7373133f797da1a19e7898e06c6faa4823d78113fefac6e9987fa60bf349b61ff5575e041ff6dcdcccfdb0cbe4efe1acfbf0e47c6f39c9499d71365c26c63bd19a3bf058d60e8678f59419ee4c3c8381f8cfb29be43fbb253661bf59557ccbcbe6bd19f4bff8d7842c79321c56373acf71b66c9e717a1cf20e2fd5cf37664cc8f7c7fc4fb29e62af31cf59b6a64ecd7409f520afc3d19f5080ef9f98e3a67e6f3775d055613cc07ed29b303f905ca0b29a2447bb7c1d2c3fe4075ce2cf0f74a8ae9c038df60a2ffc2c1dfb46bccbcbf6470f911af678d43665e3fe5037b6caf7c3fc987f5b35eff8411ad6810efa27fa390cf939a685f34e8a7e6eb43792a620ef83c11fcb192fcfbbb18fa5543fcd1a33e154de7f067abcc738c87f29499cb37b53ea209c5afda9eda277038c5fe9c71c4ccfbb1ed3e38e2e767221b19eb711daf46d3907fcf5d5c31cf70deafb0996d8c97649dd9477cd9ef812317fbc7e682d9c3f8e81ec04af2f302ddfe65eddc9e5d6685eb7d05567c5ea4fcc0eca27f949ebfa265fc89e775da5f4473b2473cbf7198f9f7a6f50db38ff8bfd0f15344fe15fead672609f03cef14ac787d11a2fd0e4554588f433e5abf229ecf7707c67c5e9c80238e6feaf591315f4f98b93fdb29333f2f341e9915ec2bd0e33b726580fe561e987a18fe79600bf3ad6899677c7ea06476515fbacecce7235b6b64acc76f997dc4cfd529339faf3486f2f979671f83d50cfb3795f66f541aefd7a4bb23a3bd37cc43ffaf30f3f3d478c1ccfbb7868ebf223fe4f57f79018ef8bc58753732f42b985dc417c536b3cfed9d8d8ce7cf87cc82e50b9803b437d1fe3f5afef9353cdf803d937fe6f370e7cc1c9f94f5c8587fcc99597ff29a3980fdf63958b9381f90a37f8288f7832a8799e7f3ea7e64b45f8c8cfd8503e680f5bf3632cea7c25e289ae0f305e8ef3014a83f54cc12f19d1133f3f35909fd2fcd1f7f4fa464e6f56884fe8dc8c163ff779399cfdf069299cfb3ca103cdc1feaf9584d46d6f1ab9ad208c4f9ff35e688cfd70ccceb2f710a1eee977a3c292b926cdfda3faa59e4613cc94d66c1f399b657351fe289e89059c21f7567605abee23cbd33327e8fa7ed7fb9da63d6fe4bd178863d06c723e3fcba000ff9fb55e688ef477b5c65f3f92e3d5e95a7f8f9b4e90ccce78786eb33d88fd862e6e77d6a8739c47cdca3fd4205e8ef453230dadf07cc8ae5d3fdbbdc3e81bd47da7ed5727d87f39427ccec1fc2eb91f1bc6231327e6f6232479027d6f6a496f685dfaf1723e3fca2c72c71bf5a30871cbfe623c3bef478a0d2437efe2a9823f6efdb2323bed2fe76f9d74d71fec794e0e5bf251f2fded35b24ad6be33dbd45d2ba15efe92d92d66df08d24cd90d2b77245a63263ca9b504acdccccbf92b7304bb3326bb3315bb3e3ef7a7361de9a77e63dd5f5f0957c8fe693b962ae9a1fcc3573fd0724febe56fc58de0d73d3dc32b79976cc5dba738fefdcd1baddff463a300f297d2bd791796c9e50d9a794cecc73f3e2853c97fc7e655e9b37e6c49c9ad6986f66cee93bdb744cd7f4be92cfa7e16618c2080c6984afc8228dc888bee3bbd7d277e53594111b89911a19da66e446417796b8d3c8f55c5a2d137d5b531ade1ba3353aa33716c62d7d7367dcd1ebbdf1603c1a4fc68ab16a7c30d68c756383bedd5cde45e9d6d832b6897728ed1a7bc6be71601c1a47c6b171629cd2f767c6b971615c1a5794f7dab83126c6d4b08c993147fd94cb361cc3353cc317267ff7453e610821022145686c5330ad385f256291885464221785284d292a412d11b568442b3ad12f25100b713bc8ff69feb1943b716fac8b07cafb48253c8915a313abe203e55913eb462d36c4a6d812db24eb32f78ed8157b627f689b3858b65f1c0a9475a4e3aee365a26f4f280defa7e24c9c8b0b7129aee89b6b714daf376222a6c212333117b670842b3cfad65dde3524e2e5f345fa44c3c20844406b41711284a6a4a05e5139f320a66b49900a3fc8823c2882127706954e75d0046dd0f1775fe40b7a2a6911dc0677c17df0103c0ef5064fc10ad5b31a7c08d682754841393728f80b824dfa6e29c156b03dc8ff69feb11433d821996964077b54ef7e70101c0647c131e539094e833371199c071774dfa5ce7d155c53ebe763db2e831bfa3ce1f63fea186fba4cf4edf28f120eefb3601ed88113d03a0adfd0ab2fa98ba43efc2043494b4a49fe5526cbbb863494124c29472a3399cb4296926c48d6b291adec644f5713b990b7f22ec8e9f5fee3ddf2413eca27b92257f99b2ff2c90f54d29a5c971b72536ec9edf1ce1db92bf7e4be3c20a90e0789e511d5792c4f20c127f27f927f2c2594a7f24c9ea355f2425eca2b4ad7d48e1b39915369c9999cd3155be776a42befa5f7bc6d1fdb8ff3fed25f2672decb3d4bf2e3f4ba3cdcb15cffa9300e137c43af29a58cdef3b008cbb00aebb0216a43811296097975795dd82f73840b7a25bf12de51bae7ba1ec2c7f0295c311d7a5d1dee0d3f846be13ae5da08375fcb176e85dbe14eb81beec983703f3c080fc3a3f0383c094fc333ca435a092fc2d551e2cbf08a24b826896f3e93ff79fec9508abc80cc6815b5601a5ae16a380b6f480fcbfd262774a9d6e551e4657222337c8a8ce76dfbd87eac5df52ec072e5bffcb141644a5a74c45112a55116e55111a5f44d1995788d04bf57514db9498aa85d7e3ba42117a52eea29c722baa557f2d6d13da521df43f448f414add0eb2a7ff7215a8bd6a38d6833da8ab65fcdb713ed467bd17e74101d4647f4ed717442e9383a8dcea2f3e882eab91c64a5d72b2aef3aba61099ecbff3cbf1a4b994453ca6b71ab68ad1ad9f4eed0b52dec4d29330ac32ba5774ef46ab48c769eb7ed59fbb1ef2a755a3e36508a46b94a54aa3279a97255a852d16852b5aaf1aa24bf37aa559dead542dd2ebf1dd2908bd29dba570fea513d11af3cfb7e9956d507b5a6d6d586da0c2cb5a5b629eda85db5a7f6d5813a5447fcdd97f98ed5893a5567ea5c5da84b75a5aed50da5899a2a4bcd14f93e650fb29acb9d7397d6eb3ee55cf954fed8fc983f368652621107aa8b9779a855711847b18ae33889d3388bf3b888cbb8529731b7236ee2566dc6dd5072dcc70b53c6b7f15d60c5f771afd7e40f3a3dc64ff14abc1a7f88d7e2f57823de8cb7e2ed7827de25fa981ef87d2fde8f0fe2c3f8283ea6f787310db91ee293f8343e8bcfe9ea7a7cf1ecfb65ba8cafe2ebf8866a9bc453cab94c16d57e1ccfa8d6796c535a7ef752be8dd8a1725d2ad78bfda1c4c42449b7e3b3c4a02b2cab29139104946f99f3e253f93fcb3fc875429f293f7dbb947aaa5b7090c824a42b0f499844898abd24e63a9324a5abd950729227453c4bca4451fe69a263b0a4d2a94e9aa44dbaa44f16c96d7297dc270fc963f294ac107d4c15bfaf261f92b5643dd94836295735a62157956c25dbc90e95b19bec25fbcfbe5fa683e490caefe9fa367dbed3e936394a8e9393e4547fbbadbf7b29df5672969c53b91774c7e558e255724d72dc24132dbd4ea4db696225b3644eb4ff99fc9fe61f4ad922597749070ffa5bd4fe40b9ecc4a1ab2ec9b19378f43d72fba9991aa4b3864b7693452ad2209594cb4ff06c3bfc13294a551aa7499aa6599affa912de3e153abd5df9515aa6555a1ac9cbd7b56eeb3f919ab44dbbb44f17e96d7af7a74a78fb74afd35bd6f0903e526a5ebeaa75fbf49ede2269ddaebca7b7485ab7abefe92d92d6ed87f7f41609cf48dfd35ba477ddbe5d7ad7eddba577ddbe5d7ad7eddba59fa8dbf57423dd4cb7286da73be9eeaf6ed977a5bd743f3d480fd3a3f4f8e797fed3747b929ea667e9797a41e932bd4aafd39bbf554b7f264dd2696aa5334af3d44e9d9f5dfe4fd2ad9b7aa99f999991094a4126b3308b32f5b76beb07521667499666599667455666555667cdcfade1e7e8366bb32eebb345769bdd65f7d943f6983d652bd9eaafd1da77cafc215bcbd6b38d6c33dbcab6b39d6c37dbfbb935fc0cdd66fbd94176981d65c7d949769a9d65e7d94576995d65d7d933bf904db2696665b36caec9fef8faf1fd876b763237f3323f37c1b9918b3cf8be7b7399877994ab3cce933ccdb33ccf8bcf4a7f41e2b7d36d5ebef86d95d77993b77997f7f922bfcdeff2fbfc217fcc9ff29531cf6afe215fbeafe71b9a379fcb0bfad1946fe5dbf90ebdefe67bf9befee6203ffceebb8ff2e3fc243fcdcff2f3fc22bfccaff2eb4fae7f26f19fd36d7e934ff2a92ecfca67f93cd7a5e44eeee65eee17264a2e8c42142fda44218bb0880a55c44552a44556e44551944555d4c5e8c18ab6e89edfb394b4e8339bacce1be42e164b2a6e8b3b4df7c543f1583c152b5cffea4739b9cc0fc5f069bda0f6179bcbf28aadef6b79b15dec14bbc55eb15f1c1487c551715c9c7c72fd0b899f4b509c1667c57971515cbe70edaab82e6e0afc8d94b5625a58fadb5941f65fa0a54ee1d2ab57f8b8bb345f93b2344a5106a52cc3322a5519974999965999974539da79597d6a51aff984b22e9bb2d59fbab2a7d74579cbf5df7d9493f3de0f65960fe5e38fdb56f954ae94abe58772ad5c2f37cacfc6ce97123f97a0d43d586e973b2f5cdb2dc97397fbd06d7950ea72caa3f2b83c294ff5e7b3f29c5e2f4aee99f2ea5519afcb9b72524e4bab9c95f3d22e9dd22dbdd2afcccaf831dd56a20a2ac99fc3a515675e152147a53ecaf9a56eabf847755b25555a65555e15555955555d7d16257c29f17309aab6eaaa9ea45b7c79ad3cabc81eaabbc1df42aaeabe7aa81eaba7e5e762b6d46d7557ad7c4bea6ab5fa50ad55ebd546b5596d55dbd54eb55bed55fbd541354a57b4d5d177e8f6b83aa94ef98e5975f679fe4fe5f8e813aaf3e2877d6275515d5657d57575534daa696555b34fd70f2f4b3c6a6a5ed94bedbcd48e97745b39157981caabb417a8cd9aacae1675f06da96b5987d55e1d2d1ffcd7499dd6599dd745fd6ce6ababbaae9b65efd5edc7f2eaaeee9fd1a2beadefc63beeeb07fdfef8a5f49ce3a95ea957977359fda1fee2ead753bd5e6fd49bf556bd5defd4bbf55ebd5f1fd487c5f6b7241e653d5ace43f5f14bbaad4f6ab28ffaecb96eebf3faa2beacaf6a3d5fd637f5a49ed6563dfb96d4f5bcb66ba7766baff61bb3311ad1048d6cc2267a9eab514d9c594dd2a41fcb6bb226ff3897354553c20f68aa9aba699ab6e95ed32de5e91b9aff9adbe6ee33dbf23ebebe9c9afbe6a1796c9e9a158a144e9bd5e643b3d6ac371bdf92789475b3d96ab69b9d9774dbec367bcd7e73f033e2dbe6b0396a8e9b93e6b4396bce9b8be6b2b96aae9b9b6652cfff6ad96f959a697ed958cdac993776e3346ee3357e6bb6c65f2f395d6b454b63bd953f675dd6866dd4aa366e93366db3366f8bb66cabb6fed51afc8ac44ddb9266edb66bfb76d1deb677ed7dfbd03efe94b29fda9576b5fd69cf74dab576bddd6837dbad76bbdd6977dbbd76ffd76a6f39429fa7cfe43d680fdba3f6b83d694fdbb3f6bcbd682fdbabf6facfd5f472fa99fbb7ed4d3b69a794ac76f6f768ef5be935cd6a69e7addd3aaddb7aaddf999dd189ee3b57cbdf9bfee97be3af69f6ef48ff74ddfef97da0bf9efef9bafd75e95db76f97de75fb76e95db76f97de75fb76e95db76f97de75fb76e95db76f97de75fb76e95db76f97de75fb76e95db76f97de75fb76e95db76f97f4df8793efe92dd2bb6edf2ebdebf6ed92d66d38a6cfaf87bf79faada57dd7eddba577ddbe5d7ad7eddba5efd5ad29bb88de95f9720be22ee9d22eeb724dc5b3d7b74d7f4edab2abbaba6bde5aba1fd06d4befdd2bd2f6dda2bba5f7bbeea356efbf52efcfd2fb9f93f6a17ba4d7a717aeac7ca5aeaf5dfbabba5ded3e746b5adaf56e835e37bbadf1fa76b7f385e6f0badbed75fbdd017d3aec8ebae3ee843e9d7667dd7977f1a6bafd9ab497dd5577cd9f3fca77d34dba69677533fa3cefec17aebd9d6e9dceed3c2daddf9b5dd81bbd18aef641ffdc429ee9b60ffba8577d4c9f923eedb3feb9d7784bdd7e4ddaa22ffbaaaf3f93afe9c9d6fbaeefe975d1df7e79eded74dbdff5f7fd839676a57fec9ffae763e455bbed57c942cffb0ff4694df3fadfa3dbaf4abb9463a3dffc4c3e6dd7fd76bfd3eff67b2f5d7b3bdd520dfb78a74f07fd617ff4ecbebe3fd6df9f7ca1dbd3fe8c5ecf47d69ea0bf7c6bdd7e4ddafe8afebbee6f5e928f3e4ffa696fbd7ceded74fbf1bd9ff59bfdfcd97d1427f476eff4eee7baed767baff717e6a7ba5d180bb108de56b7af4bbb908b70112dd44bf2d1d578912cd297afbd8d6e3f4d8b6c91ff04cdbc996e7f0f69bf4fb7a67c8bf4f7e876512cca45f5fbeaf6b74dbfb5b4efba7dbbf4aedbb74befba7dbbf4aedbb74befba7dbbf4aedbb74b4bdd7efa1bb77f5a5ad4bfeaf3bb6edfeef3b774bb6896e91bd23743fabe72beccfde5dd1ff3be74c7b724faefa0db4f5bf875fd7ecfd54153dfaee5d39cafbd7f4babbf36e1ff79f8dca25ed3d8f3d67e69a32fe9e24b0dbcf6fdcbb57d69a72fcbf0bafcd0f0affa3cd8edc7b67caedd41de8faf2fe77b4927afe9f6a5be79adde8ff4651daf7dfa7d743bc8fd759d3ccff19addbed4b6d7b5f7b2e63fed854fafbc64b71ff5fe72cdbfde6ebfdedacf75fb65ee6fd9edd735f96774fb656dbfab6e5f1e535fced62fb5f0755dbcaeb5d7bde9d7b4f9b994ff3d7cc220fb4b7ef0256dfcd85cf66994f665993f12837d6d06fb2cb2fb0de2844fb5f47a7add1fffcee9d7fb846f4af8cd15c4ef9a7e07ddfe3a19fea99fdf75fbaedbff8e9f759cf08be7d37f6a7ab7dbb7b5db5f2dc33ff5f3bb6effb9ba5db4cbf4ebf5f00fd56d0d0dff3e3af999bafd857369fbcae77f44fa7576fba5adc2867fbdbdfd4cbbfd15f5bee263db9f55feeff0f917e9f6351dbeebf62f7efedad8ff27c50c7fb76ee165bfee877fb54e7ea66effc6b9f3fb6281f69f1133fc9d76fb23e3fd9f1033fc8dba7d719e5a74afe7ff565ffceefaffba6ea9e53a3dfffc3de975dd7e99f3b512e07bbfbfb69fa1135d5efb2cfd68399fc8a5fded57a5d66d7cf6f97bea1a4ba83fafef7be57ca6e3f6e3baf8637a9eff477afd1ba9fd8ba57d22e39ff5099fb6f26bfd38e6ff4bfee43bfcc33389bee6f33ff6cb4bbdf552feef29f3253bffe79fbfd5adff320ef9d158e4cb3bda6f95a37d42fb720ffef3d25ff5c9dfb6f3e79f5fb2dbcf4b58f4cbf44db9fbefc9f73ccf97f95ffae6f9fbe7757c5baa9fabdb1ffbfceffff73ffff5ff0114463fbb</data>
+ </image>
+ <image name="image7">
+ <data format="XPM.GZ" length="41898">789ced9c576fe5cad29eefcfaf181cde1d18fc163309c317ca396719bee8c8a89c65f8bfbb596f91a33c33de833ddab0541b4b7a169b9ddeeaea40eef9afff7c3bdc5cfbf69ffffad7d5b5b8aed5375589cb6fffd13727270ffff37ffd8ffffdaf7f0745fa2d9b7ccbf3e85bf8effff6af7fdbe09bfae64de8a7e73606075192f6dc4c81c3b00047cc89d43deb0770ae2cf89ed9584be9ef88036731f1397338a1fcba92389c441341d7af99932020de1899eadb1c134703b776e488ae9f30a701e55fee13c7512a29bf7a8f380b2611d5af6cc1696472baff8c380f8298eeafd78945902654bff6885806a9407b4ae62c51d49e25621de85412a3ff4c2814717b416c83b040ff1cf61c04936482f618e270e46a646a5fbd0d0e6566e87eca2f8886ebdd3d3854027a9e30eb9cb87b0047814aa8fd197324d1be47e278c8aff1c1a1cd0b2a7f1f9c0606faac122743faf60e1c5894d77ae05008e43f078e829cfaa35c0727ca42af109c468afaa7bb64961afaef10a79394db8bfaa6919594be42f959240bd47f97380f8a80fcb325fd8322b11a7a907f05220c43d2bfbb634e72f807d20bd7a1f07ff4af4c8ca6f6b739b10a9390f2ab2438ca73f2876a656049fd5d1f81e34252ffd4e81f9508f8679512eb200ba9bddd34380e25f95b750d4e7393d1fde87f1b1421e5df9e8293d4d2f596c65b38090df4ae4a70a214e9a1713de88dae2f81931ce3a15e240e5d0b49ffee0c1c1621fc7d87d9c6180f13703ad1f0179fd948e2aa268ea2a420d677e082e3453d431c872224bdba865986e4ef55088ec218feb3cbccfdd70ae2c4f933e9d5ee30c731d5b7a6f116a689c47854a46f98f546d74fc0519aa03f72701269e487fbf33085ff56017301ffa91f984584faa33e799427a4a746ff15bd517edbcc025c297034c9a83f358d6f77d5195d27ff71bd21e16f75c7acc19d01472e80d3f5eb91a9fe4a13abde28bdc76c98291ef6b9a13e669b59b31e5bcc26c4f8b807cb2c267fb673601505f017dc6f5d09e8df59662e4fed325bce0ffd67ddf482f148fe194ddc752a5fac80639d537fd454be6b9d0b813dcbf991e10f3e7306ff280fc0e94452fe96fc2b0a7ba3fa50fb22faa1f67f67d2c35c30c7604bf1b927a4576a64ba5e22ff383105d5bf4a88d328427beb73e618f5357bcc29f4aa1788b3217f11303ba3fc3d709214747fb7cc2ce1af92f488f2dea8bec82f1719c6bbda242e2211416fd4c711f326b3332a8ffc3992499a438f65e6a280bf411fe5ee477f5d333ba3f4d0432512eb8992afcb04f14350fc884c6f743f8d97c8c613f89726ff8c27fd3754ff0d70ccf3b91203f3f5142c0203ff25ff8f83300f501f1aef71d81b959780d309e253f3c86c305f343538cf25e2c91571140acc2f86b937f2bf35705e60bd549e83659e60bc50ffc5f443f5a1f54d9cf446eddd624ec1ca1b19fde783d318fea5683eed53e3ba2d9939bddd01a74141fe50a27fd22cc67c6069bcc6599a627dd2a27e5931ac176ec1b288317f207dde1b5d477fe63285ff288a4771d11be5bf074eb382f4ddba066729e6573d01e74253f982e25b2c7aa3fe9e036713d4b7427a198521fced12dc1be98dfba55bbed17851d057ca04ebd516fdaba218f3a77c00f746f75f80b300e5957760e924a4f2501fb7da13585f22bd2e328df189fa6819c4883f67cc11f42caf9813cc0f1eea637b232ec0a911d0fb142c7482fb6f7a4e5c34c37c53d3f8708be114f15630f746edb1e0cc0d684abf092e8442ffc46099a37f3af2af248c72cc6ff21edc1be9d58c8c7849e33189c6eb01d865477ab7a84f546885f842f19fdc9df4abd19e38cb04f57f49fd992432e27884eb696fc45323633dd081650a7ff1d0beac376acf2dd82d1031fe51ffbc37caef71646abfb5cc4582f54c0e1619e62785fe29c6fb4f47a6f4f28e99ef1734ff24a237aaef0e38cd05c6db0c58088df148f12691bd51fcf1c0ae7cc4771a6f89ca783f6135586af48f55601df37e8ed6a789160af1cc835ea637aaff09b305d7a89f292cf492e48ffd555c173b2323feae31f3fdf27664b46f012cacc6fc41edeb97f329c543333d32f9b7dd026706f377b70f16135e2f52ffa6419c60beeca8ffd2308f05d61fc83f8a33ccef4d0b16b9267ff5a8bf283c92ffc99b91a97c619913be9e8f8cf187fce36282fd89a2f5789f1ae9c5f6c888e79bcc9c9fb73e32d6e715d8b91ff6a3a760a717d6cb343fb8e85c603c09a4cf7aa3ebb43e4e45a1f83ac55f371c448a78bd3132e9af6b6689eb9e1a19f113e5abd8f2f843f9ca19e5ef91dea9ee8df4807ec6450cf817ca37bdf5ecd3fa2cb5bd91bed7e05cf2fe60195c08435c1e82853294dea7789b4d7aa3fa1c8e0c3d9798838cfcc5866099a33d82fca9bf8afb3d3932d6fb1958048aeaab299ed0f600eb83162c35e2b74ffe9745b946fd3dd23f8b7b237fa1f52e851ff813addf492ef2576f91d9fd90ff44609521fe0af2cf2c1bae97349f677916607fad2b66beeed1fa272b7a23ff41fb8588395e50bccc646f547fd22753bd51fa189c5bcc073e8d77379939a3faad301bb0207fe9095c6e830b03fd34da6b5cbcc2785d03bbed1cf5a78ffeb1bd517ca0789c4f428df31cbb04ee8dee27ffcd83f1fa3138513cbf5a701a62fe968fe0de48df5bb01b3fa80ff20f6484fa088a2f6eb273468ceb6191e27cc4a7f14fcb692a5f4760c1e3d1a3f8e616437c5d2d8f4cfed01d30c7e096c6439e8612edf13c706f947f3a32d62b92d96aea8f86f4ceb350e17e85eb596fd4fe6366b722a1fa27e042298c8f2bb098406f49e337a71f2a7f6560ac177d5c2f7aa3f4d7cc02dc1e335bc42b41f1aebf8aeb6a6964ea4f99310bb0991919eb0594e7f6af018d1f83fe71cb13ec37e429b8c8b1df97fbcc42221e5f82dd0699f2572158694bfe61d1ff6eb784f3bb1af55143791edaaf7aa3fe300317d89fef8d8cfebd07171aeb7d0ff5572244ff6a9a5f73d31bf54f3e32f9a35e66b6c84f517cc86d6f94ffd4c005e2dfddc8d47e01fddd55be2e9843f49786ff5b19f0fc47ed2f2643fef20adc7f43e56503233f75c71c61bf2137c022c2f95b4bfa1641e4061cd5e71eec963fc85f33f3fa5fd178a1e310ac17a747c67a4a32c705e62f5a6fb9d205d6afd5015805d0b731ccc6405f1a9fb4fdc0f914ca4f2281fa4905ee8dcaf39933ace71b8aaf45169900e5cf810b85f35f2f070bc1eb231aaf343c50ff6064cc9fe49f45ff43f56b69be28441c0458bfa2fe222b78fd44fe5bc8dea8bf6e47c6fc74089629e28fa4f572617aa3eb315872fc6d69bd5158171f114f1fc17a82fdb1203d45d01bf52fe52f4217c0301f576029b07eb314bf45e4ea8bf3ea7b70bf00a1fca83cdabea1bf0e99f93cc6a4cc7c3ee9476019a03f35cd77b45c86ff5e8d8cf135039631ca53d7cc02eb7b49f14ef4cb1fc41b3132eebf60d6881fdd2e58a7586fd4b45f13599662bfe559706f945f3b32e52fee46861eb4dfa7f0067f40fb5c40637f4179b90a0dce77492fe11c0afb095b809d517d8c62e6f34eb9035691c17e88fcc76d1f42f49710ccc3f93bfa43c854915e720fecee477a9a9f85ec8df4c075292389f3728a0742a502eb1f013d556f94df365865389f16284ff746f95d82ddf61ce9b7c0437a83fe35f92446fa25706fa43f8d17617b05498f96d9a27f443130f4148b6039c1f9b97fc59ca03d7213ac0a9c77b7d0c7ead0e2bc81d6c77212f379942ac1bdd1758ad732c8438c576f0edc1bd5777f60f8b777c42c30ff56115817d0df527be87817e7010723633ccc320fcf6b76c1c3fd0ae545bd517e972323dec991717ef13030fcc1a7f148c727c8ef9e592bcacfdf67360ae72d0bcc16f3494df3894c5c7f203ea0fe4921b1def135b837ca3f1f19ebf38b91c93ffc6b6681f945ac326baccf7d1affb45d21bdfd0b66c1ed813eb4e0a5fe3c1b99eeb73760377f603c207dde1ba57f60968af42ed17fb99ae0f98ff09803b04feb050ad738ef5a1d99dae3410f375e31fe15f42e7462711e48e355baed29fcc967ee8dae436fa1129c2f598adf6ef36479bd8af6d10fddbf3d30f7c704ac26d0cf8f99436ecf037382f32e89f6a8dec8df507fa533ecbf7d94af25af77543530fbc7fdc8183ff3cc86eb03ff70e35f416f5acf49e3ae43cf63b0db7062bc1ae61cf1de43fbace4e77f3ec69775d7d17f87cc05b8e4ebdaa0bf15ddef7a63027dbddd91118f0e46c6f81b98fbbf3e051b89e76d8aca53416f349f48b051b85e26609ba0ff0cc55b151601ce8714f2a70734a46f3c32f4bc614ed87f1e9815ef070a6663719e43e34b4522c5fe479c837ba3f6d891b13e996716d82fea8115ef873d668df27cf26f3a2e85de7a649c27742343df6664e8b3cb9ca07d3a614ed1bf26662ee09f5eca2c909f77cb6cf8f9f002d83918d6b7343fbadc13c45f396136885782e63345071ad49f73cc39cfcf9699e35b43e341656184f725ea2d7021709e2fe00fb4a1a6fc8a91b11eed46c67c9131e7b86e6699ad46fbeec03ad0581fd17c46db11ecc7d60746ffc8a391b19e2e98d9ffbd7bb0cb0ffb4fd4c7ad46f9fc76092c27bcff407e456f74ff315847d0a712cc1c0fd405d82416e9693d4dcb03ecef2603c3bf54c0ac511f8bf60a3d41fbab73e610d79b65e6c8426ff4875b1ea0bc8ad62b4a06f104fb2b66c5cf7b4d3732ce9fce07467dbc2bb08ed13ec5d74d8af54089f1da3f2fc57950052ef8bc57c09fe987f23b67667ff3307e954eb13fae507f1d0af89382bfe9de886f06c6fe4696609d81ab336665f1bc09f1c004319ebf96e85f13a6c85f84e0dec83fa09fd139ef8f919f711b50ac6731fe6c6f94fe11ecfa07fb619a0f9c5a13c4037334329e2f5e8d8cfe98654ef87cf291b9e0f7316ec186e36345fda1836032c1f9fd1cb3c5f3367b089621ceeff412d8e58ff556cc2c517e4bf1498721f74f75c59c4f108f97c1a248319f57e0dea8ff3be618e7b3669139c5feca0b99797fe45d3373f90dea171a1e2f96f6f3daadbf70be2817c0bd51f9e7cc5c5e75cf5cc0df35f9a38e65c4e729a84fdc1bdd1f8c8ce701b7ccb9c1fb3935d82438af5334befbde831ef67464ec672a66cded4d980d58717a371f424f8ad73a0dec04e7c3cce104cfbfed0cb808f9f9fd01d8edbfd0ff0fcc0aeb5bc1e9b541fdbd88d9822dfccfedbe528cb712acf9799c5c1d18e935fadb11ceffec2233bfefd15c32a77c1ebd05b621cfdfc83f2f223cbfaf0bb0e0e74d12f5cd7b233e1c18e5e99c59a2bd5a824dc0f5a1f95617458cfed1e8dfa237ea6f8c9fc28498ef5a8c2f210a3c5f6a14b3c4f99641fddcfe0fe7f506fe401b34ca7f6a60e427d03fc2f0796d47e7035a8609ce43da15b09b01b05e437fd08290ea970d8cfc4cc86cc012fe2987fa9b8639e6fb4f980dfca9a378ae55c0f1b2855e6e02e0fd17eea7004af763bcaae1fe1afeab831cef0fd6bb6025f03e8f457be8877873603e1f46fcd1fd0333f2879c59f278867e7d3cc5f9e02eb3c1f8b1066c127efe35cf9cf2fe17fe690bc1ef9fac8335cfefde32b3c578f36f0786ffd88b9131de276033c4a78179bf6d693f6726ae81587fed807ba3f48f23633c9e3007b8bf3d604e719e2a669933eca7f52233bf4fd696609b237d49f1d804ae7ff0fc609ed9e2fc4e207d60f87d43ad4746bc5c1b19ebb59a390777283f9412cf63440a1efcd96f47c679cbc9c888a73e736e711e78c35ce0ba56cc02dcec8187f6f9a81fbdd042dc8d8cfaae8f8ce76553cc09eaa306e6fc2b8acf6e74e4387f6837990b9c17988c99df6fb40fe0be4729bf1de698cf0b9a91d1fe7c64f41ff48cfb0776a4cfdcc8580fa0fe891b6f38cfab992de29d8ffe4986f1a26746c6fee27a648c6ff46fe2f2477c427de90122e5f79d115fcf4686bfdd8c8cf8518f0c7f53ccec9f3266e6fe950db342fa16fd9fda02f5f1291ef6a307e5fb6723e3bc7b8a59e33cb5e5ebce1f70fe3a612e78ff8cfae5c3f8b0d9c8d82fdc3317fc3c2d1b19fbab8099cb6b307e5c69d0abf246c6fbc6b4de7177a73cbf1d8d8cf658662ecf262363fef79879bdd9c0bf8bfe813ef56fc1cce5f914efe9f80efe8bfe1543fb9b2d66bebfa17866fa0300f88f3732f49c0c8cfdbb18d2737bd534d84e70bd9c61b6d80f4b5a7fd1f217fd9b0eccf9e17e4718efe286d98d68ba1fedd136e078b0c92cb9fd3133d7a73e1819f1177ad30ff5871e98fb03fd6d46fd8a9191ffe6c8488ffeb42ee2e0fd5fd4afbf8cf7a3af4646f934fff5bdc3fdb33832da1731c716f1f29a39c17ea09a62b638cfa83647467d28beb9c5393f6ff4f6c0e3fd5bcc437af2371b6a7ebfc9db075bde6fd50133ffff05e50233df6f492f1b2985e7df1deae3e229e67335031ee257f3c0ccf777140f6c6c22c4cffa9299cf27ed1ad819e5dfec336bf8536d992dfcbb3c1e98c7c7dcc8a82fcd2736d1930cfbe1959171fe89fea71766a83f4e980bac5faa1b665e6f3401b3c5f8a8e607867ffab41ea1d72db01ed81819e79ba7ccc37cfcc82c381eaf0eccef835d336b7eff86fccf6686cf67db8259e2fcab9905f78a53fd76982de255353330ea5b5d8c8cf5ecd5c868dfc3c898cf907f6e793fd44c334bf8afbf3532ca3b61e6fa57437a5e3f558f2363bedb1898db4bf1c6951662ffdcde30b31ee28a79f0d725662eaf499907ffc378142e3fc4cb4d66bebf6a990d3f8fc2f893ce63f0bcea64649c2f8ed7797cce310bf6bf756609bdabfd91d19e81793f554703e37a393b32f2a3f98d8e0730df2966cdffff41c0cc7ad66664c4377f64f40feaa79dffe1fda7ed91b11e99679688dfd502b3e5eb23b35e145fad19fabf9c66b6588f55eb03c35f9a7c64e81f8d8cf9fd7264e44ff3918309a75f650ee08fdd0a33ef172bc31cf17ae09a39e6f1b03d30ea532be6217eae8e0cff59671ed667cb23a3bc59663e6fa813e61cfbc772a87f0e7faf8f074679dddac8c8ef92b9603dcb91f1fc7a68af407f55bb2343af8d91113fe5c8d03f63e6f1540de52b6e7f3732faeb7464b44f306b945f8723637d3e3332ce23e29151fe01b3817efe505fd67bebfacb3e839136de977d06fbd2e2f3d897169fc7beb4f83cf6b769217cf9b7b5ea1f5ad627d142f9da37eef36772b27ee957ce4abffec5b21abff53bb613fff48332cefc73ffc2bff4affc6bffc6bf7565e2fb3bffde7ff84159efddfbc3b23ed0e2d195f32bbd3de54f7f70f57d2d943fe3cffa73fefc0f6bedf90bfea2bfe46cd95fa1dfabfeda2f94b5ee6fb06dfa5bfef6bba5ecf8bbfe9ebfef1ff887fe917fec4ffcc00fe94ae4c77ef26159efdffbc3b2ded5a25762d94f7f5a89cc2991fbc5af6ad1ffe7094f7acad39ef1ecbbbe0ed5527fc62bdd2d95b3da6b7ce1b56e7cfc6c59dda08477e29d7a67ef95e39d7b17dea577e55d7b37dead77e7dd7b0fdea3fb7eca9bf666bcd98fca7aefde9f29eb1d2d58096fcef9de4f28e1cdfbd3de825f788bde7be9dfeb9f656fc55bf5d6bc756fc3dbf4b63cf16ea45a70f5d9f69553201ccc6bbc1d57c39777bc57d6eea8c49eb7ef1dbcdb9a43efc83bf6265ee0855ee4c55ee2a55ee6becfbd4238f93fd4e29d7b7fa6ac37b578a28410de0f238790fd98e85f3bf264ffb2d0af68e1ee2eddc0a8442d1ad18a4e9c78ef444671ea6ba75ce34644e3229333fc2dcec4f98be8f64e59e2425c8a2bef445c8b1b712beede6dcfbd78108f624a4c8b19312be6c4bc58108beefb25b12c56c4ea4765bd77efcf94f586164f9558f3ac58171b1f2b2136fbe824b4d8f294d8163ba2f9192dbc52ec8a3deac535b12f0ec4a13812c76222027ff58dfbadab4de8975e2d22af7671a9742af4ff884129629188f4e3b2442672a744d18f895e09e9cbfe1d5c29d51b118ede66955696b292b598928d17c846b6eefb4e9ec85379f65159efddfb9e3d4dff4a8b674ac8f35e0979212fdfcdeb4a5e43893ee6cb1b792befe4bd7c7895f2b5af66f2514e79cbf4b792d372c60fe5ac9c93f39e79a3a4d26be5825c74b62422b90425e48c5c762bb025b9f851597245aeca35b92e37e4a6dc92db7247eeca3db92f0fe4a13c72fef0b24dc7fea19c884719505ff6efc9c73279a34e6f95f52bf7be48ff428b779490a9f3a0b795c8bc054427a7442e0be5f74a2837407ea48592be1147cf63bd37a794d2ea2d2d2a5f8b3db1db1fd8fb9ec03fec11bb5cb5af55e9f91f95a52a553b6b54ab3a75a24ed5993a5717ea525da96b75a36e5f96a5eed4bd7af06ed4a39a52d36a46cdaa3935ff735afcd2bd2fd2bfd06250c21b9470fd4d4aa88537f259544b6a59ad609e50ab6a4d34a4c4bada509b6aeb075a2c08edcfa9672b4bb5a376d59e7ae5a9bd166a5f1df8ab225387eaa85782d6c2bdfd588b6335715a042a5411bd3d0d4b55e6c6c5a1ca5fb5ab7002f7ef7549adfafeec5f68d2efcd9a2fcbfa957b5fa47f15a34809e7a15697fd98e8ff7e5b89c174e5825eedadcb5bd1e8a65742bf151f5fc7f00ddd794a9ff8a13e958f181ffa549fe9737df1c6fda58b44cbbd89532831aab1ec2fe9cb8fcad257fa5adfe85b7da7ef9fd8837e74df4ee957bb223da367f59c9ed70b7ad10bf4925ed62b7a55afe9f51fb7eb97ee7d91febdfdc58fe689efe694d8d09bc38cadb774ab367f460bbf72fb09b79275738dd0dba2d23beebb05550a2157deb8bf766bd715678bbd126e253bc36ab8ef44a2773fec9f3dbdefec401fea237ddcbf85ac437a7b36a1ef5feda174a6735d18dff4efa848a38cee5fc530a5a9ccebddcfab7699c6b4ce7ee65ed88ee950d6bb5af03cf1632dfae8644ecca9262dcc9939376ff9f51beb4ca9b0923597e6ca5c9b1bf32a723f2bc7ad695d445b10919b33b67bc3dff4adfaa82c7367eecd837934532f6cda7d7f6f665e966466cd9c99370b665c119825b36c56ccaa59332ffdfb8d76f55a3ca1f7ef7d61ef69f1d18cfddcf4a6b7a17cb381b593d9345be6add385b7eabce37966573ef42b59b3a776c5b1fc2016ba31b3afb69d22958b526c6e16d97631b5fc787f61f6d58d393087748a359a3932c766e2ae04afea159ac8f46f858f9ed8bfe1660aebdbfe6d04f96159ed77fbe1bdceac62e3776aded4e2dd19fba5a9356bfb19dbd24add5666fbcdb9f7edfd572dd66dad849cb38dbe30dbfa8dd5fe7713a9daf71fddae6434ffd1b66e2dfc72f4bfdc0befd8ce9ed8d3f1348acc9ed9737b612fdd6aec65ff5cd96b7b636fed9dbd1fbf7bb08f76ca4edb19fbe119c86b2d3eb8b7bf3667e7c916ecbbf3c5d319db2e3db51fabf3a6bd7f3668edb25266d39fb66fcd13cf4d897355fa2b14a156bc7e15f6d669edeb18be6357edda3325d6ed86dd74f3fe1b678b76cb6edb1dbb6bf7cc93533dbb6f0feca13db2c73f6a1774b09367f7064fedc99570b4c9cf9d99ff65253e3ca7359736123f7b0a69452a17fb3ff4a59bb1d59b67bb6f9465639be06db5ded4c4f66fce6eda37cf32fb4d7d294c58ca523dfb5e97a6b465f9a3b29ecf17c3bd6f29f1dc7ef6f9c55f54e21ffb7ce77796f5b112bff22ce92f29f165641f29f1f5bcfb33d997169fc7beb4f83cf6a5c5e7b12f2d3e8ffd752dcaaaacbfec77d85fd5829468beec77d85fd6c229d19f29946dd99527e56979569e9717e56579555e9737e56d7957debbbfae9f9f057dd95bf6dbb478281fdde754395dce94b3e55c395f2e948be552b95cae94abe5da5fade7ff0ff6dbb4582f379c6d965be576b953ee967be57e79501e9647e5713929833fddce5f37fbb7d7f9b769119651199749999659999745e5575e252a59a94a57a6b27fba677fddfeb95a54a58b4e1b5555d555534e576dd55527d56975569d5717d56575f5a77bf6d7ed4f6a319c5b7d7c7ef5ae16d7d54d755bdd55f7d543f5584d55d3d54c355bcd393de6ab856af1ef6be1ef2ae13368e1bdfffef5475a2c390d96ab956ab55aabd6ab8d6ab3daaab6cb59f7f74eb55bedfd4c0babfdcfd4877f468beac0f7aa431b5447d5d1a049755c4daaa00aab083a5571955469f5ea2ddd518bbc2a6abff6aa855ad4d28d88d3eab456b5ae4d6ddd36a64269756d03b5ab76dd5f4dddd65d7d529fa2ddf5597d5e5f3cad597d595fd5d7f50dfae479fa17f42c25a7bfadefeafbfaa17e7c92e3543d5dcfd4b3f5dc1be5cfd70bf562bd542fd72bf56abdf6a7b4a8d75fc7a87aa3de749f5bf536beab771cedd6f424bb57eca516f57e7d501fd647f5713da9d6eba09a2da33aaca33a76ea24753a9437b4b0ceeadc7d168d8f6f1bafffad76bfd7ac118d749f8afbf659fae7f43c253e1bdd18f7699bf2498e5553d3efe68df25bf77dd79c34a7f4fbec4f69d19cbfd6a2b9682edde755738def9a1b47b7cdab77b3072d9afbe6a1796ca69ae966a699753cd7cc370bcd62b3d42c570bcdca4b2d9ad5c6f95eb3def0b7cde6cb9ab9145bee739bfbf659fa57f42425a7efdf4074d6ec3ecb71efc9dfcfcb77f1b139187ebb76fe212dd0fb2fb438242d8e9ae38fe7f5518b4913346113357193346993357953b47eebb5a295ad6af54b2d5a437db1dddaa7dfbeafc5f3f4cfe92d2d5ad396af72dcf9aec5dbe53ffdfd27b568abb6fededf6dd3b6eeb36b4f7e4e8bd68dedf6ac3d6f2fdacbf64a5cb6d7d5697bd3deb677ed7d39dd3e8c7df0d84ed1efe976c67dceb673ef69d1ceb70bee7391fbf659fa17f42c25a75f6a97e9f7ca931c575bdafff731eaedf23f8d16ebedc6f7b9bbdd6cb7daed76a7dd7dadc55bf345bb57adb7fbed417bd81eb5c7eda40ddab03e68a3366e13a7c5385fb4599bf7b3425b747ee775a2934ffbe0e97cd1a94e77a6b31df9f7f3f4cfe9794ae4d5555ddd355ddb75dff3ed4ebad3eeac3bef2ede2bffcf6bf12b6bd8f7c64577d95d75d7ce6ebadbeeaebbef1ebac76eaa9bee663a377b7473bf5eb36ebe73dede2d764bbf2fe5afd83f588be56ea59c7ed54babd569b7d6ad77ff0f35eb36bbad6ebbdbe9767f5fca5fb17fae16fdb9f8fbd6edfdd57afefdf6cfd5e2cbfebafd8ee77addfe97fd0efb7adefd79eceb3d90cf635f5a7c1efbd2e2f318fd5b98075ff6198cc685fcb2cf60f83752bfec33d897169fc7beb4f83cf6a5c5e7b12f2d3e8f7d69f179ec4b8bcf635f5a7c1efbd2e2f3d897169fc7beb4f83cf6a5c5e7b12f2d3e8f7d69f179ec4b8bcf63fffe3ffffd5fff1797676269</data>
+ </image>
+ <image name="image8">
+ <data format="XPM.GZ" length="59764">789ced9c59731b3bd2a6effb579ce8baeb98a88f64ed313117d66a6b5f2dd9137381b5766a5fbf98ff3ea87cb32852a27ce463e958dda3461c910f0b052432138904aadcfff5af3f8e7736fff8d77ffde3e2525c96ea0f5588f33ffea5afdaf6ee7fff9ffff5dffff8e7304bff180e32f7df20f963f4cffff18f7ffaf91fea0f6f40ffeb78bc0d4e99eb457096317f9ff090f870c2d45efb65c2315d5f6016dcfe0ed85ab0dc231e7685b89a70d87171c63c427b524f38e938ff34e194ae1f3207e0f12ab897bfbd661683ace32698b0a2ebdf9925fa5717c423d71ed51783094bea6f89391c6892d74cd8907c9f276ca9fe0a7334a4f116682fe8c7af4a66be2ec30907c439733c24f91a019e8c2f605643eabff9daf388ae7bb83f1ca44392a71e8227f60d9905c6efe37a344847b0ef2d38d301c9d72e309b00d7eb0947343e491c0fd490f4d3421ff144de23661b903d05fa4f066604de003b030be2cb9e03e87779c2341e75da7348f209c13c0c497f63f85732e9ff84d98624af87fe52773fd5177bcca390fa1fc3be69efcf6d0a76eaa2ebcdf28469bc0afe9b398b917ec422b309c83f15ec93f5eddbdd09933fe6d7cc01dad3fe8469bc1ec62326ed633e88611491fdf2c184697c62cc1c47e4cff9c18431be35b01831973dc7345e714c2cfbfed41d7898a0fdc263ce707f13819dbe102fd09f1443ccdf56310711cda7b1ed39a6ebcdea84313fcf98c390ec2faf88552f8fc5fc55c32ca6f157865940fe6a8959c6645fef8059415f2df4af7a7973b0763306e3457d3d9411faf77b46fb39e6b799d457cc06f1a0407c32438bf13488b7a6ef4fc15fad0b6f90b7640e628a7f45c01c46c4f67cc2d017fcd78a3821fdcba46317ef23d6cf17f0288ec8ffda02ece21df5df5c814592229e91ff0f87fdfdf21e3c4a63ba5e16ccbdbdbf834596923d738a0f4317ef06a4ef1af78fba42ed6d834729c6ab96994542fa1187cc32a1fec61b602112f8cb276615a33d8a3fc3c0e91ff13266eefbbf037785fa83bcc148a17d71c6ac139a5fcd08ecf443ed8fcfc1426688cf349f8661df7e71c91c83f38859239eb59be0be3d058edc0c24fdf9186f148ca03f1d310729e6a3020bf69f02f68a87c990ea37186f2cb4a0fe9b1db01c44587f28deb9da29eab73eb897a7916037a1c91e1af64bbb42f3e52bd81994ea1bc9ac50bf803ed340a4680ffe964a1742a83d8a7fc3ac2bc415781407341eff9ad926a42f1ffe918543d8a7c2f8c5c8790cb50f7b0a1926d49e827f49a77fac5f904fbafa88ef97cc29af1718bf0c838ce6670bff933290247fd910abbe3def163c4cb01e2acdec0ac903fd2a196774bd807cda45449aafda809dc5a83f7bc8dcb7d75fd7582fe56770182698ff47cc99a0fa1efa372e5c907c26048f12ac970af29b304968fc35ee3799827f0a8a27433b8a900fe8217312903eab0366097d69f8ab0d95407e057d5999a4f0b7963913e45f15ad172e5d4a111fbdefe0d0e27a4dfaa47040f3495f32b3fc65c29c826dd333af9f23702811ef2ad27f676df887bfde73807c2e064709fcb1de04f7faa8287e8c02e7efa47fbf61ce90bf79a760d73fdd9f6be62ca0f178213818623dd707e0d024646f41f36714ba0c00feb80a76fe4ffeae77c04180fb3d058e8440be43fa75a34b307eff8c59c05e5a326be43f0dc613492b497e017dc4a3e190fa2fd79863e46f66c89c80f5123888b01ed42958b92597fc13fd25bd7dbc803943bcf3169815f2457dcaccf9a3867f2481c0fa95c3fe491c48e41314df5deb23c86b0be66884f974c59c607ed715730afbeb55e66c44fa294e278c787b3261b29fbfcc2c707f1930b3bc793161ec9f56c08146fee2419f699c40fe06fe9d661af3b3e6f6d548116b9adf9db646e47fe5f184d17fca9c62bcf28899c763f30963beed310bb03d65963c3e8c278b4c06ff867fb9d18e902f1d3167988ff29859b0bed69825b8e6eb2a52c8d7311fa5cb3848fe6a1fecda43fc3c611690bf3a659660ff76c258ffbe809d3b20dfbe07bbfeb0be427ed5b7e79f322bb0b73261ecd7d484295e7b882fda6dbf902f63be6b57907fe07e9d8412fb0fd8dfb8eb90cf82039780d2781ae620207b899259225fafa10fa77d9eff943f74778f906fa460a514ec03760916f683de2e786447d84f7d050bde9f96a4af60e46630dabf60b6988fb904bb42ed998899f3e57a05aca20cf6467b818b50580f8f9863f8ab1930a7685f97cc16fe3b86bcf43f92770bac8c46fca0f520085d38217d95f7cc166c2db89f1f6d0bce0cf4578fc072087db7e83f5456d3f87c5a7f83c86d78b11e537c0d6297d1a3fd03702731dd6fc08af3018df125a318eba33de999d7ab156685f9e9dd80dd70b1de09b04bb790af2c825dfbe88ffc214875a0697c3ec5bb201bc67c5e00fb09b77fc0790558ea44233e60fccaaddf586f4e9863e457e34bb06b9fec6b293e04dae917f3751becf211ec37e16f3a1b2acc5fdacf052e9f40fb793e61c43bc86b7bae03b096982f5ed67138e8fb2b97c0dd0914b547f33574fb07f46feec0d110fa516be03494247f79c11c4b9c2f6d81b5d4d87f7c231e096ebfa0f91ebadd32e2b3be064722c3fa47eb53e80440bcb243709c427e4df60b23e7cfd4bf647616c7fe07e38b228df9e2ed815317e149fe6db0182af2a73a066ba569bc35c58b30ee0ad983d6ab30713b2e92a7380107e988eef7c8de61eae205f6331adc151a7f09d646239f853e32b7df467e0079848b08f007f2ef50ba1986f864c05da1f185e05864586fcf268cf566052c06185f05fda858c37efa1e2cac82bfa33f65869a787ccb1c19ecc7281e877ac8f1acb6e0aed0f817c131af5f793961c4cf43703f5e0fe3d5d26dc0e8fa0dd8f587fd30ee372efd82ff637c2619a0bd8afc3db45d217d409f360eb13f14fbe02c86bd6bcab7a2415768fc39d8a5b3c4be06a76e0523fbde8085403c54b49e3aefcf70bd247db9742f12642f7102cea482bf507c8e822cc57a28ae9905ee1f6f81c56880fd00f95714660af7ab45668df53b27ff8aa2cc2acca70adcebd352be15c5233ecfd447e020e3f8b7ccac793d6cc1492290bf2c80b300f98ff9caac60ffbc67eebfbc9e30f6b797e05e9e82d6af28e9e5a9a1efa42ba40f5aef22b75fc5f98bf90cce86581fca53b09b9f64ffb160667df914af22272ee79317e07080f99fd73d231fcc295e75d105f1b64ec0bdbcad64e6f3e392e241245d00c2f9500ace52dc2f7ad6b067bd0b365146e333147f5d3697699c4f9f335b456cc8ff232b4686f43f86fdac56186f4ed7e3411663fd29489e782822cc57ab7a36385fff06960af573da3fbbc530e5f1dc312b9ca75763b08b30c847afc12286bf8f979815ce830a9aefce9d22c82737c1ce3ec8ffc9dfe2d0edc7e8ba427bd1c4bea4ef3876db25e483e46f71e2b667341e1ff2b8dd3fef774ec18941bcb72b6091189c070ec15dc248d7313e2124f4d9427e61a444fe05f9556635c9ab6ec082f31149e757b176eb1dceff697ec6c6b587f57d8d59c59097d697d83afb637edd31f7f3c103cb10f9aa217b24ce3bf97c651f1c0eb13edb11d8cd7fc84bfbc164980d25f993fd0aeed7abf2002c8706f63803ab08fe26497f89db9e41ff36036791a4fe8a55b0b0f01f9fe657124411ceefed163849114f0de473e104f9924ff976e256279c3f891c1c29ac97e6189c64b8bfa27c92a63ff65f062c87438c4f3287184fb3cf1c63bfafc8de890befc8f7fc1a1cf1f3830ae3894588f9218e98ad26799a05b00ca07f95f6ccf38be26192f6eba59732b3bf979b601943be9ae667928988fd1bf533991892d762fc99121ae745140f12e1ec0dfb62fcc2b5877c85d68f448e52ccb79cd6cbc4ed96c06a855980c515b3e4f3d2236605f62fc0e108fee56f80c508fe59c01fb4ccd07fee8195467e5241df26e1f391760fac2370c3d78de57c17f258270fce636fc0c2e07ca080beace2fc674cf64d27cf37fd1bb09bffc82717c12e61417e9830271aeb21f5ef94a579fc35381a207f2ad1fe503a09693cf73d5be4ff5c5f0f90ef285aaf53b7ff82bc82f29fd46d1798d7c06e3dc1f9e5395824ec6f776099c29fac60e6fe35d93f0d5d7e077f0dc17288fcb8dc02ab01e4f3236685f13739582b89fc85d683340a06904faf3373fe680ec152c0be2603f7ed97903f0e429c7fca55b06b80f45bed805dfe83fd2838918afde51bb341bcb1cb60e50202c98bfe1213c1de25e5572efb1e72ffd047aadd068ac60b7d64bdfef363e608f2d5122c2383e79b189f103c1fac075621f70f7d0a3b80fcf506f308f1ced27c4fa5647f2a7db0939fe4b13d737bf69e3902b7341f53255c8027fd8c990db7b70776cb05f24f9adfa91681c47a70009616fe512c80558afd47b9cc2c113f14c663dc7c267f692b703f7e73c66c30de06f6352ebe223f183067ecaf8a59435eb30b5603c853f2f57ebcd51d736a71be00ffb342223e1acc272b47f0d7ea8c3940fcd52366c5f102f6b2bd7e4ac99ca0bf729bb9ef8fc69f0d8442fcf23e835d7bd0b700bbfb71fe4efdbbd5b31f1fc5836cd4dbd7ec3107e0f600ac87c8ef0ab2afcb4e06c8878a5d665e4ff231580d307f73c3ccf379dc5fe7f38bea9c59589c2f52bccb429740613fbf0c0e03ecb7fd2d66c9cf23207fe8e21f5db7349f3297b0225f6fb79925cecbeacb9e711e5c427eb79aa17f8fe67316770b268d6f099c4aacd735e48f452a317f513f511af7db256663b11fa2f891a5ae3ff8fb29b3c6fea7be00cb21e42d1ab00ae16f35da4f4d84f3809ae24796b9f583f45d7d02cb10fbc5ea10ecf21d9c1742bf2296d88f56d0877317f88fc5fd6e3707792bf88f0b67184f057d4b3dc4754df94da65c7bd4be5660b71ee179c62d588f2cf20b8c47f7f29a23b01ce0bca63e670e91df1539b8f77743e7339989e310f683ff1a39c2fecfdc3087c84f4ccbacb13ff3e07fc6c50bd893f2efcc869c3f5512dc6d10e97a095611f46f53b01b0fe2ff057388f18d6bb0711e4efd53fc1103d9ef8776c06e3d857c1ef310f160cc6c23e87b4cebad180a8bfccf3460170fd15e04d621ce03fc9239c27adde6601b62bc39e9578cc214cf5bcc35580586ec5554ccacef629359225ed845b08e30fe16e319d900fb054df14f04219fc7b523b01cf0fc0d9823d857a03f37dfe12fc56766c5fd2d80758cfe0a5a4f459884787e546e80dd0613ebd757b09307cf6fc85f4514f2f3b05a81e500f3b5be621e61fe19f417b9f883f16f301bc823a08f48c7f0a782e2a988e32440feb00a9edcff85d9607ee91aacf9fca8d9051b7e9ea2687d1749c4e7d506fd257dfc352bcc8adb5f67b668bf5803bbf98bf91c3027ecaf37ccc2627dc7f8d254c4643f03fba6bdfe3de82775f2e27d914be60cfed61c806d8278e0c17fb3889f077bf0af2c11785fa381bc59ef0f6619ece225c6bbc4ccfad66bcc16fd2bf85ba653e443e23333cb535d324b8caf84be5d78c6fb27ed27b0ccb03f1a9f81b5db31d1fd9bcccae2fd22caa7858c628ca786ff49b73fa2f96a4e9835e26d0d7b4b95e13cc452fc13ca2dffc89fc760272fec47f1d37567604f0ff359eb90f3ed4fcc3c9fab6b6603f9aa2b666b71de03f98c8805de07f1c15ac25f5bd8c765f7388f6b057382f8e5533c165624b8bf8dc176c8f934f9ab5bed13c86f13660b791ab29f5bbd24ce73cb16ecc60bffa6f1c99173689c87ac825dbe05fb9f83559fefd560e7cf987fe42f3288f9f9a1bc03a796df270ac166047d94140f9c3086df47b260c9e7f12db352382fae297ecaa82b24ef1e5871fc56a81f390360ff44fe27e36c90401f867998c01f0760d99ff70b706f2f0dfd246914217f5d604ee18ff922d8f587f380026c0631f2c70de6d822de8ec17628707e44f157a66e4786fc5233c7e8cf7c0767a304ef17fa60c9ef7734097302f6c8bf6596c47c7eb80536438ca7827dddf2cefef98539857ce34d66897cd1a3f5564ab78384bf8c996588f3877d7096e1fd9f1aed4bcdef7354189fea0add7f0876f907d6cf6bb0b6fcfec13ad8f0fa6d6366b78453fb141f5df3aed075f4a78dc0f531ecad6d86fb15cd3769b200eff3d5b0b7cb96908f94d0af75f115efc7e17e9bc5388f574b3de3bcdd423fb67fdf617c0a367c1e55f3fd26c67aa5c81f54f73a06ce231bb0ab8ff5e58c39467e5bad332b8cc723ff53c3ee0087aeaf81dd75d83f04bbf1d0fd0dd9478d5484e7e7f91766017d371a6c32e45f39e5472a703b7a9ce7df81d500e7ed358d5f856a88f3698bfe4317af709e40eb8b8ab20cfa1219580cf1fea3c278dc6c857cf90e58a5d8ff8c17c0869f17488a072acec208cf1b6e984584f76d4f9915aefb9f990ddecfd21b6091c03fcb12dccfcf22643660fd0d6c068817b5c72c793e2c322b3e1f86be126d713e2bc9ff54eafc03cfef32668df77de516588458dfea4fe0ae90fcc7603dc2fe38a7f8a3bad7dba1af8059e17db8fc88d9e07d587f156c86184f097d89cc429ef2122cf9794f83fedd82c2cf27e07f520cf03ca35c610ed07fe133a7319eef64cc1af1ba1980fbf5b44dc02641bc1f9f305b7e7e17f70cffaee08f2ad3783fafbe06f7ef278c218f5b8ff97d5dc8a3ac40fc2ae02fddf2057bc07e5a381390bcb7603940bc2feec126c4f949a3980d9e07b5d09fb6433cbf6d2366ce674acad79511439e8f1533c7e71af3dd7485e449c1ae3fe4c7fbccfcbc638cf9edd67be4c316fe6c9dbf40ff23e608f1c9fbc66c783ff71dec5650acef9b60c5efcb9b92999f8f1a8cdfbafc00f188b9d7a7257fd0039731e3bc649159613d330558f37942dd320f715e682ec12640fcad7db01d215e55b8dfad7e789f5787603548906fe660cdcfcfc61a6c867c7e7fc1cced9b2be610ac6f991383f362ca0fdcec1af2f9dc77e698f3fb7bb0e1e781f53ad8a6380f6caf268cfd39ad5f3a702b06f421c06ec6d1fdc682fbf72de43ed8c4d8bf5509d8861cbfb9be6b1feb37ea876e85c57ab506d601e687d1cc21e2b96cc026403c2a6f99233cef69319ed0666081feddee0eefab08cbec2638cd9743662db03f36e0ae507f2370efcfed06d8c6d8af595a7f74ecfc11ef33696685f7fbfc03b08af0bead51e0ae507bf09fd8183c2f6ae11fb10df87de36366c9f31ffd2532cab03eef3067787f5ba760cde7a312e371f918f4a1295e68b71ae17d577502761e8af521604e71de579c83fbfb05fcdf4557bcbfa03ce638c1feffa267cccf629139c1f33cd1304bc40b3d6656fcfeed3db3c67e406f311bbc5faa76c13ac17aa233667e5eebc1fe420fe09f7a9939c4f32fdd30f3fe5ede80ddfc417e88f6848d2cde17427f5247b0cf789d59e2f995baec19e725e60bb362ff3e023bfd219fa078a6dd7031ffc57dcf78feecf76c05e6df10acf97d6fb1cb1cb2bdce9923e4f3de1233e7f7fa2b73027f155bccfdfb341bcc19bfbf90334bcc6775c5ccefd728f88772eb2faeb7cc01f2893c664e30ffeb55b01d607dab52e618facd31ffb55bbeb03f184c18e761cbcc02f94ebed433e2919f301bbc0fe1435eadf97d3031ec99df97d861d6c83f9acfccbc9e6ac403edc6877fff70cd1c21ded81be614e3cb37c16e3cb037e28b5192fb5f00eb18ef777b25333f2f96c184f1bc71915923fe8898999fbff95f7bc67ed7c375ebe633dea7fdceaca1cf02f1c7ea418a78b0cecce7ebc2305b3e9f3b059b219fc792bf19b7dea5d86fef315bbebf061b7e1e24d798d9dfe51766d65749f6306eb5c3fcce2d7320e0ff8bccfc7e469bf58cf30caf007785aeaf328fb0bf6fef98139c478b6f3df3fcee3963ffc478862e5dc0fe95d66f3372f30bfe76c59c64c85f3db0e1f79fc477663e2ff5379947f09f769139c47e5e2c3147c85f65c1ccf23490676403deaf6c3027f0af9ce2b5099c3fe1fddb5bb02b386fdd9f30ce97379943cc4f7f87b9f75ff417baf50ef6827d42371e6a6ff79299ef1f17ccfcefdff28cd9623e57e49f26721314e73dde84217fc56c118f24ec1f390de33ca8e919fa51923940bcf6fbfaacbf1cf68eec00fd9794bf1a97ed60bf692f7bc6fe572e834d9fafb413467e71c01cf1f3ff73e698f5574d18ff7e249930ce47608fb897c76e330f39ded1faeebc7104ff56e7cc313f5fcf99930cf2943d73ff66c2d81fac3067f8f77316f331e9fb6f8e9803e4573ef4917685d62bcc87b497cf56cc237081f1644e3eec272f268cf3c905e604ebafdf3273fe550c9925f253037fcefaf673cc5fb7fef2f3807b663e3ff57c66c1fe7ac3cced598a678ef83cafac9805db47334b8cb7389e30e4dd9d30e4e3f66c00f914da5386df4ff2636685f74914ad572e1cf3f980d7306b3c6ff7d01ffd8fda477c347d7ee1e17e6bf87cb1a1f5c66927c27e6c4cfeefb2e708ef3b36a7cc1ae7a32d8dcfb5d69f8f927dbad508f1a225ff72bb1d89f93cbee899f36592af3bde81bfb7241f8983fd2cc587ee5f97e37d0f730bb63cdf772f517ccf17bef495af7de3dbfed7d9e2e7ee9af9f3df9e2b2fadeb177ee95713aafdc6ddd9e2ce4734f64ffc53ffcc3f7f90dabf70d72fbbebd375fd2bffdaaf1e5a9de9efc6bf7525a7bf77eedef9b5487affdeffe42ff4bdf98bfe92bfecaff8abcfcafbd9ffe2aff9ebfec6f37aed0bece16f52d9f2b7fd1d7fd7df7352eff36f8f4b37cecb17fcf65c7959dd03ff90460efaea1ff9c7eece5dbef3db0c7d77d2b6fec01f765aa45f467e30b93e5b37f423d7ea9cb1ed76f776fa8e5d693bcdce91ea2b499ff8a99f797edf8ee779c2f33de929b2f9e653093ded197fd7b35e3e91f0d982f5c22b5c29bdcaabbd865ab1fe3efdd695d61b7b27dea97746bde5ae6fdffd3df72ebc4bef6af7d22b1c5d7b37dead77e7eedb9cad3f69e5defbe42d788bdd885d0b4bdeb2b7e2ad7a9fddfd5fbc355773df5bf736bccdae3d57b6bcedcebb5ccb3bdeaeb7e7be395d798dbbd35d757aa81ed1a5b7ef1d38c98dfbe5d0fbea1db9ebc7ddf5d9bade37efbbdf721f33c5d5b3d4c7c01b74e3f786dec80bbcd08b78849023f7622ff152a75dbfd32cdd9b09df8f85274467c7496b53bd0a2994d7083d91f00705eb272d25d6cf452e0a510ad793a885e1d274b28a568c69d674b3b075354ffc5d712acec8deb938f78ec585e8acbf3f5b7fd2ca95b8f62fc50d794d2b6ec59debf55e7cf22bb12016c5d2eea558162bdd6ca6daabe2b3d38aeb4d7c71f5e1add4335dad453d4546ac8975b12136dd2f566c896db1d34948fd3caebb2bf63a6d4fa47a54a66a5e897d27ef8138ec7cac97c37d7e1547ce162eb24c34742cbeb97bbe8b41e741fcdb6caf4331128170bb5392f099be51d81eb12b89eb2d757acda4effca3a0df5c919e14524a25b593c872bcc9a5f18edd8295fb145565e135b2945ddcb0b3f527add4d2cd3c093d5dcab17f4bcf674e3a3f93a7f24c9ecb0bd9b5bc4fb5afe4b593ca8d49de78c79d464857ee7adfde0cd5f256dec9fbcef3e527b9405161eafac377b92897dc5cabfa561e97a99a4e5ecf97cb728547083972b92a3fcb2fae0533b9eb58aeb911ad8b6e5e99b96d6dc84d37f62db9dd49f85cdf28b087dc716557eec97da7d703e962b7fc2a8fe4b1fce615f2bb1c381e7691aa8b2014d77339f25b19c8b01b1df7ccd7a6ebcb68d24aecec712903acb33291a98bd3a69be1febecc94af3c25babb0564813d62f6b1b8fb8d5bdf419926d7f3a6924e6aa7b9ee4cbd4bd4fcdcfdb5ce523375554ef6c0f7a2970ded3f6a3581bcaa64eb921caed54ad5aa512d5aee8a97a9b16fd4893a9d966fa6d73379edf9ea5c5d74123ed49857b09eabae5ca96b75e35faa5b75473e44aba930ea5e7df25bb540f6e824abbabf6ad1c9b0a496dd778bdfd4257f4ed73793565694cb3fd46792b2525fd49ab347a5d6e9da86da545b6abbb30d49722956d58ebb7ad5b7dc95e9ef53b4abf6e8977d75d0ada72e765bd660dc458b47771eaaaf9dc418ef44b6ab27ad5eaa2375ecbe7d53df1f8df05275ffc72323158898ef0a3de1ae452aeee2aaba9cd356a252a7ad4cfb93be9f2d38ef709ee26ca33d2dfcb5ee9caf5bcf454c6b51dc9d2369ab73f2914e32dbfdd5852e75a5eb2eb2e137ddf0673b55bf9ab432d627fa549fd1fcb0fa5c5fe84b7da5af3b3f5397fa46aee8db2eb6ea86ca9dbe77925ff52deb4fdad9572feaa5aefe34e965bda257f567fd45af75b2387f2d3833edec11ebf5993b37f46637b6ae0f677596cdf58f5e9b497f8dded2dbfeb2ded1bb4f4668f49eded707fad0b5d7d5fcaa8f5ccd63fdcdb7134dcecafb5d0f5c8da11e75ab6ddfd7fc42fbaf89755cc4deef8aa8d5159e47e80023a48c61bf5ba778ad32cefbb9267ed3013e67ebf7ad4cdaa65f5517ddf6bb1c8eb4e17cadcb375ded86eb873a72716ca76f59372e565488fc9df6a6a9f7f359a99fb9d3edb8bb1ca3aff5b84cee0a2061378ea723c458ba4fbaaba1fe698debf5f844421a7b97033c4838bfd0f960cad649bb765c8fa4233c4f7025e8460c4d4fcd45dbad1854336519facf99fa9356d2ce1fa77e6da06de73d19533c55bb71a1d7eb2309ae3b2f755a874fced2640e36d3bd3dbdb35b9cba1c75bade6c99dc95cee8e2f108dd3527d9d5a41d8c05fdb39fcf4818602e76f69ad2ebdc42fb75f5b305b9c0cfdff7d2a253ac6eafddaebaa26892be9de4bf5ac81efa670be6d6cfdff7133dd0bf9637e6955bede44edf52ee5f2d640ffb51de4b217be41fe5bd14b247f151de4b217b941fe5bd143c3ffa28efa57cd8e37d950f7bbcaff2618ff7553eecf1beca5bd9c354a6368d69cdd89cfcee31be5d31a70fe5755a7c1b7b9833736e2ecca52b57e6dadcfcbd5afabb8ab3c2ed54b97b8d36dfc21ee6de7c320b66d12c9965b36256cd67f3e5efd7d6db17b2c79a2beb66c36cbe637b6c996db36376cd9ed93707e6d07c35477fbfb6debe4cec716cbebdb53dcc7733f06fbb779499bbb771a317ca199bc4a426b3bea5b7f6acb27ab686ed5ebdcd6d614be2fc15b594ff807e543fff79497a7bd8cad673ec91fbb7de896d6cfbb2d6ecd89ed8d3f9f6b067f6dc5eb8cf4b7b65afbb5fc4b17df12a606fed9dbdb79fec825db44b76d9aed8d599eb9fed17bbe63ed7edc6cf6be185fa9d473fa86f377f5e92893db6ecf65c7b74edeed8976a6dcfee637e78d7f6c01edaaf53d78eec317ffb66bfbbbf83ceda76f842495b3bb2ddbf2e8b6c6c139bdaccafa6afe7ddab0e33924f4b908b5ce62ad7b99973cde6795ee425c69a57799d37799b8f1f6b213fc94f5dbdb3b9f5a65acccff90d51baafa7fc22bfa4fbaef2ebfc075ed8db23bfcdef9eb3477e9f7f9ab174fe7454ac95857c11f610e78e96f2e5a96b2bfd6cc857f3cf33edbda8e45ff2b57c3ddfc837f3ad7c3bdf797475f7d15ccba725c8f7e8ef7e7e30e7da61de69f188c77a9c7f737fbfe783275a18e62ecee6c1dc7a332dce8b5779984779ec3e933cfdd12827ebc75a9e3d678fc22fbc79fd3cd579210a59e0ff0fb270a4e5940f4fdba3303f6d8fcbc21679511465511575d1148f22e8537b4c4b508c8b93e2d4bf2dce9e5e9371e1c6515cf0582fc9b76f8babc75a90b134cfd69b6971fefa515c1737c56d7157dcff923d6e8b4f72a95898d7cf539d3b5e2c96a6d68f298d3fc4ab62b98b573f678f62a5582d3e175f8ab562bdd828368badd93d61ee17db8f249ffa2c768add075dce5e7b648fbd62ff49eff3ec315b6ffe0a3e6b8f83e2b0f85afc4956f8e7f3a3382ebe15a4bf62500cbbe835b7d7a932df1ec5a8088ab05bcf8ba8887fce1e4552a44556faa5578a5296aad4a529ad3f3547cabc2c4a97599555593f95ae6c4a57b71ccf93bc3c29dd3eb8e475a13c2f2fe8f3f2b1b6cbabd26521e5cddc7a332de60be5ed1cda2defcafbf2d30becb13929cfac1fe542e9d68572a974b1a95c79de1ee56ab756cdb787bbfab9fce2df966be5faa3abb7537fe79672a3dc2cb7caed72c765589fcadd72afdc2f0fcac3993a5fcb239b97c7e5b7393affae8db6e560ae3d86e5a80cca5041bf511997499996d9632d547ee5e54525f8aed97a332d56b252fd7a3e45bb95aecc8fad4116b9337795adf2eef3c955eea72a2ae77b5555d55553b5cfdba31a5727d533f9eeaf94eacc2e57e7d54575595d55d7d54d755bdd55f7d59ff8da0bdb5ee8667db5582dbdaecc737a5aae565e58d3a56fafd7ef1bd863b5faecac71557da9d6aaf56aa3daacb6aaed6ae7d75b766def567bd57e75501dfe7a5b3fe8e56b75541d57df9ead51b939d197ef7e5b0daaa1fb6fd4fff62b7dff457be43365763441155651155749955659edd75ef71a62adde52837f6fa9756d6a4b25f75c02598deab2aeeabcaedd155d37bfd2f65f9e1fcf5883e46deb717d529fd667f5797d515fd657f5f5efd6e1db94faa6beadefea7bf7f755e2f12fc5ab67acf1517ea5fcd2faf1618d572f1fcf6bdf57f9b0c7fb2a1ff6785fe5c31eefab7cd8e37d950f7bbcaff2618ff7553eecf1beca873dde57f9b0c7fb2a1ff6785fe5c31eefab7cd8e37d950f7bbcafd2d9a35ef828efa57cd8e37d950f7bbcaf42f6589c5366ebcdabf151dea07cd8e37d950f7bbcaff2618ff7557ed61ee6b65e729fcbee73de5d2bf56afdb9fef2bb47355b7e2cb3fb758d3fff6a0feb33b4516fd2e756bdfde8ca0bca5fb0c78efbdc7d46fabd7adffd3d9873e5f00752fce8da2b941fcbec7efd5a1fcdb1c7cb7479f8a4e671fdcdfdfd5e0fea613dfa5959ff823d823aac23923eae13f737adb3fe6ae3375e23f8bb6c54a31be3bed9266f8aa66c2af7bd6e9aa7d7dec20a2f95d9dc366d33eeedd14bd69c34a7cd5973de5c3497cd5573edaedc34ae4673d7dc379f1ad2c84476678f66b159e2712f372beeef6af3b9b7d4a4cd476dbd8e3d9a2fcd5ab3de49df6c346e66365bcdf6c41e3bcd6eb3d7ecd3f783e6b0f9da38cf6b8e1be731cdf766e0fe0e9bd1d36b6f6d8f1fc9ecae064dd8446c8f8964accbb8499ab4c95abff53a6e452b5bd56abad6cbbede9ad63ef4d7e66dd1966d356983db7cdcd6ebd8a3addba66d49fac376dc9eb4a7b377b667ed397d5e38ff3a6b2fddb72be2ebf6a6bd6defe65d7b6b7bfc48e6eed7f6befd047b3c48065db60bed62bbd42eb72bed2aaeb79fdb2f2dad38bdeced7abbd16e4e6960abdd6e77dadd491bdce6e3b65ec71eaefdbd7e76b7fbed413b15fddbafeebfa3f698be8bd6794ffbbd9ec4d776d00edbd1fc6b6f6b8f1fc94c578336e4ab13c9da88a58edba44ddb6cec7734f6c6a2556349d77ad9d7c76aacc7a66f716cc7f9b878a831d5e64c5baf658f87cf71d99e8fab87abe37adc8cdbf1b8fbdec8f1c9f8747cf620f7f87c7cd1faf3afbdb53d9e97997fbdecd78f5eb2f1d5f87a7ce33e6fc76e4e8fef1bba67fc69bc305e1c2fcddac3fdbe3c5e194fbc7efc79fce5a1c6549b336dbd863d66cb786dfc37e8f375cbfb96f957ec31de186f8eb77ef7087eaebc77993ff6e7efab7cd8e37d950f7bbcaff2618ff7553eecf1beca873dde57f9b0c7fb2af4fe55fe7665bcedfedbe1ef53ff6afde3fbfcef6f6e8f9df1766793df3dce7f97ef0ff618ef756546977bd39fb8fe5063b6eeb3f6d8c51cf9dde3fc77f9dedb6356f7b37698bd32afe6f365bcebca36fdfd282f287f668fa7f361da4a0ff365deb7dee65dccfadd7ef7eff2fdc7f6988d4fd3fc60abe7be4df7f7618fbfba7ebc345ecdce8f877b1f47b10f7bfc557bcc6afd65f6e8bf3dbfca7fd8e3afd9e3f9f57c9e5d66e7c847bc7a5d7b4cc79c87ab4fedf150e347abf8e3f59ccace3bc9b1b6f9eff63b91e74979f3fd20e6076558bfdb07498687dde9f6e3efef619ff4ff873d1eb4fdb84e7fe5bdc4d5697bfc525bdb3faaf3fbedf1d2fabf7b1ebf8e3d9c8fedbce371fed057e68ce5a7ea7fd8e36dedf173f3e92decf12a79cbce8b329bbfb76cffe54ceab7655faf363fde5d5cfe351f7fb0e5df3f3ffe23edf15a6bc0f6c3e77f943d76fe665f7b557bf0cee5d93aafb7defc67dae335fb9ade35ceda603aa6bdd65ef23fd11e6f175b666d305de735edf12a99cc9fd5f8fb4eb07e576ef42a79dcabcd8ffdaefcfef9f1fbcea07e74d6f278ec0fe7658f4fd15ec31eb4fb205bc02acf9437b5c7744f2fafff6bfd3ef6bf9935a51ff38cdefbb3b2c7ebff430c7c6a0f6ee9e7ecf1a7f53b8b3d2dbf6283a72df5e3ece8913fee4fdf3b55ffe7e47952fb79ef9bd7ef94d5f6a7659b2eb47ecc93e9873d3da9b1f3027b6c8f1fe524cff7f2d0c3436f8ff532cf375fa6b997daf849f94b7368fef89e4af3b09e3f8cc89fe4d2cff731d5e674bcfa537b3cfa7d7a0e3f9def93f13fe8e2477af9fde7e4aff57d6e7ef5b3673e7f7e7ab5fba4c69ff7f1b2b3a777fcacefaf9467d7f387b93fb512cd9de3f486ee9fdbff2575e6ccf7edc7e5512c7e277efd9af363feb5a7e39f8dd17f8f3de6b43315dfde8f1edfde1ecf7d7f9aabfdbdf698ac16ff316bc6afd9e3710c79a9ae5fd11ed3674aef448fbfd31e8fbf3fc99ddedc1effb9dffff97fffe73ffe1f8aa0a745</data>
+ </image>
+ <image name="image9">
+ <data format="XPM.GZ" length="39746">789ced9c5773dcba92c7dfcfa7701dbcdddae2650eb5b50f0a568e56b4b7f6019154b672b8b5df7d9bfd07a9913463f978e42b1fefb8cba3f90d41a0f147a3017064fff31f1ff637563ffce39f7f5c5ec9ab03fd4137f2e2c33fccf5c9c9fd7fffcf7ffdeb8f3fa33cfc50c51ff2a8fc10fff91f7ffc1950990f22e43f2d376be0d2b33d025795e7999e23e6879eb9befaace79caf1f7a96b85f5d31476429f367cf31cacb9b9e4bf6e71adcb5efee3ccb50737b1b9e95af6f8a390ed3d0b46cb4e72c627f5d09ae54c4eda98c39693de2fa56c1958e2c979fe93846ff3f32a7bd3fc6b344fb2ef56c62f47fb167ee4fdd3067954da0d77dcf19df9f7876e8bf84bf79a823ee4f7d0aeeda97fbcc4514268ef5427f8bdebfc6b34b58af46f58cfa64cfdcdf7aa6e394fd914bcc651481eb08dc8d67bd0da6ee4b6e2fe899eb1797cc5558410f557b7649c5d7a17f15c529fb27cf3d27b83fb8ef99fba7a0b78cb28cfd51179ef38cdb6f16c032f67cd7710ebdd09e8a2a5c77885f45fd417c60fc954c32c5fd8b3bce0bbe2e7b667ff50eb38e24eaafd19eeeea5321b38d1ccabb5b70775d633c5c4c43c8fcd97392b35eee0b58e605fc65bda390e21df36f1f2c8b92f5521c2f511466988f92fd8928fec384cb37e0d6589f25b09405f7b739f3ac73be6e79bca2a4351e0fdc9fc4bae0f6dc05589a9ce3a7f9d833c68bc7234a2982f97ef9c5b389594f81fbd3284ba0df1598fac7edeb69e68c4618e35181bbeb35eacba4d757f17c8bf2a84079077f726924b7ef70bde8eeb7eb601515dc7eb0c55cb6c6f5a5e044965cdeed8115851497c77854adb1bfb85fc631e6bb8dc02a2df87acdf934522a51e81fdad7a40fe70f390f8ea801be2ec0692a917f50bf5679c5f72b8caf097d3e33d0d390023c1ef2c87311a3bd25cf3641ffd09e49f312fac59e2b89f8c17853fc62beda7b70a5fd78223e287e13e8b1efb940f9e612ac8a12f1b7eab9923c3e72b3e5388c23dc6f96c04989f9641d33072cfbb7e3394ef87e13782e63be5f2c778cfe0527e05461fe48d447b723ffe9d47386f10a2ec15981f1b567e0aebf9ae7739c507cf0fd12fe2471057f74ee5922df068be0d4163c1e01c7639c2609f2a5e0f94eade7c8df72c67301ffdd21588715ea437b799261be5bf437d7a146fcf2fa4d77cb8ce79784ff459e28e44bce77a4561c319bcc7389feab7dcf15f434671da798ffb39ea58f6fe8515606f16ba15fa963cd2c787da6da32cc77233c97580f824dcf64ac9ff32cd19e58f7ac62c4cb0238970afe415f4925383ec4b9679572fb8d04f7fe4d8175a6917f106faaad81dbcf3c2bb058ec99db17b39eb55f0f0d98eac37ce07c10ebbebe65cf3ac5fa73e0d9c03fc9f92d366458ff6cc729eb53432fd3f96fa0af4d42e44b1d794e12acaf88175b140af104fd5d12a6d87f20fe9ca614c6fd61a6da225c1775cfecbf9b076badb19fe2fd47bb1ca4c80f73cc7112c6980f5b9e698ab0fe3cdf13fec3ed5f83b535f09fe32b494387fd5f3d05ae6cc8fa5ad49faa08fd733b60ed0cd64bce4f491e1abf7f3c042749ccfd17339e8b14fbb94db04e2acc47cee74911e711caaf75ece3691f9c94d87f98878e33ccb773701929cc87124cf5a33cf42dbbf2baf65c617f53e7609318e49715e68aae235f2f768cfb5d01aebc5e02fda7e524e3f2e6c4b3c6fd66b6e38cfb63a67ae6f6cc7dcf981fbb605318e403e8a1697c90cf0d98fcc5fc86ff86ae23dfc4e02ad27cbf81fe3671684fe27e9786d8bf390d360af359737ca7b41d477d661a4ce511ff1c0f29455f8678d5e02c82defa1e5ce60afbefaf60a30cf22d38eeee771b60e9db93bcbf4869b789fd9fe6f14dd3c89f4704fca13f19eb6138bfa459662af83f0ba6e309e2cd818d363cbf0d8f5f9ab7c6bcedb9c8b0fe723ca6145f31df6f3e81d332c3fcdbea19ebfb32b8541af5f17e282d5b633e66aec8b07f5a07cb08e319f0f8a43289638ce714385519e277a763acc786f37daa5a63be0177fd6d78bf916a9b59ac173cdf531325684f61fc4c92f8f52702b7c6faad76ece3457bb6d88f3ae86f3aff2dfa6ba83dc43bdab7a9c57c31779e5d8ef9057d5d6b7c9de3370b5b63ff6ec052223f053c7e145d9586bfbc3fa5c52c938847ce37594286f5e4c1738af342b3029631f673cd34d864c8cf82fdc92880728cd76ecfd0cb822b89f61bcebf59d68f1feb95e5893f5f1994cfb32247fcc6e0a290980f682fefee37b85eb4c68ceb6556e27e33efb9823f62135cc658efea7d70d73f117a4e34d61f8ea7ac4a439c7705f4aca83e9c87381f66b2f3c7ad784e42f8cff331533401311fd0beca14ce1bc679d639f66b0b609b55180fe849e181f395c478dbca69f49fd7e3cc650ef1d53460430b1edfcff195f38182f9ac671e7fcde3418b85c6f3089d805385fd607301961ae72dcdf9b49dfefefe63306d08a02fcfb73ccb69c4b83fbcfee705218f7fc07ae46561912f2def7f731a9d02eb3bc7632ead52981f9c9f28192a9c3f04e7c7dce406fb51c7e3975b3aeff17805ac5f11a611ce4f661f4c86fd09e78f82d428797e886dcf31ce47f2182c23e403c37a163119e64bdd33f74fad80e93889fd08c763410b6a81f323e7b7228da310f3e51a5c54b8de08b075c83706e539a0b9ff9fc02a8ab8bd3a0077e503f84bc381f5dfa66095e03c17dc748cf5d9f27a5054320bb97f96cfef852c6489f5ec0c6c4a89f304cfc782f67f383f8b2d302daf8817e84da35162fe717c14b6f0e7853a039b0cdcf0f8164e5a9f3f391eca900ce36b3baeb0dfb800eb1cfa2aee7f49c755e4af80f52953caffc8b70a5ca6159e2fe460a315eae37c5ae6498af3a6e6f5bc2ccab2e2fb15ee2f94453cbb05b0cd0cfbaf79fd2d4b135ae45b8e4fba39437d92c793c45398bff50a981204f2ff0dd885d8ffd953cfb1c5fa8cf24a91a4ccf05797a6c2f9fb184c0772d4770256c69f8f797d2a0d95c7fc2cc02a437d6a1a4c1562fcae3c2b83f58bf365694b8bfbdd2eb8f3dfee80291ed95fcdeb6fe928c0797c82cf60a5b1ff723c1faa5015386f5a5e0ff97103e63bfb57c526c27e4c733ea3c3a833d07316ac43ec7fe4aee7086c783e55699a44d89f1830198f9740fd29052cfacbf155b5091cfb891bb054119ebff27eb7ca4b85f9696ec17460c37873bea868faa27ec3f15295e410ce4ba8af944a43af79b0cdb01fb33cbe5545f18ffea13d991becefc529b8927e7d663d2b5b593cff51e8af4b73e8a93f812963239ff178ca900cf1647a66bdea3d302d18385f72ff64241df24b3305d6259e7fb82db04ba19fe4789371eaafd7b89f0e6806f98afb4faba77f9ea0783d91b45ae07980bd035379c437fb2f3349299febe7f192b47ce0f946c0f34d16598af816c7609d389c27389f499a20589f9b59b0294b3c0f457f4a57383c0f86bf5521fdfef93358858867c9f399a66b85e75bb505ab0af9b5a9c186322ef76fdd33add87c3fef07a5ca72f86ba7c1948f31fe180f4d86f58bcfefd2ba10e3ed963d170efb21f4df4987e71f35f4722e423eab973cc70af38fe7bf0a2921e379139757516bdc7e05d60afb6bbd01369545fb579e0df27133df33eae77cac621a00f647f37ce4ed34ee477ba9d67e7fcdeb916a373cc8f7bcdf53ed828ef8e7f59cb29d817eb600db10fbb77a1aec228978437ba5f2cf07dd9ce702dcb07e8af60fd8ff2ace278a765b78fea137c1a5f2cf072cd8283cbf323c9e4ab7c65cf68cf9293ac6fc6e50bf360ee369519f698dcbcb8e7df91bb0ab1cc74fc0f1a46c9560fe6b0d56cee78f59b04bf1bcc770bc2b57ca1cfbb908dc1af777b3639ca71a07b619e2c31df5cced295eef7568238bfdf595e71ccfe304c78ba6ed21d65f770f267ff07c93d77bda1e6478de6637c1b6c2fe49723ed309add0d8ff1f837588fdbefb0ab606f15a9760575ad6df72bce994b69f38cf6f794ef17cae9e03537bc867a82fb31afd571cdf3a27c37e681d6c43c47b73ee59fbf3099f7f346d58d05fcbe3abcbd658ff8d9ed1df6b70575e72fcebf6eb43c41ffa5f91617f38d733d623b447f9c59fcf16c064683f01dbee79118f9f565589e70f1aedb7dfe7e0f95ceab9c47922b8f36cf0fd400dfd942d32c487f5ec305e9ad737ad2be3bf6f433c6853f9ef8f307e9afcc17870fce9367d406ff8d73e2ec07c097a467c227e0c1d70b11e6c78b6d0b346fc181a7fecd770bfa51587dbd75f3a2eb05f863eb635ae1ff16ae9c084fd2be70bed28dd61be8760edbfbf0c0acf0efe3527604ab88817de3f9ab035d677d57384f54ef3f9c25076c2f77141066e8dfb13826d84fd44bd087605eab3b73de37cc7f3c9f00355be1e83697c106f276057627f5a2ff40cfdce7bc6f9f4b467aca71c1fedd33a9c07e44acf787e06ff69fe61bf6b79bc4dfbc003cfef13cfa9dfaf7dec19fb69f89792fed0fbd2b3c5fc711198d637e873e1b942f986e787c9baf235eea7e32df295cb3d2be44f81f1c8697ca13ff46a0f88781e5b83ad55d88f43dfdc25fefbb475cf0ae3ad385e4ca1329c3f44eab9c2f78b01fc2f8cdf9fbb6b308d1fe289e3d3b41b70f8bf0c263db13fc778573a84bf6ad67381f36e30edd962bfd6cc806d85fc1e70be30b235be7f094cc72de887f8a20507df3f6c5e758cfca4793d3234c1fd791ce3afa987789e2c3cfbe77d01e247d3fa8078093d1716ed23dee83c81f389dcf32cfd7e01fde73face76dcf184fe5d9e78f00fda1d500cfc3025e9f8c6d8ddbe3f5d138edcf430a7a3b13e2fc1948cf64acbf2f6f23ff7d3cef676c48d7517e036cfd794e9cf48cf8e4f38ea5fd8f1fdf29706b7cfdc4738cfd94129e2be823793db2b12970de0914b835beffc0738afd929af1ecef0f586f9bb4c6d7515f6a32c4975cf45ce17c125c815be3fa53cffef70d64e2d939e463de1fd0e9564b7cfff1e0d9211e6acfe411e2e5c0730656c73d633f87f63317a27ecdebb9cd8ddf9f0406dc1a97bf0477e545e239024bde9f53b4c5581febc47381f36970dbb1c5f3efa067fcbe81f05ce179b3580077edb959cf4989f8e2f5808ebf29be2fd2539e33ff3cf5d07389f545359e69cbc6f5df803bffc5bce7d8eb0d7f2b5204ebc761cfd8dfad78f6f950e59ebbfa8fc05d7d2ef39c617f2c391f594977e079d685677fbfabc0aec0f73d02e3431b501f5f979e95efdf6acfc84f65cff007fe2b97c09f00fe19ebcf43eac433199747fc583a7f62bd0d3c4bac2735eb45a323fdf32a1e7fea2d9dd8f93a38a5fe62fddcf66c705e729cdfa9f602f15cf3f8badc95386fd4ceb375c83fec8f2b5d85fd76ad3c2b8c4fc3fb95f6f8e5d763ce4fb4593088df9ae7635b1bda17b89fff20ff6e5e0522908122938168993fd381090cbfb381a3f775d0d0eb41f739fd3c0c8e82e3e024380dcefc3d5f8373ba7a115cd2ebd5e6d590baae839be036b80beedbba36affefe86352f78a0be9d055364a445cb6c9af43ae077d3c14c301b7c0ce688a7facfdb9fb7c17cb0102c064bc132975c0956a9e45ab04ed736824dfa7439f8146c51d9ed60873e590e76833d2ab11f7c260d55dfd6dfd8b02f19611b6cf48e749541185cd1df0d8ad8ee73fe49d736dacfe9677bcf03c7f3411bd17d0c3ed0f81852dbf008092edfd6d6d635aaedbf9161ef37dcbc02a056870dd6a0ffbcbffe405a087aed4a2eb72599bbb15aa6e86d33451bab5f7ccc4b567d44db7f27c3fe7c62e318ce60131bc7700e9ed838c61a66131bc758c37c62e3186b584c6c1cc3b96e62e3d844c3f16da2e1f836d1707c9b6838bebda986d580bd7bcfbec7e8982f840ccc78b5bca186955003a6df5b9f57ed4a18618513b5688283716a7a630d0fc80ec59138fed5351427e2549c89afe25c5c884b71354e5d3f41c36b71f3ab6b286ec59db8170f624a4c8b19312b3e8ab91fafed9986fac9cfbfa643a7e1bc5818a2a1168b62492c8b95efece5aa5813eb62436cfe140d3f892db12d76c4aed82315f7c567f1e585b7ad852fee1da2cc700d45348686b1488669c8f5a622fbce5ee6a2a0d7528c5c9d64f05a1d234b18d9fe36a2925a1a69a593b56c64fbadc60b1d86f8354419fe4ef0501ec9636af304faa34c47f2549eb1475fe5b9bc785d437929af466928afe5cd131ffca8cadbce87beff77f27e801ee4949c963372d697ff28e7e4bc5ce06b8b72495e0c2db13c42db15b91ac4724daecb0db949fab556070fc335949fe496dc963b7277d0e3e71a52b93db93fac6f5cc767f945524ccb48c6df1cf72e0e0fe4c83894a9cc866a980ff800cf0b59ca4a054ab4a4a452f4aa1576215a5922a76ad5d0cf037538bcc4285347ea589d04913a15b35ec156c368d05bcc6545d1a3bef23de7eae2db1aaa4b75354a43ba7aad6ed4adba53f72ffdf97e0dc9a30735a5a687b5a366067ce87a3aab3eaa3935cfef177c9f167df925fe7459ada855b5a6d6479518a1e186da549fd496da563b9d866a27188cda01efd5aeda53fb54f3e76f6bf8e2da530dbfa85045eadb51f81d7148fd4d54ca3566aa8dbceba1ad0ef6b65053fcb354d5d3ba5ad33430edef388e2e31dcda7fc72b226db5eba3b0d175100fbf5f379a768ffaf089aff4aa8fda31d3c7cf359477fa640895fa549fe9afdfa1e1716f23f2a13ed73427f4a5a698d3dfd050dfb4b957df627eeb3bcd73403f3cd1704a4feb193d3bbac450053fea393daf17f4a2acf5925e929b7a59afe855bd3642c375bd41af9bcf357cb4a71aea4f7aab5b5306a8d4db7ae71505c9048585ded57bedcf1757bb7eef6b9a13fa8b0e75a4e36f6898e854673ad70553a92b131861e4d372edaf6623fe46957869edefab19676ad3980373688eccb13931a7e68cec314a06ee37e7e6c25c9aabefd0f09b66aecdcdeba5b82f7b7aeffb4abe97995b7367eecd839932d366c6cc9a8f640f66cecc9b851fabf1750d95338b6609ebe35033147bdeccb25931ab668dfeae779fbdb7662f34dc309be613d916fddd363b66d7ec997df3f9c9dee68d357cd5a72ffcdbd1adc5c19449cc7afb8fa14d6c72baf2c514efa4957e624f3d2e4d65038bdf92d3d604c593fdf53b68f868d65a676bdbd0eb58cf41dec84628d89a59e1df7ad9080edfa2a5dffa19ec0805dfda7e6b0dffea89ff07ed37d7f0df62130dc7b78986e3db44c3f16da2e1f836d1707c9b6838be4d341cdf261a8e6f130dc7b78986e3db44c3f16da2e1f836d1707ce37fab7b38b1716ca2e1f836d1707c630d8f26368e4d341cdf261a8e6f130dc7b7e71a0a658ffdcf1fadf3e4099dda33fef9d59e3fbbf2538cfcbea09f97c3fda74fafecb5bd79a596db6ff6eaf6f9e74334bcb3f74334fcbefe3fbc283965a7e975c6ceda8f76eee7eae7fd9fa79f0b23353cb28b76e9955a866938f7ec6ad7cb4ec365bb32d0caaa5deb355cb71b76d37eb25b769b4670c7eeda3dbb6f3fd3952f36a4d7c8c636b12997cd6c6e0b5f7b692bd4e70227e8553ad5b7dbd5f9bcae37d2b0fd7f7d9c6dfd77ced5f4d9d3de1db9c61dd0eba13b72c78e3d72a7eecc7d75e7f4eec25dba2b774d9f3ef7eee4c9d54e0fbe97ff0fa21b773be0c39dbb770fd0d04db96937e366bbfebb8f6ececdbb05b7e8782cddb25b71ab6e8ddfafbb0d8c8cdb749f1e7be5b6dcb6db71bb7d1dbecee775bd99867b6edf7d66b5be38eafdd3ded92b17b9983e4de86fea32f6287745fb3f30d9a33aa8452d6bf5b2a7adef8f571fe3b0bd97ff1f263de8039535b58586b523b5afeababba76eea83fab03eaa8f6bb0ab4febb3fa2bbf3f470df5457d595f3dd6585fd737f56d7dd7d7e1eb7c5ed75b6958dfd70ff514fbff504fd7332f7a276b8a89fa633d475eccb3470bfcba487f59af7af9654f59c3feeaa386edbdace1cab35656eb351f87cbf53a31c557bde9eff9546fd5dbf54ebdcbb457efbbd5faf360adf6a4fe528775d46b18d7499d3e9618a8f3495d6fa521d59b75b9a8ceebe279ef900febb2ae5cda04039e53b436a2fdd56c44da33ef4e9e5dddec7a0b0d9b672345a54d970f1bdbb886e2b0699a83e6907e1e35b46e3727cd29973b6bbe36e7cdc5530de9f3cbe6aab9eeea6c6e9ac13cfc58e793bade4ec3817edc35f7cf7a77d53c34537465ba996966ddf5330d3f3673cd3c3e7de6ddc9b3ab5e8f61ebf2ef65cd42b3f8f35bf99d356c969ae56665fc7a5eb3df59c37f974d341cdf261a8e6f130dc7b78986e3db44c3f16da2e1f8c6df2ff3bf4168561fff45c7e4fd5f793fd170a2e1aff09e9f39ac4e6c1cfbbbc461b3f6fe3e7c2b0edfdb8789866ffdbe53ebc9e76b233eff25deff6a1a3eaaf518799d86adfd2a7efe8a1a3ed58df55a1da0befce0fbf7f67950c3f75ed75ab5f8efda90cfd75e7cfeb2d43bdbaf11877f2dd7fd6aebcbcfd610396c54992ecefe7a9d7eeeffd61a0eaa337c2d185707ccf1df55c361b137a8e78fc4de88f76b63dcfb2b6b38b25fdf9ed73ff6fe67d4f9d88bef9a0b6b6fbe2ebfc7aa396c451fbf176b2f6c44ab6f1787efb9077edb7647e599a79f3fc63fc7e1f86bdc5be5b71f7eff8df5e559343d7e3eaafcf7683bf8fead347c0fdd5ed770d8da3d3033878cfbb7d7fac7d87baee1b873e157d8630cf3e1b5d878a9e1eb3a0c39cbffbfd67030aebeafbc6fe9595bfdbafca32bdbdbaf89e3aca5dfe2d7eff9c19efcf9bffff9c7ff0192189eb5</data>
+ </image>
+ <image name="image10">
+ <data format="XPM.GZ" length="47178">789ced9dd96ee4ba92aeeff7531436ef361aeaccd48c8373e1b13c4f65978783bee028c9f33c54a3dfbd43f147ca4e0fb5cafb949761572e02b63f53a282fcc9882095aef59ffffab2b3b6fce55ffff98f8b4b7dd9d82fb6d6e75ffee5ae8e8eeefedf7ffddffffec73f07fdf44b917cc9b2fccbe09ffff18f7f36975fec17d5eba56508cc17e02c133e67b6f9005c272df7cb5caeafd3960783dc09c7cc6991c8fd57cce5f0fee68cd916b95c3f68394e0b2f5c3097e5c0177cfd29b32fa5bdbadf72d22f0b701498e35c5bc36c9893dc58cbac3b762d2bd7b1674e842d38ca3be6f6f539d89771dab23de838e3eb578435eaa38a39a5f635b3ef98edd35f3b66fbd47ec76c5f74206cc1fe7bc76c4fd81476aecff5c3f6bcf08f8e595f8bf1497d1ee7fcfc15e102f69bb263ae3727c2d23f85f633b2afe4e79f77ccfdd39bc2626f83fbb352431f330ff669cc7aaa6de10ccf8bd63ae67a73262cf656188f9c9ec7f5fab863b6c71d0a3b19bf55b08f63ae8fa68513e19eb0d813d07e41eda1bf65c778fe79c7b03f1696fe4667c24ef4ad3be6f9e4a06f51f41db7ef928eb9fd70213c90fabb8ea117e663e1fb31e6f7407810f3f8db2361e9afbeec18f30ff697c3fed93b612febc376ccfdd1b0b72c12c7fdb519d88518d7a3ffa5efc11e7bd931d79b5d61b137a03d3d1c2f3d052e5207fde68433c7f6fa4638c77cd658cfdab918e3dd17f6789e9ded98ebcd9db0d8aba08f21ff9070fdbeb0b1bc3eaa05616b63be3eed18fe62195cf4444f279cc37ebddb31db5f4b7ba50fdc9ec6f8196762f81bb9de59b055c2d2bf50768c7ad86fc91eb6d761bdd9a270e8df5ac7f00f0bc225ea6bcc774bee9aeb2de69b7565d263fb1685758cfa6f4346bd391536a88f96985d6e0cb35f1096f517a08f2b4acfe3ed8e85b5c37cc1fa74ae4858df685d58eca9303ffcb07d87f1f0857518ff1d61efa0f704d86509fcdd95708ef6cd4dc75c1fd0bf40edc3bf5e740cff0f7d433180de5e0b7b0fffba2f1c604f83fe05dd177f077f1f5c9c70ff95b4ef9284e7833d114e618fd9eb98eb2bf657698fec61fdc211d80dd09eddee98e38d991496e779707fa8478df6fa7a10f87ab50376bd04fe4e09f7a53d1ebf74905bc3f35969b0f509fb23bb2b1c70bfbee818f183e34b1a93fdcc7e5658fc8bbd015b9bb07fa99a8ee10f2e841ddad3d71df3f5118f7f4af1dbb0bdfeac63f837276cf17c3de898eff777c2628ff92e1c104ffc14b8d41ef3b1025b0dfbcc7ac73c3e46dab706f59ae77f9a0edb57c2458cf8ad2ec1b648783d9805e112ed85938eb9bee2f89952bc35983f18afac48257f380697c6737dbd07d6925f59d897d92c817f76c239da570b1d73bd865e79373eb0372f12c997ae8533c7e31315e0d261bd6b0bb64902bd13e1141cf68487f6707e91523c35f0075be0d2a3bd06f3bfd0c37c0ffa147690a07f2bc271c2f655a7c20958e3fe92f4650e68bfa4f6311fd68583e77a83fe94b69772ff422edc07eb256179be81bedaf894edafae3b863fda100e528ff544f147235f9813b69ac7c36f0a0fedbd05ebc4637e2f828d4d311f2a6187e7551c2f534bed633e0f3ae6f955cd085b3c5f15c2f23c03fb283f87be3a051b9db21ed186b0c1f34daf63c4d76fc2625f40bd1bda6360bf3345caeb57af0a976077262ccf53180f4f1304fe240397b9c3fa2fc13af6c8372ae1d4f37cab6ab0c952f8af2de13c45fe7b2c2cf678d81b687cb8be9aeb98ef57e85f18e6031ef7079de179410b1760b726ec615fbd2b3c8cc7987fc12429e6a35c6f52d8ebfac243fb39bfcf283e68e41727c256b3fdf51d98261ce2e78db0e423cda1b03cdf1c81cd20657decb4700c7ba21961b1afe1f99df54bd9fff900d625d64f7d2b2cfb41bb0036bd94e79fbb1ab2e44743eea35ecd0b8b3d86e77336a0fef2fcd691b005d7fb605d069eaf36160e29c61bfd1f1889cf15fa1fd3fdbc1e1dae8f8b1ed64738056b9b223f38177629d6e7a2b00757d083e24b89fc6b7bc81af6ac81354d48ee4f2e6cc07a59589e1771fc26b16d09ff8b7a7280881f7613accb14fde90f39f078a83d61795e74d531ece3f543db7f5ba23f165cf4319f6b0f2e4bf8ff0af38be249c6fdf14bc205daab311f3293ca7ce3f593d1feac84bf9915b66087f9969709f63b167ae63acd588fb0de31fcd9957086fafa003c9c3f41da377d8f788cf129749c617e15c289b4b72e6c305fea29f0707ed43bc272fea16e8435c637c2fc29a93fc8571af070fc2cee2f752f433c5c10ee83fdaaf000f6d9a98e11ef94b0f88faa272cf6aa0361895f8ee333c9634be43bdfc045867cc6607c74d9c37980b9150e19fcdd4ac7c8e71c98ec873fc1fcd634de983f524fe3c5f63468cfd080e07ce45ad866d83f3b6187f6ed64c7d8ff2f0b7bd4571b60ea3ffc1dd60bcd9e0ce7031bc2061c0a61799ef9d131c687e34146f1a7c47e06ebd19565067fb724acc11af73bdb0bc8b7e15f7c777f2a6c4bc4f363709967d8df1c0a1719f6df1c7f328a1f05d6effc90d19e9d03d384843f48c025a5645c7f2e9c49fb331d637f87f5118cf87bc5ede5140f0ae45fc7e032ce309fbc7022edf73ac67e611b3c6cafe2fd55dea7f6906f6e758c783703a67c14fd5b16ce255e7e0797fd0ceb63af63c49f203c407d75233cb497e3594efebec0fa3ee818e721c71db37d6e09dcd9a385430efda6c0654f9ebf232cf668f60f794c1e18e7790d98dac7fc883b86bea9b0c37ec916c201f3235a1c32f6efd6828b18d7fb65619763bf3a27ec61afd61dc3ff61bc639a2e887f99b0c4db0ae349fba182d75338eb18eb7152d816d87f45e0c2e4385f3817b6e0ea5258ecab385fcf293ea1fd68b763e42b0370a173ec6795b001d7b02fd5e22f35f4a6d99de37c6f1e4ced61fc67c1450e3d8c152e725e9fe158b814e6f59753bc29902f9c760c7bce3ae6ebab0b70413390f5f92e9c205e994c38c3f3c36ec7f06713c2629fbe13b6381fada53d2bfeb3be141e9e17b07fa2db2924727f2f846d81f9b0dd31fab3062e0639fcddb57002ae6e8553d867a06fd94608e669308d00e2f391b02d10dffbe0a20f3da24be181f0b57002aea16f69ca80f82eed1be3e12f30ff75ebf1f8fe044c3dc2fe77c8a5e43babc2628fc27cd4454fc6e75bc7387f3e13eea3de34c219d65b8dfe6b1a6fcc37cc3f43191fc61fed9bd683f0f38c7029e3150b6bd8ab4b6103aeacb0cdd1beea18f17247d8497f0f85bddcbf2f1c440fe86b28ff80def0d7965618c64709e7d89f4447c216f65adf31f2c93d61797ed8e818d7633dbbe1f5d6748c7c95e357ee2942417f5cefc91ef84bcc5f5fc8f977edc0d441c4132dec02eb53237e043b7cff73212cfbfb8ac7977657bd00fb78fd16833283bf8c861cf0bc6a00a6788578cdf61671d117fff60ddc1e40f3f30cd8f8807ca300db019e57b3ff2912d3c37e5b796123fb4bf6f7454af914ce3f26c05ace0bab55b0b1b0a7b9010fd7bb5b161e60bfa479bd9237117fa3378453ec27940593c5888739d8a6b037e27c97bc4f8c786bb6840dfc99823df41fe2618df60a4ab8e09f607f31b42fe2f853e8cc15d0ff02dc8e08fb872b70d9c3f9989b128ee5fdd38e70827cb3867ddacafbbd0adca617f0c71998e603f67f1cbf29fa380d7bcfc14efca741bdcf7d89fc19e347f34ff2b1184cfd41fe9a0b67182f0fbd43e144bf13b0ee1b9c8770ff283bd025f4ef818b52ce1753e180fc4d6f81494fecf7f979e5c0f7d11fc3f1ba8c8b42f69b0598c607f6a2bdd85a591fdfc04ef61f11cf47cace64ff1bdd80dbc2d74f82bbf593089bc0f3a139003bd99f79d4a77e20fe3a12ce03f7dfb3fe65e6fab8dff17a2929bdc17c8e783f531614c1b15f6cc03641bd7760721868ef52b8005b8e2f659b7e23ff89c1e42f10bf614fd9ddcff1b6342e0988371bc256facbfb97d252ffb1def6c1c37a7f081e3ebfe678513a27f96df0605fa2deb1bfa4c5d177d85fb23fd13d97cbf3393fd4032ff351b13d3a2e5399ffa7c201f33ff0fad3094d67d6b769c07ee80fd89fea94aec07ad8025b07ffe4d05e460b127a737f74ee4af1576b602ffa46bc7fd1b47f95f7d99c8fe8d248bed568b08ba17fcdf995d6a6c07eb1417fb597f957b33fd6c618f80fc7f1535b6db07faff6c056fc690d7b6d670faf4fedcc00feabc678382fef87235eff9ad6a7c7f3399ee8d0d5b33f313d6df1bc869f4fbbfde1f956060e3de8a778fe98587b5caf1ab0d1785fa327c014de70fd9d7001f61c5f4da2538cb7abc1a12fed73ff4caa03decf361eec25ff0e3cdf4d467ae37d0b8faf298cbcef753fc0c3f5d4387090f9e4581f53ea58e65f104e608f9a06d37ae0f9b68ee7e9b6b0fd9c0f18339c2f01fd25f9f03ed0a33f966600f2558caf25ff85fdc52298ba83f5b2020e325f03c6c7d10c843d5360ab114faa6530cd4fee6f7d02f6e2ff3dc6cb0f9f1fe6c17407ec63ff677ba57c7ec171fe6bfbb68ff77d35cf0f4bfe52de9f4f82c99f81f9f936b131de87ba79b08f515f713e6e531a7f1e5fc7f3d1e6a40fce43a6c1d47fc40fb49707590f81fd2f6d360de69367ff6d8d91f7e58ae72379f341c0f9612e9c811b8ebf34bc32bf1daf77ebc9fff0fc57ac970ded01093f6f114ceb01f9c10138c468afe6fd0f4547c9a71c8f2f79ef18fe41ad08e7c87f1de7ef6e40f317e7edb760d393f9c0fd27ef90a27dc7f6bac4c9fb253703a6f1c4f50d381468bfe6f947d1463eafa378be533493f1d07bc2321e9af5a374b387f173ebe061fb6e4538113d6a618957ee044cf662be2e090f3fcfc4fec0918387fd8d0107890f01f6697a1ed6db9cb03ccfb11ed4fb4cfc31fb7b67e9f9e05d709078e5787d3837ac0fb17021f393f355b266587f2d2cebc5f1fc74819e87f5bbd431d6cb94b0dcef67840bb167a1639cbf046159cf8ae30745af3ee647e0f8e1076e20f1771a4c05f3695138169e142e315efe044cf319f38bd72f5d5d60ff12eec0a43fce4fb87f34ba926f079e3f3e75a947ffaec0d43ec687f3159f517fb93dcff3c7d30605f979fd15dc2684bcbe79bce8e9d23f372b3c40fc0e5f8563d8e3d93ff89214873e161c0cfae3797d90771fdacff9a00fd443f8bb6de1007fec6fc034bf106f589fd0a31e61ff6084338cb7af8425ff51b57090f970000e7d8957d25ed73eeb49b539f6dbfe5ab8407bb6141e7e1e83fd15f546cecbd589b0ac07c5fe2ac4743df68fb89fbc0dea35f79756778cf18cbe0b0fe31f38a51e201ef17a09198d20fcdf1d38c87af2e85f4e4f84fd51c7d8efec084bbe532d0acb7c53ac4f68f5c578627c69f6c8fb10f62774758ef9aa78fe92ba928f55bbc2329e6a203c8c57e8afa37af8973961e98faa84bdcc97ad8e713ffb0f22b93fac08cbfdd1b6b0dcaf8e3a46fec3fe24f07f88f7911a978f52c68a7db43256eca395b1621fad8c15fb6865acd8472b63c53e5a192bf6d1ca58b18f5644313d2e1fa58c15fb68e5b72b669efcc646eebd7bf999caab14f354feea1a1385f7eed3e72eaf50ac8aeaa889f6499383f7b6fa4f2eaf50cc4487d11195e3e8243a8dcededbf23fb5bcca2b9e4717d16574155d4737d16d7417fd8826dedbfe3fafbc32f398a43536154d4733d16cf4359a8be6a38568f1bdfbf06795572ab6448a2d472bd16ab416ad471bb4debe459b6f62d9e39de3afded37edf8abe47dbd1cedb8edc7b95572a66a2dd682fea45fd6840bac5a45b12a56f6259c6a5d5003ffdfcea9cbf42b1222aa36d15bdfdd8bd4f79f57eec9856594f29d26b45e9684d1965dfd0be91d5a59cf22aa84ad5aa51fbc37a75a00ed55147c7ea84f43afd7b47f1ef2caf534c9d4547ea9c74ba60c52ee9ebb2ba52d76f66dfa86237a4c8adba533fe8fbc4b05e4daa2935ddd18c3a52b3ef31927f57798d62eaab9a23c5e67975b58a2db43fa945b5a496dfc8be51c556489155fabe46dfd787f56a63e46aaa51dfde6324ffaef2eb8aa94db5457a7d57db9d623b6a97beee91663dd57f13fb46151b901e317d4fe8b7dbc37a953ebc5a51ec53b92ade6b3cdfbefc9a62aa6cbf44479a2257b4a20dbc6234d0b6fdae9d6e3f485de9fab7db37a2986e9e5b63a357eb7d7d405f0ff5d1fb8eebdb95bf564c1feb137d4a6a9da9797dce0a5de84b56aca7aff8fb8abe56dff58dbed577bf59b551c5daf875ab27da38a6279fd683f4949ea6fa19fd49a3d9cf15d35ff59c9ea7ec704f2fe845a843fa2c753f2d773fade855bda6d7f586fea67fdf0e6d54915c6fe9efea486feb1df185cf284656efea3dd2aca7dfc653bf73f999627aa0e3f62451276a67a8cc23c5529d3df87dae0b5d9ac828f3eefdfabce525c5f4b131ad5ac61af7502dca342e388aad7144bbd6aba3b5c69b602a539b667cc2ff36e579c5ccbe3920b50e0ded964715d12be6187922d5f4cc49b46c4e1f697666da3bcfcd8519bfdb7e83f29c62e6aacd34cc3572f811356ecc6dab90b9d3973a6f737b736a7e988927d74d9a29336d66cc278dfeef599e2a66beb679bc997bb2764e28575c30774c7d43fb68b3c03f4fd36f17a3e94757cf9b5b6a65c9bcd5defa8f2d8f15332b6695467a4df2f74e2db34eba2c90175c9113c5f6eb7c57bb6036ccb7766f3d72cf26b5b465bebf771f3f5779a4d8b9d9a651de31bb2363bfa70bd3d30fa3d9357fbdc2fe4ce25b9f541b3c8a796b2636899cda8ecb6f29a38a9994f4cad4885e3a357934a204952956b2188d60a634b98dac7af09b3babadb16f79baffc795878a59673d29b67e3fe236a8795b3dce2b94468c33a743bff8a06ec74c29f590a3235bdbe6bdfbf979ca8862fb6d041bc62a52648232c3bdc79ad803d3b707d0d31edaa3279aedda637bdfc6895923cd3ef1fbaabfbbdc2b66cfda15f6e07463da9edb8b277a5d9acd761552fe3e497465cfef4fafbad2b3d7f6666495dddabbf7eee967290f14fb41233bd19e64206bb0930fbd1b8ffd36adae2978447b655829b36ba7ecb479e41df5a59db1b3426b76c27eb573efddd3cf521e28364f3e71b31bf32b64171d9fab4bed6407c62bc72e0c75320b7ac12eea11cdec895d1afec64ed25c18efcb7e537910c78e685c8763bc6a3646b340bb66d7cdd9c3ec83ae7d98a36c44cbf6db88669b5676d5768b5a1eefca7e5379a498ec81ed8e7d90e1db59bb771f9764cd2dd9153bb20ba08ca3f7703f6676cd35760596f6e4f653bef9788f32aa989c35f5ccdc031fb7ae9387ab49d4192865e34719c73469f6e0a49f32c904bf27c5dee633727f60794e319be96edccdbc5d528f33c6359bdb2bd274d95e3d52f2c2d8fbf348b3285eb655ecb59fbc50b6c44f2efac5cf973e69c1a1bcfd93ba967ee52a675aabc4ba97cf16b82de79c778ffe56685431fe3cdb886214bd1ebd6f3167f4d049fe39b64bf2d3bdb75cb5879d7ef3508c5a3d72d5abc7bb76b4ef76fbeee0df55ec2f46eef0b73d69d8e26b3e5bf2d327916d54ef8edd897bb293bd57ac7d23e6905bf4dcf9f02cde1e3f794356b86ecdd959b3317ac64fbb8225f185b40611d7a8d523f7da7765ca5db96bb2fac6ddca7cbb733fdc849b7453523fed66dcacfb3ad2ffd1cf10dc8fc09c9b770b6ed12dc9bdcb6ec5adbef8a435b7ee36dcb7e79e345ae736dd96fbeeb6e559ea99eb47af78c6ba176c536ec7edbabda72373af98eb51767fdb651ef87ea28b477e6fe1feb31df0833a19bdc214ae0f7fea06e26523522c7eb56289a3d8e7329aff18c7dc916775a5c7e7b395a7df7aedcdcb8ac12b7af23cde794f5f83afe4defa674ff27ca6e6f7fdc1d3278dd6f9434febca1f8f2a3672fde815cf28f6826dca9ff8674f8aee15f367ed5bcc28467667783766b7fdf923c5be3f3e15b63ba36f3ecdba283688a06dcf5c5bef2f5eab185974e9affcf5b077fe4614b8457dfbd91ce5bacf2d3ea3d8fdcf6ac6df510b3ffc848cc6e44f9f34e5a7fd8ceb3e13f9f049a375d4ee2cfdeeeba8620faf7f74c533d6bd609bf2737ede2ffc4cb1c8b49f9af272e6e4977807bdee971fee8ccda91fcd4178d5f991cf7af8359c86d873bc9331ed27f55f7f12dc8ee3badff0df86bd53277e73b4fefebbdf6adfe8f8ef2f2a76c2a3f2d56f3fae79ee49baf13b4f7478b6ee79c51e5eff0b8a3d6f9b5289dff57bea498efdf024d8935ff47d7c3aca2a7bdcbefda2a8f460d7a5afcd93935fca4446fca24e68ffd59e3b061bda3cd1586a75f06f29f6d5c76d6f4495c4b3f53e7b46b1dc93c7f4e54b8a852810051dcce39ae79e146c1b53827b4e81d1baf65faca4afd5cb8a3dbae219eb5eb0adfd9e873a34e1d1dbc5878a8583d0feddec328ff48add6cf310d268e3e78ab51addff1c8ec86f520c0bc781cfefc3697414cec2f9bfa3d8e8cfe1225c86ab701d6e9e1997db70177e84899714d35361324c85e930f3bc628f9e341bbe86b930ffac02237561212c86a5b01c565e546cf48a679efa826d9889dfc36a58532339c0a377d0fbedf9bdc57e7960e6dab3607b7e1fa7ccc4fdc96317c776ef15332766a3fdfb091b07b4b11136b40a9ff62f17c266eb8dc35678f10ceeafaf786d79fc398fb04d6b62c71cb56fc0cca4d666d74cdabdfb4f7d84ddd14f14b471ebfeec23ecd949ddbef1bcb674874dc28ef5a1f7dee3fa7625f4c320c421092f9ee8fcf515af2d4f3e4b55858c3f07bcd0be7709b959b341af8662780a6c3675fa688d9d07f194a1a40475d15e554a5fb4e7bf61273aaade7d543f5b79e6f38aa632956dffeea8ddffdaadcae94b938775e48c94ef8f668f0b9517e5562b154dd96d3b11f648378a8895adcc33ff86ceb8fc7f95173ec5bd5f053ecbbfaeaa90db63cafe66cc0ff846bd50d59d626b94047194ab2aca0d0755138e4d6137abf6f30707d1d27bf7ee3396973e775f1d5487557b367ce4cec9275eab79f3cd4cd92a9ad6b9edd9aa5d6766b73a6e77d8eaa23a7183ea94df5c4eb4f7546714bdc6abeb4dcacffeb6a53af783eaa2cd1ef96f26aeab93ea321c5757d5b53d54e7d54d754bebee8a32c5a3ea92a2d906aeabeee8aef15f49bc59f985bfd15caa7e5413ed27857f5eacaf26e9ca29fdf5bdfbf4b9cbaffe1db43eaea6ab996a56cda9b9eaeb50a5ea8e79b69aabe6ab67cec0c6e5f797f1bf88f9d1ca58b18f56c68a7db43256eca395b1621fad8c15fb6865acd8472b63c53e5a192bf6d1ca58b18f56c68a7db43256eca395b1621fad8c15fb6865acd8472b63c53e5a192bf6d1ca58b18f56c6ffe7d38f56c68a7db4f20ac5b6abc56aa95aae56aad56aad5aaf36aa6fd566b5557dafb6ab9df7eec79f537e45b16ab7daab7a55bf1a54719554699555795554651dd5aad6b5a96ded6a5f87ba7aefdefc09e52f14dbaeebbaa9f7eb83fab03eaa8feb93fab43eabcfeb8bfab2beaaafeb9bfab6beab7fd413f5643d554fd733f56cfdf5bdfbf4b9cbcf14abe7eaf97aa15eac97eae57aa55eadd7eaf57aa3fe566fd65bf5f77abbdea977ebbdba57f7eb411dd7499dd6599dd7455dbe77af3e737959b1266a54a31bd3d8c635be094dd5d44dd3ec3707f78a3587cd5173dc9c34a7cd5973de5c3497cd5573dddc34b7cddd7bf7ecb3967ffecffff9c7ff029249605a</data>
+ </image>
+ <image name="image11">
+ <data format="XPM.GZ" length="64211">789ced9d5b53ddc8d2a6eff7afe8d8bafb6242df5a3a2b26e6c26073b0c1e6603030311775d459020c363031ff7d4af9a664b06937eeddbd7dd8cb190d3c9454aacacccaca2ad5a2fffbbf7e3bd9dbfdedbffefb1fefafc455a57e53a5b8fcedbff475d7ddfeeffff3bffeef3ffe1984d96f79fadb72b958fc16fcf37ffce39f72ed37f59bb7a07f230b090e536947aedf83e3454adcc4cc41aa88df8293384b462e51df7294917531333dcfe899a391fb0be66091d2fdddcc39b5478043a9343d2f0127220f47ae0e66a672bb491ccccf0f98a385a1e7dfce4cfd312573bca4ebab1b709047929e7f058e624df7d71e7138d56f5e33c74bea5fedcf4cfdd37bccc932a6f2b73393be04d717459aeef76e98534bdc3c278e167940fd15dbe038d262645513c7537bba756627541f9e1fc7a1057f648e2c3dbf78c62c603f017b27716ac91e35fa9f2452c03fd0bf343696eca3d1becc9993daab0f66a6feb7061c3a071979489995407bde8093c0527f9cbf8e9c2799857f1d81f34490bd0ad8532cc388583d678e62ea7f0bff128189a83e2f0727c6927f54b097742da4f61bc12c02b4ff14bc4c622aef72e634a6e7896370b2d0640f8feb4b1796fca34999554ecf2fa12fe52c4ef557b0b75a6609dd5f46cc02f5eb8b8913d27f81e7a93410a4cfea109ca70afe057fd6ee7ad2af399b99da6f37986542d79718bfc67914c623fcc304cb14fe037ddac97fcc4be66c41edad315eec52a5e40f0dfccf067142e3a5de624e62ea7f11cd4ce5cda772ea6f35dd9f24545f4dd73b678ee14fe71e385439b57f48c0512cd1be1de2a56b2f5ddff5cc7a41f6ae8fc1810de01f161c85d087b800a7a9457b5e11074196215e24cc39c64713319b88eaab17c46ebc433fdd005e0688072603073223fbe82d669dd1f3ebd733633c7c003b7727fd191a3fcb68aabfd2cc7249e5568003cbf1379d19e397ef770187f461687c2fe34582faf44b661390bf14efc091823dab33701ca5d4de06fa8cb338277d598a57cb64912ea87fdd0978ea7fabc0411c12fb57cca9a0f1edbf9f5852b9857d9230c5f33de82f71d311ec03fb26792c611fd4972eb325d567b698f592ca2d739007e84f090eb394f42360df348915c6eb2e71b6b021f9e3b90f8e6241fa1b02e61cfe372c99b522fd0f31385e2a7a7e7107ce22f4afa2f8bbccddfc42f557b83e0f35fca3417ff398edd5d0f85dca20827d9a0be61cfe27d03fe5dc97f4d3d3fcb2d4ce1e642fb3c99c2de01fd0b776e104e5f0371d45d047b5cd9c48b48febcb2dfad7b5c466ca17d429789905a86f9bd940ff25ea37c122a0fa1bf89771fd833d16cc6e06a7fb51bf751190aeef611feb2c48cf3307e04809babeae460ee678d16bf028a4ffd7cc7900ff38014722453c7ac96c73c47f8a37c1d26918f1f42d3832189fc3021ce79af46143e220e4f8aa9f8163b6b7a5781284d3f38b8d8943f4ff141cca08f94b078e6c46f655349f0751b248489fb265ce158ddf86fc3f889739f4dded830311128b737016c13f348de7205908c47785f6272e01c178d903c721e70347e02cc6fca61be2746abf45fb52174ea9fe8ef2bf209be68fe616ec7a8cf8d9316721e9ab78c99c839b43702842aaafbc032701f2d10a9c0711f2a7fe9c5940bf2a6096182fe7021ce5983fce0d385e62fcaa04ec020ce9bfa7f9c8d5c6fe63d79855007fa3f813483723a2bfb09f9ce25dafc0d3fdda32e7f067bb3331fcab7e074e2cec5940df32970af337fae39e8efccf423f7a6a8f1a989d90fe6e984d007ba1bdc6cda8d47f75019eeeeff666267b961f9935f4670f98b93e7bcc6c61af0af63791413ea3a13feb84ae57e733c37ee4ffe1c2cdcff4fcfe2378aabf4fc16180f9a2b9668e436a4f4ff673d32beb7738032731c66347e32f0c26ff6b0bb08b37c85f02706210dfca3d662b114f37c199c6785134bec230cc63c48f4b709262fe6bc97fc2688a874d0b761e8df5cc16380cd0ffee0d7314c2de132be46f0acf8fc70c82cab7c1ce5f10ffcfc1ae98b8bc640ec0da9f38a4fe58f2c73071fe0aff7b0b8ea2989eaf1a7026b0be52a82f75e518bfd05f1a8711d55f49e61cfaaf717f9af37cd7e1fa6cd28767c12e9fa1e7f5b07fee32506a8f3a018f3da2f1a9c16e0287ffa2fd224ce10f3a0447594ef6286fc02efdc47a92e6ef508e42f5a1bd32ceb15ef4283e862a3698cf15c5a350bb8c81dadbdf81677fdc014ff509e84fe71c4f8dcf9c6a6a7f710b1612eb830ef79bc91feb53668b7ca92fc1933ff7f007333dafa4f1175a6159bf947f468b39debc064fd7eb5df0d41e41e3270a9214eba79aea8fc2e582f3b59899ebeb0e9923c48be623d87934e9cbe7fb238bf59bbf04c791a0fabc8239c7fcecdd32b3be053f2f77038efc69002b9752d0f3717d34c5575b8133857c4f1ab0711e43e38fec1b8de38158401fb18943f22ff99e3909319f153323ff6b9853944b3d33fc93e6a728594aec1ff46be0c93ff6afc06988f5987706365148fa10cf996370fd82385df2fe4677ce1c2e11df279e9ef7013c3daf7c054e34cf17684fea125ae8b7069b6508fdaf3307889f52328760f1863902fb689fcb5f05f21bf853962c05f993b7009b05eaf7d39991af6f31f3f365c11c707bce99437007fde6d3f8e8517f3e0ad5ef81d304f9a73e02670b097f0bc0daf0f8dc9d99e283bc9a99f4e3bd60b6dcde7666ba5e409ff9dc9f8699dbaf303ec46c3fb44fb80885f96c6096bc7e50e064c9ebd71c9c6a83f9611becd243f277ef04eccc8bf6f63393fdfd8c597379c7ccedafe02f32e47cb3c2f874d96544fa9502ac73e457629f79ca17db99d11ebe5f4b2ebf659edab73133957bdb33e3fe8899db6b114f94b01af6853d954eb11ef2369933e6e7ccdc5e6f609edabb3e33cad798a7f6523c8fb44e78bdb4c3cccff38f67a6f21efd9fe3b142ff8d8b7f583fbd644e787e85bf1a9169c4130b760b2a8aa7a29c19fb777cbd8eb93dd5ccd8ff3b654ec096f299c88609f2890afe6465ae499f12cfb37a89f59c173207fcbc9b99a95cf2fd3ae472ae7f6a6f4dfe142f968ae3cf123c8d47c1ac17f027b1c7cccfef693e8c972e7d43fd2fc0caf0f56733231e1b66cbe5a7e0a97e49e32b0e94e6eb839911df7d66ae4fbe9c19f6407f02571fd60b787e38f5475e83958cb0dea3f839aedeb0bf2ab7c16ababe9c19f12f01bbfed3fd7e3e33f2558a3f713ce7e31b60e17a48f55d825582fde69ec677ec9623bc3f82e7274aa1bc237bc7e922c4fecdc01c2731f54f7d607642fe03fda462da5fbe00bbfec2beb05f36e50f6a173c0af91beacf04e7777501964a423fa82f534bacffe4167380f56c07fde7e38e3cb517f6cdb325f275f30a3cfb33f3549f5733e7e082e69b58b8152cde47a0bf225502eddb01bb000b7fe772a962bcefe07269b05f5cc35fe4545f71024edc8a82aedf044b817cb9c5f3d5b8c1407c089ee6effe163cd9bb3a072b37e352398df758cffb1368cf982f623ea1f11b9b291fd3b8de8c1918f933da6b5283fd0589fa8d5ac4187f28b7b33d3f8247a1fbe19fd6f51ffd43fdd6dd4ffed2d1f5c962da3f6d43668378506d829739efef6560b73ec57ee44bb00b7758ffbe06bb0534e663ae5f6a7e1e8dc76439ef17be6156d8cf6b37c093be9a129c8a8ccaf53e5824c87715cd2749b0cc16285f033b7fc0fe23da17a825fc5ba1be70149aaf2d38cdb1df3e44e03c3158ef51fc7193498ef7078d01c719d6cf35f96f12bb091af60427537e632578c9faed9f83dd70c67ab6004fe3b9b9036716f965017d27c2203e75949f24e9b4de1a50ff1c0f2a5c9f2d059ea7d1de2c54f0a74180a7eb75021e85ee4fc12efda6eb3b5aff24f964afb267e6fa05fa9bbb018af1b7c19c2758cf43bf221158ffca5db048707d47e33591537f349e27c394f77b5e31b37f77d08f9af4dbd5e020c17cdd1966857c485f8147217bd2fa2ad14180f73f3dfc5d4702f1bd5e07bb0535f68bd05f9d2b85f5cb0558e6e08ee26d62e67cf09299f31f85f61bb9d4d83fbb600ec03dc59fc4ba7c0df6a2f54bba1885f4b706760b54ec8f92fdd3797c78062c96585f898fcc01f693c501b3c0feab22fba7c12874ff33b00c51ded1784ae7f561b90487bc3f3ef8e0c97f24ea0ff325da2b0f9903f090814580f154bc05abdc907e2bf4cfad9e96e47fc539384f731a4fde4bb0ccb11f5adc809532b037eda7a5f1bc3ef6c0937e5af43776191cd967a8c073fb5f80854ea87d03f4398fc7b604a719f68fd516788e3f14ef52fa47f6eac179aa904f9e8145aeb17e79c76ca17f4bf12fcd22970291fd53f028d45ff21fa70c37e352f9022c43f61fca1752318d8f5a839310f9a6dc07e75c9fe672a1f87d32c59f548e42edcfc15998e1fd2cda2b736701aaef2db3eb02956f80dd048cf797e4dfa94a33c47b0dfd2b171f913fc560c9ef637ab46fde6fb12dd82564c81faec153bc1e3ae608f1a3467b759a2758afa27e2d13d4eff9cc06dc427f2659e0fd6339807568601ff8871506fad003b385fd7ceabf5b8d26e87ff902ac7343fa19a8ffd9726aaffe001e85f475021631ce535894074186f308ed11786a5ff111ac97a8df903db230e6fd8f92e6932c0a42e43355031e85da83e74542e0fdbe8ffb239965e8bf01ab0cf95343f1308ba388dfaf5d304fef5397e039bfe0eb8544ffbc4bb0e4fef6144fb379ffc4e4cc16fb4d32068f42f6dc002b8bf15d1e82b530c85f293e66f3fe887ec1ccf5b51e388991ff5534df6459142ec99e2dec97c526a6fb8767e094df870fa82f9fd840bff928345e8ec193bd0df96726e204fbb1839a18f163803ec4e40f82cb73cdf3fb0076ee0ffde0f97214f20f8a3f990a13bc4fa8519f4a8218f1750d3cb5b7dd018f0184f47bc6ac903f0d34fe333db7ef1c3cb54fc2ff746ef1fc12fad47a61903fc39f8cf357d2ef00fd98e9f932028f42f681bf19970fc33e14cf333bb54f79cc4ee8fe3db008b0bf65d15eebec8ff995e27f3ebf3fd0c760377f20fe6ab09bd161df7df028a47f2e770111f92ec5d77c39b5c7ac8347a1fe9e81b53188af646f37bba5c86fda6df0747fb10956acaf01f585937e7c051e85fa7704960bce5717cc09ce039c537c768b5183f757d573f018f0a93d0358198c97ea19d8c50bf8cb1e7384f866289fcde35148ffefc12e1fc1fa83c6639e8c42f640fd89d0d8cfd2645f373b3b217da660c1f393847d32b944fd3df491ab0cfbbdba65e6f9bf477bc4bcfff7112c6c8efdea03b05bee21df23ffcfe5bc7f0afbc828c1fcd99f32737d03fa2f47a1fab7c052a27e1fed956a89fe74688f9acf73dc8147a1fef660f700bcbf86bdf428c414af729ba4c877cd123c0af90b8d07b198e2bb4cc0a350fcd460c5e7537aeabf58c631d66fe51b668bf789ed0978aa6fe899793c979be034403cd49760c1fbbbd53eb3c07efe40fee0b247bedf328f42ed7d0e9621ee2f8fc17a3afff08159f07c48f14bccf9e270059eea6fd0bf300d787fee35585af8ff40f14144f3fd0378eedf5bb009707eaea6f5865bbce79c4fee821389fda106f7c7e912f1b3dd64d629f62302f02854ff1178aadf507e209288dfbf372fc06e3983fdf933e614f94c017d27ae7fd0d7057388fd057b0d1e85c623fae3161006fe4ce359ccf39d85fed251c85f29bf12d9b4fe50123c0ae98be653914ff9a9c8c032467989fbdd68b4382f86eb4524b1bfdcc21e225b205fb0f05ffa47fa82fd850cc01df421e7f519fa3b8f578df6c954e37c980cc1a310c3bfa5f32f70cd9ca1fe620fac2df453c07f5c7a87fca6a7f12d546291cf571178cc90491f77cc26c57ccbe5a390ff5d335beccf77f07f3defcfe4e071c798f4e383ddf8473c55e051e8f91d58c692da37a0bf5a717b15c69f198518f55ba71fc4175c6f47a1f661fc5915e33c664bd7cbc5647f7d0d1e85fcf38439c2fb13d9314b3effa4c1cefed8af22fbc8797d59df829308ef4bd53b706a63ac6f71ff72147ade25d8cd97a4cf8ec6bf0c2289fdcc72014e0ccec7566fc0cebdb1fea1fc4586b1c0f9a2f6183cc5b70afd09b304ebdbb6064b9e0f4bcb2c600fff155805d83f2bafc06681e7b5141f6434cddf03da333617fb6bd0e7bc9f5b1d81dd8a8dee2fb93c55bc5edc02cff9570a967c7ed18f9835b8d8071b61b13f85fa9251683eb863b67cff1958c7981f3a3c2f9dc69b3c058f42e5a82f9bf72fd7c053fe6e0d38e3fdebf6035844d80fb3d03725a4d4de43b0c9719eb8a5f824f3397e318f428cfee62e9e217f3f628ec02dda27a6fd27bf018f42fdf7982dd83e074ff7f7941fc9f9fc4d59816385f8ecc39fe91f8d27f45f8d42f6a4f82775b2e0f34ad09f1e5760a4cf0c3c0af907fc51bbf509e673d8635e4f36dbe0d4e07d94c6fd6614ea0ffcd1a8085ca1ff360b91af36e8bfcd79fd5a308b3cc7fbf0257814ea1fc6a78b07a84f53fea416a3d0fd3d73a6b01f790b76f64339f98fcb7eb214e741df83259f3feea83fead3f99a183c4e40545f041e85f443fea34217de90cf2fc0a350ff4be60c5c2ab031f0ff52ce8cf729a46f15e54184f5720a167c1e41e6e051885f33f379e9721decc617d6a3141fd4bc3f5436609751613f06fd8b47a1fade3127a8afa678a39234e3f9f812acf87df579c99c221f92cf9825f2ebe108ac39bfabc91f559a66981f1b1fec5668c8efa19f749affd40d7814ea0fda9be5fcfe42bd008f42fa3e66cec125f49319097d7494ffa8f97dbc417b29e125ff34e0f97ad427a6f950a1fd220b90ef0e2d785a3f29f48726586acf7b660dee613f39ad87ca9a39463e551f82a778edef322fa1bf96c6ab52f37e09b3e0f54d5b81c77fd47ef8e33c9f2be84f6702e7350a0dcea7f534c6939ee6678bfaf528d41eb4cfad8f517fb5c51cc2ff3b9a6f9499deaf34f047932f71dea42a9853e4f7ed1d787a9e87fa8d8ef13ec93b9819e393f235359fdf57f06fab387fa9317eadc930de35d5af17798cfc4e6f829dffe3bce00e7814d2470c76f102f6a7f8a3e7f7379d024ff9477b0b9edb9f8035bfffec48bf3a98aeaf33701ef1fbc3d7ccfc7ec07a60b782c0f9898439c6fb9cf686999f27d7c19ad7b325d76f34af0fc87f7428f8f31eb606bbf885f9e2043c0af927cd0f3a9ae24585e747b9c5fd25fa1b8900e711ea7de6e9f31721582e908fca1e3c0a95f3f52ebd407b68fcbae42f427dc573b09b3f90bfa17df128a42f8a973a99f45996e07489f9ac3d078f0756887b669edfcd3e73ccf3ffc0ccf97d55316bbc3f396776fac1fec02d73c2ef773bb08bdf8867343fea340d707eab28990d7f7e0afe986621f2bdfa08ec5620f8fc43005639faefa37de3720df323c5179d25d379635c9fa592cf1317e03ce0f38defc14260be53787e360ab5ff186c2cda5fa0bf7926e17fed0578daffa8317e72a71fcc17a88f360446161f9805f6eb6b8ca77cae1ffe2184c1fdcd26b3c5fb8e12fd1153fc920d7814aa8fe2b5964e9fb01ff42fa7fd8406ed9772897ccfc4cc7c1e5444e05148df349f699567c8ef4d0a9629e243710576cfc77af290d909d92764d6e096d66b5a4ff3810ffd68773fe2e707660d1e283fd2665aef9c637c1ad73e9c0719980d7f3e0ff1c8d805d6af1dc6a7cd05f667d4365809ac87ecc02cb15ef1d03f3b0a8d77d287594ceb7f4f80dd7a06fb33bbe051485fb7cc21bf9fa3f165965263ffac58825580f5b3770d1e85f46bc17689f6f7643f134ccf1f3699797dda28b05b2121be328f42fa5c67e6cf8714347f9b30157cdefb0c9c47ec2fb83e9cfcc53f058f42f75f335bc4cf96fcc344d37ed8b0039ed637e533b09b91719eb9053b7b53ff7ce8271a85cad79933ecef36d0579c5a9c4f6c5f80a7f587bf061e85f48fe7c73660fbc33e73fc1a609f64caffeb103ccef0a4ff5366837c569f335bb08ffe26a350fb287f3069aa39dee27a87d83f2a24d8790ce9c7db614ee01f7ecd9c8287b7ccfc7927fd0aecfa837c00facb26fbf7efc0533edd656037e3c21f73e610fb1b7a7d62febc4b3731f67ff41be618e5d54be684df17de4c9ce17df115d8b518f6289833e673e69cdfa7bd9d19eb05bedef2e7531be827cf0ce6ff16f5e7d37a499f80dd0c84cf03bd611678bfe01d810dbf8fa9e02ff954bfa2fcc8b86889f15eee304b8caf02f61066c9e7130f98f97d83f9089eeaaba18ff17d27f269e87bdc8f42fc43bca0051fdd0f7f9736c2fd25eca7dc7482f3f829d8856f9c7f92cc92eb0b9815f3cecc88cf7cfd547f41f99271c30d9f5f6a11cff4b43eea5f30f37a45c1bfb45960bd5ef9ccbcdfebef336b3caf013bf5603d3660bc9929bfefd01f976e211e298c17e32216e9cbde318758cf37cf98f9f376fe26b3c1fade427fc6f2e7971b8c0febc617f2a52573cafb23cf980dd6e7fe0533afd707f26fbb1833526aef0d33e753450776fe80fdb98a3943fcd025738ef597cfd78f42fef19c7989e7d97de618edb7341fb9525e8f15c9c4c88f8dc72cb87e3c7f9c1fb01ea1fcc506d37cd5a2fe609a8f6cc29c42ff7a9b59717e6bc196f7b38b7c66acff8e98b9bd35cdcf2e18bb849ceac7f5e3fe1ae2299e176a3e0f337c044ff387bf071e859e87e74722c479da42805d84c0fcd230f3f81b6a66f6bf612a67ff30cc76097d986262e8c3ecce8c78bf3133d6972d73c0ed9dca23cc2735b7cf26d04749f1c825ff013e3f509e326bec6736b05f2c96385fdbec31f3798ce135788a0ffd21338fef618b99fb579f33737c19b667467fe1bf6efec3fca49733637e99cb616fcdcfb37cdec1727b9c46911fb43323de4c1c733ccd98591f05f49d0889f3bfd515b341be6f717d328f878639823dab7662f84757cd8cfce005730c7fa80f6646ff878979fcc99961eff399e15fcf6786bf2be604cfafc299b11e3e9819f1a59c19fdc7fda9734fc44b03b6bcbf3fbc9b19f1e79079fa7c33c6732624f2ebe60d5886fc79d163e618e739aa77cc29d6470dfa9b2985cf6b57f037379a10af8a05d826189fbe66ceb0dfd6c0fe6ebec5e7adea14ac1618efcd2e738cf5c3007dd00b4dba1ee35da81cef2b1ac16cb03f5f5f30db14fe83f6d1060531e567947ee37d02fa4f019b18faa47f23ef5fade45715f24f6f25bfaa203f5ec9af2a5fb5aff4d513457eef7eace471f98a7d47ebea27cacac23fa87cc5beca37be7da214eeeaefde97957c295fb56fe9574f949aeddbb87bbe7b9f56f249be6adfd6ef1e48ef0ffeb97ff1d96f47b95cd9f7c714b2ef7b2757fef56765a37d2f1ec807ffa37fe3dffa77feb3cf4ad656f6fd3185ecbbeee4b9ffe2b332e56ff89b0fa4f6b7fc6dffa5ffcadff9aca45fd9f7c714b2efae93d7fe9bcfca94bfe7efdf9303ffd07feb1ff9c7fe3bffc495df2f3b5dd9f7c714b2ef999385bffcac6cb46fc022fcd08ffcd84ffcd4cffcdcf33dcf139e9cca3db5b2ef8f29f47e567bc6b35ef1599972eb1efc74e9955ee5d55ee3b55ee7f5dee09d7b17dea5f7debbc215def5cabe3fa6907d3f781fbd1beff6b332e5d63d074e7aefce7be6ad79ebde73272fbc0dffd8dbf4b6bc6defa5f7cadb19aff17657f6fd3185ecfbda7be3ed79fbde8177e8bd9dcb9c7dbd2327c7de3befc44fbd5367db336fe12d9d6d032f74e338f2622fa16bd2957d7f4c21fb665eee7e1c3fa126c5a77d28e5d6b5b55f0b2d8c9f092b0a1ac11ba21495a845e3beb6a2133d5d33acecfb63ca685f712e2ec4a5782faec4b5f8309729b7aebdf42fc547ff48dc7867e256dc8dd9957826d6fc63b12e9e8b17cec61be3356e65bcb2ef0f2964df4db1e5bd16dbe2a55be77c2a536e5dbbe6af895762c78dd95d67d7d7e28db3e88db7e56cbb27f6c79fc5015d73b8b2ef8f2964dfb7e2481c8b77fec30c5ad1be452f4ec4a938130b37721b71e7e6e02d2f14639caec4520422a46ba2957d7f4c21fbc62211a9cb831f9629dab7381599c8a52fc7cf734aa9a496465a5938fb2e65292b598fd7c86665df1f5346fbca56768f94a971dfc253b297833c9717f2d2c5e83d6f5dbe1767f24a5ecb0ff2a3bc91b774cdddcabe3fa6907d9f8d3fc9b5fbe2c3bed74e76e5ba7c2e5fc80db929b7e4b67c295fc91db9fbd9f52bfbfe9072fffde003eb8ef615de2e4436f2b57c23f7e4be3c9087f2ad3c92c7f2ddbdeb57eba31f541ebeffbd67ddd1be075efa75c1f5eefbedcabe3fa67cfe7e7fb62ed9570c7f24728dbe9eaccee7fc98f2f5f375f2e469b23a5ff7a3caefdb579ecab395fcecf215fb9eb9b974253fb93cc9befbe2d03bf25bf753fbbddbbb926f9327d977532ee4725c2dc93b11c91371e8ca5796fe2984ecfbe8674eeed977cf3f91810ce5f8172d1299caa5cc9c8d37be77db57f2c742fb57f9a3727ffebd70061fff0299544a69efda0ffcdafdb7b2f00f2ff83cf06372cfbead5f29ab0a55cadc3f900b5f92857bbffbb23e55a95a357f7d3bddbafc1bae53adea543f921ad4b9ba5097eafd54ee7e33cad5bf5bd3df479e645fe1afa96bf5417d5437ead6d7ea4e3d733fddf9c597b3b05a53ebeaf95fdf4ef5e269d78df6551b6a536d4d44776fab97ead5fddffca7c853ec2b176ac7c5e55df55aaeab37ae6ccf65d352edcbbbcf23b43a5087eaad3a52c7d0a57aa74ed4a9a29ad4422d55a042157d5e36fe254fba2255cf55e64a72edebf1efa949add4a9d6b87efcaacd38f6b4d50551a92b5deb46dff332b9a63bddeb61a2e9f7fa5c5f3cfccd7f863cc5befa52695feaf7facacdc2a37d6ffd0b7dad3fe88fbe7d589bbed1b7eeeb9d7e065d6aa74dbdae693ceb17da7983ded45b9f97e96dfd52bbd1a577f42e95bc763fbfd17b7a9fbe1fe0faf91987faad3ea29f8ef53bf7f5449f7e6a81bbfb4c2f3ed17cd75207f80de2b30ebfb7e6ff3df2a4f87c211b79ea2c1ab971ece2b35cd7b14e74aab3cf67609d1bdf2fcdf8b7b85e8dba34d291323402c7bfdee4be16a6849e1f9455a6368d694d47256ee634c3f4dddc1bbf8ecfcd85b9e49fdfc356e6de5ceaeeba361fccc789a6df9b1b73fbf037ff19f224fb96febe5b1385e6ce3cf38ecc9a5937cfcd0b19ba3931b85f97d9309b66cb6c3b79695e7dd225be9b1db2efae79fde97773d91bb367f6cdc19725d3f7d9be87e6ad39e29f77ccf1e7fd71f61dcc3b73327acf03fb9e9ab387bff9cf9027e6cf17229281b3eac22c4da02fddd7d06f4ce472ac7b739f894dc23fa526fbc286b97563db7a567cfadda7ef565a65f56325f7ed6bc73f61594ccfb3a5ade87bfda90de375b6b1aded6c7faff6c19edbd5fcfb7bf6b5fe9abdb4efddf87dae237b65af4d2417f244edeb6befe8535df683e5b8680a7b636f1f5ac8ded96776cdaedbe79f7e77cf022fecc6c3df3c6adf4dbb85984cb46d5fda5776c7ee7e6a035ff7dabeb17b767f9c6ded813db46fedd1548efbed1723ffd79427d9774f44f69d3d19f726e5d25eeb4b7beaaff9b57fa2334ffd353b95f6cc2efef55a56f2b93c71fe1d3f6936c6c2ced9d5c565ffd259758f3e57f617ec44dba50d6c3866532bf9abe589f69d648cd4918dfd8befddee953c4dbed1bea3858395757f1ef966fbaee4a792957d7f6df976fbdac4a6abb7fb3f8b7c9b7d6d66f3c22fbc427cef76afe469f264fbb6852c54a10b53d8a228caa22aea3ff7c495fc3be5c9f6dd289aa22dbaa22f86e2bcb8282e8bf7c57fc83bf29f599e74fe8aa5b82e3e141f8b9be2b6b82b9e156bc5bafbddf3e2de9b77da0f3c2c368acdaf3db3d82ab6d550bc2c5efdd956ff5da7449e2a4fdfc57ef876e4b1fba61dd362e7ebf516bbc5ebe2cdb7b6f4e9e79f9d75f78afde2a0382cde1647c571f1ae38294e8bb3e2debe22da572c8be0f79f58844554c4ee7b52a445f6e7f4fb779d1279aa3cddbe3877f275fb7e7e35eb297f785de97f7ab3f27479ba7d4baf14a52c55a94b53dab228cbb22aebf2c128425bcbb6a4f7c28f9daf70a57dc9a72bcaf3e99d5d79515e96efcbab2fef7a780684b5f0b79d12f9fcee07bdba2e3f941fcb9be9370feba32b6ecb3bf7f559b956bac8563e2f5fe0ca720363f4f1dedcb7ef34dacbcd72abdcbeaf89f2e55847f9ea611bcb9d72b77cedbebf29f7fe35fb96fbe5417958be2d8fcae3f25d79529e9667e5a25c960f462a6b222c493f8f9daf70a5f1e4877a39bd731fdf1c9649997e79d7c333207cdfdf764ae4f3bbeff7caec94ce8a653efde6617da3547ee5b9afa29295d287951edf417f1e9fbfeccd149f2bf3e9eaca3ea609eefd8336564555565555ffdeee3dfdff619ac7e4be7dabb6eaaabe1aaaf3eaa2baacde5757d575f5a1fa58dd54b70fedebda79a7838a34ffd8f98a87f69dcecce0cdbfdefbf2ae87e73cf8bebfed94c8e777dfb76fb556ad57cfab7bf1f67e7d882bd54699559bd556b55dbdacee9de7fb54d397bd796cfc563b8f6902d73c6ca36bd76ef5bafadd7919ff7fa2c7e4817df7aafdeaa03aacde5647d571f5ae3aa94eabb36a512dab2fc66f15565115c3e33f9dafa812f2513742ab6c8acf553ec567d8b7f63fbfebb199ebef3c25f2f0eedaabc538dba0ac96b5aa756d1eaf0f52dbbaa8dd1d7555d775f3987d7fcfa60fedcb3d7d54139fb5b1adbbbaaf87afd9f78fd647f5797d515fd6efebabfabafe507fac6feadbfaae7e56afd5ebf5832c679a7feb17f5c6e3e72b5c6d9bf556bd3de657f5cb9a7dbc76fe5aefd6d4e287773d62dfbff194c8c3bbeb37b58b28f5fe58561fd487634caedf3e5e1ff7eda83eae5d4cad4fead3fade79a07a512fbfddbe8f6be2611bcb377550877554c7ff827d933aadb33a6ffcc66b44231bd5e8c634b6299acf6a9bdae0c27bfdf8f90a2a6d9a560d4dd7f4d35dcdd09c37170d9d9b7b78d7971af93b4f893cbcbb79df5c35d7cd079a6d0f9b8fcd4d73dbdc3d5e1ff7ec99eb8b2b6bd69be73825862b9b17cd06f2ab6fb2efa39ab8dfc666b3d91ae79766bb79f9e7eddbbc6a769adde675f3a6d96bf69b83e6b079db1c35c7cdbb66fc3bd08fd6fb2df2ef3b13f5579f12f9f14f9d3c6dffaa396dce9a45b36c82266ca2266e92266db22657d7fef0afbf6bf8f7d8f7af3e25f2739c3a79e2fee466ebb75e2b5ad9aa56b7a6b56dd19632682b7fff7bf760255f93a7bf5f183f51260edbcaacb5b53c55372272bf59bd27fcc165f57effd796957d7f6d79ba7ddba66ddbaeeddba13d6f2fdacbf6fdf76efb4afe589e6adff6aabd6e3fb41fdb9bf6d6fd77d73e6bd7daf5f63bbec359c953e469f66d5fb41bed66bbd56eb72fdb57ed8efbbedbbe6edfb4bff3d662253f8a3cc5beed7e7bd01eb66fdba3f6b87dd79eb4a7ed59bb68976dd0866df4bd7bb092afc993ec1bb7499bb6599b777ee775a2939dea74673adb155dd9559f6a5b9ddf78fccaafbddfff2bf4f1fbf214fb7675d7746dd7757d3774e7dd4577d9bdefaeba6bf7bb0fddc7eee6f3deacce6fdc6be91f9edff833faf8fc6cc7efcb93ec7bdbdd75cfbab56ebd7bdebde8369c6c765bdd76f7b27bd5ed745f7c3a73757ee35bce6f7cab3e70b6a37bddbde9f6bafdeededbc93f6ddfc3ee6d77d41d77efba93eeb43beb16ddb20bbab08bdccf71977c61dfd5f98d6f38bff1adfac0d98e8ecabaacfb8391fc14fbf67eef3911bdec55af7bd3dbbee8cbbeeaebbee9dbfededfe0589ddff8f6f31bdfaa0f9cede8fb7ee8cfd5d0ffc167fd9e64dfcbfe7d7fd55ff71fec813de83ff637fd6d7fd73febd7faf5fe79ffe07ceceafcc6b79edff873fae837facdf19a3fca049e64dfad7ebb7fd9bfea77fadd595ef76ffabd7ebf3fe80f3f7ffaeafcc6b79cdff873fae8dff647eeebf15f62df77fd497fda9ff58b07b2ec833eec1fac7f57e737befdfcc69fd3471ff7499ff6d95f61dfaeeaf3c11fbcf17fb430fe69b0c10c76288672a8da78f80b3e85b43abff1f7e9e369fb934333b44337f4c3309c0f17c3e5f07eb81aae870fc3c71fad3fbf2f3fcff98d7fbf7d9d856f86dbe16e7836ac0debc3f3e1c5b0316c0e5b7f7ddf56f2d7cab7bcff1db68797ed8be1d5b033ec0eafbf77cb57f21459bddfffb5e52bf65dfdff717e01f97dfb4ee257f26e7833ec0dfb2bf9f9e409f62d3d652f8737265ac9cf277f6cdfe1c0efc6ffc3afec57f2f3c91fdb57ed390b6ff895dfade4e79327d877253fb1acecfb6bcbcabebfb6acecfb6bcbcabebfb6acecfb6bcbcabebfa60c87c3dbe168385ed9f7d792e1dd703c9c0ca7c3d9b0189643b0b2efaf226ebc8643e4ec1a0f899360484759d9f757101789b3217723d68dd9737f48cf3d27e25c9eab957d7f7671b68dcef5188fcf0dd9559edbf3e2bc3cafceebf3fa9fffef7ffee3ff03a588314d</data>
+ </image>
+ <image name="image12">
+ <data format="XPM.GZ" length="33962">789ced9cd9521c499385effb29641d776d63f1e7bed8d85cb008c4be0a016373e1b1b1ef3b63f3ee13e9c7ab4449a8ad9128e8e949dc54c54746c672c2c3c3230bf4af3f3e6caf2e7df8e35fbf5d5dd3f581fd60f7e9f2c31feee6e4e4e13fffeb3ffefbb7dfd3bafa50171f8a3aff90fdfe6fbffdae4f3fd80f2ae1af8ed52cb868ad6136e0b2b081cba7c2c1f1fd34cf9c76d6b1db1972c19c096749c5f5cd80cbd4fa8e8365ce923ca18eed8d7099727dfe2b737b7e81398f9c73fd4eb84ab93d7f32646ecf3e30174993a17fb85ea749cee3717b032ef83a3d3237695a945cdfd990b93eda666e9390b7cc0533a565c9e5dda17055f278d44770593bd6d7a33d93d6a5e5fbab21737fc205b34b5dc5fa1be8195223bc09ce6297b97ed6274daac4b11ee633739a9409eb650fc1994bb97ecff3956683eb661a9c554dcdfde7f1a451df04f529614a79bc7a1d5c05d7707dabccc5b0fc8d7005f61a9c8586eff797cce5a0bcb5c294f2f83cfa5fe66903ff5b039756f4e3f94cab41fde6169cd6b85f613c55d483c7a758dfa86e651ddfcff39b36699b32ab0b705538f61f8dfe5196653c3e3d275ce7ecafea9ad95495837fa03d1bfb03ff837e362b33ccd724b8c889eb33ebc205f17834c6e3e208b87e9b08d719e607ecd302feaa309fbe4ea0bf835e216d33ee8f42ff43d53aacb723709d3bd65f5d751c1723c9f563709d3af657cdf397a55993c17f091cafc33f783eb22c8e90eb0b47e0accdd89fc38d7028580f5b32e7599b637e12708c1f3c7eb7c85c6494f17c84206c32d68378fd4435eb1cf3219c1705d6cf27e6aaf486c7e3d81f62e9aac47ae7781547d3623cee9330e5dc9e23619723be34e0bc29111f515f1b4b70fd7a5a98307eba075764a01fc78bd87b83f97737c20e1cd09ec9d31cf1626ac8980fe865a23f627daf0a1bf8a765ffcaeca07d7d2e3ce87f2dec311f6a1d3c983f75205c61be03c7a3ae77329e696127f37925ec33f63f83f1fac42668ff119cc790cbf7637e7d5d1bc4335e2f59883d82ff2c094bffdca57040fd81fd314f22637d5a706d1de68bf7a7a8568af66cce1c1d2c67bd34cf6f9ec7fbd95fec17e6a2f42deabb07d701f511cf771ea337d61fed81eb1afa980cdc90c57a67bdf3185eb09f59dc5f752d72ff1e840bf4470937a9c3759ecfbc8ed711ff76854b8c47ad80eb42e68bd7434e83fe5ae8639290e03afa6b9a04d70dcf576ee3759e1fb709cedb9cfd4771bcc85ded1dd6e32db8a91c8fdf2f33fbac4eb1fe79fde421eac17a06de0f8a181f52ccdf805bb0dd033715d6a3ba136e317eb5cf9c3585b47720dc18d4c7f1b2c833427cf619b8690db3467d65e95ae40b1e4c09f209c7fe17d39b06f1c3ef8263f7b0de787c05d58985ffa33f266ed7d0f313b8f11efec4ebb3b07981f8ea57c0956be1af27e03a457dd4824d8afdd8f1fa285c5b4bfce47caa88f11bf73b5e1f3199a9b03e8201d739f1fd3a01b785c7fec7fb5999c5f1613fc9c1758678a127844bc27c2f80dbd2737d8af7ff326f2bb0e3f55e16754dacbfd9069bc2703c711ccfcab20d189f677dca2a32fb8fe6f1964dec1fe265235c829d3089ff10eb59b64522f16a83998864ff811e267a14e64f81e3fdec4f86f52c6ddcc1b1bfe3ba6b1b69cf0b078bfc047a3ab2f077c7fb558c06c1623fe4fca40c6d0b3dfc1730c97ad3ec7f55d21a5c0f77604a02e68ff3d9987c9688df81db8fcbbf96f11d81a9813fd82de6a295fcc473fe1dbdcf627fd69ccf5635559efd8d78bfa8cca07d8bf68d6d1de233e703952d241fd568df5186fb1dcf7fac2c93fd77114cde637cbc9f57815a94b73c9f71f14b7eae0a61f2d08bf5a9b3783ffce5026c6be84b1cafeabc75e20f281fc7ef110f36853dea331c4feb224b13d6d3a6602a901fe81de1c1fd5bc246eee7f558979d71f96d701c0fe233fb475d75c6ccfb4fcd5fcc285f5389f614c78bba89f7b3ff28de4feb76307ebd2b6c3ceee7785e9bce78fca8dfd8807847ac77ed07e373e8bf8fe90de69ff7b33a6406feac39be3749675c9efda3e9f277e4bb67e0cef8fa3ad8e4a8cf727c8bc1211a33ebd3149df1fda8afec8cb9005382fe7aee5f53c5fec0df02382fe43cc5fedcd45925e73112b6284f19d878c937e7c0312141fec0fb4313e3450bbd78be9b362fa57e8ea70db902f1d7637c313f4ae1cf3c1f8d1db069c08d69b05fcf0bbb06fa3bb04da47de8eb3a63de07b7498b7c1be3f39df17c403f6f8c477c5a1e32d613c6eb07f55bb417a24323ff3f0477c6ccfb5d6c2d017bf6ef36cde384f2f51370675c1fafdf36eb8cc7e3c1360f88f7ec7f31b9f6e88fbf100e88973403b609e2abad8425dff75e58d6b3e7feb7654ee88f46fb9509729df56ae36908f9815e02c7f123dfdc107601f92ac7f3b6890d62fdf07a685b9b4a7d3cff2d15a9e8c5f12206e378a2e3f2b3e018e1b8bcc6f8429515581f736097209e59ce6f283324f912eb4b79dd94d85f39dfa1ca55982fc7f920d57585f3bb36606b02e20fc70f6a066cd9ffa88d0103fa10d85a5c27dcdfc6e336ce93f3c2b23f5a1e3ff1178ff71aec0ce2ef1ad844fdb0dff3fe4eb6223c8f208e9771776a03f209d6c32485c7f9546f802d410f074e9bacc4750b8efdc3fafa28dc7ae40b3938a6fbd8dfd97fe2f145ae138fdf94a5c9f07c67051ceb87debc5e391c72ffe80aec1ceaa34db04f03fc91f71fd374c6d7f93c60c81701e73b8eb7c6541ee7278ffec4e205ce2b0b609f48bcc7786d67ac2ffb9771f1388dfc741edc198f8fe7df84862a3cff390277c6ccfbad4d6a83fc9e1438f60fe749b9ee0de6c3f3fed97937d8703e169d976a8c97dbb33121c2f94f713ec3e924cfb729857d403c9a03c7f6709ee17863db36a9e0ffe7c216e755f3008eee80fee07e6a4389f5b80f362df261128ef381f9e2f56663be91432fde2fe2e1ab94fdff44d84abce378663dc97a346b43c6f8b7c0bec47e6a387fb42148fe64995dda19b77f060e05ae13cfa7cb420e561c6f5c0c3fd0872e8443c079ce824385f286e35d5c7d09e2b7657f7465677c3d8007e52daf675775c6f51d8307d7e954b891fc8ffdd3d5a66c31fe55b01be4fb25d857d0cfb17fb8980f231e11ca37a194fa79be5c6b65bdda1970677c7d193c2cbf223ce8df89700bf6bcde1c518be791de0a1b3c7fb4d09b9ce4639ecf1baecb2f79fc9ef323171d04fd31980f6b5be45b8ee73fba43d3627cc7c284e777664a38ae4066f49fbfb8bf6be041ff1de6c35b2bf7d7e0ceb83cc7271762bacced591e5f9cdd44ce478be0383f181fe7f73eed8cebff22dcc21f02af9f185c4c8de7774b605710fcdd81633a007f2261b9df4f8007ed39b497bb8a10ef4ae106f98e9d0577c6e579fdf922fa23e2df83702bcf0727078cf398bd1526c2fac578ca2838f49c140e06f385f6ca813f68f67f5f39896f6a1bec65bff66be0581ef5ad0b1b591fbc5ff8ba33e6476142fe6179ff8b6a493e6de7841bac7fda1196fcc9f1fa8c6a56582ff459d8617d7bf4b7ed0e643c1ee84bbe91e71dbbc2adecafe7c284f9a1096169cfdf8187f57961199f831e31db93f3532e6c247e5d0e19e78fbb21231f3a1932fc177a9841fd9ad78bb79df1750b1e5ec7f8d9e1b9bf98ef6ebad05f37649487fff01797e77cd387e89138cf5d083bf44797c201feac39ff8fd158f257753660c93f783d87d4b916f37d091e5c5793c2924f988fc2e23f6646d84a3ce2f51d32e709cf530fc19df17a44fd7175c8f37f0f0e29fa475b0396fc6cc0d1f87ef68f10d321797e31215c1ae4773938b687fbf78473b4af2be142d6c3a4b00bc89fd0ffb2bb83fbd70e19f9d3b97009fde95ab8c2feaad8ff239572ff947034ee2ffb7b88eb09ebd397c2c6e279e22938b687fd6661c8a86f59b894fdf14658ead747c235faa339bef2f1049f2760feda90c9f97f42b8c4fc92168ec6edb743463c65ff8cab2b93cf0b37852bdcaf1ae116fda14361927c8af3b3e8dd25f69f703064c4870137a2efadb0417ee9ec90b17f425f1b0deb7171c8387f607e5c20ac6f7f3f647cbe712a6cb05ec39970907808fff041f25b3b2decd1be47fb2132f6ab8921a33f4bc252dfdab556f11f69a3ad76daeba0f7f4be3ed087fa481feb9317d9a93e633b173a79f27ea12fe395137da5aff58dbed57723654e46ca8cde397ac7c93375dfeb07fda827844e9f2df35c2d937a4a4feb8f7ae697faf26debb3fa939ed3f320f6c905bda897f4b25ed1ab7a4dafeb0dbda93f4795b77e42e3debe9d2968fc456fc77f3bd17675a2539de95c17bad495ae7b8d7fc29ed3b8d16dfcd728ad94226594554ef95ee3d732deaf82da63db5707ea501da96375a24ed5993aef357e0d638d2fd4a5ba52d7ea46ddaa3b75af1ed4a39a50936aaad7f8358c359e561fd58c9a559fd49c9a570b6a512da965ce2a7a8d5fc158e315b5aad6d4bada509beab3da525fd4b6da895945dd6bfc1ac61aefaa44a52a53b92a54a92a55ab46b5ba22fd8b1a9ffec2bdff20e33355f7f984214b8eba07257bb44f07ea5c9dd3e1af694c47ef3dbabf87b1c6c77442a77446e77441977445d774a3a6d414ddbe5463baa37b7e7fa04792530f4dd2144dd3478a27299aa54ff1758ee66921be2fd2d27b8fff2d8c355ea6155aa5355aa70ddaa4cfb415f3b6b39fc9dde80b6dd34e7cdfa5444baca094b2f89a53115f4baae26b4d0db5461b65e8bdc7ff1686e79bc61a67ba079c7b66df1c984373648ea39d985373f6b2faccb9b93097e6ca5c6bd1d8dce00986b98ddfdf997bf3601ecd8499345366fabd47ff368667aa66c6cc9a4f66cecc9b05b348b7746b16cd9259362b66f565f59935b36e36cc261334fe6cb69e5cff62b6cd8ed93589494df6dea37f1b638d735398d254a6368dde322d1d760a5b6d957df15ab6c65aebac67628d6db07bfcbecfaf07f6b08bd9f6c81edb771ffddb183ffb3cb567f6dc5ed84b73ac0f625ebc157db88e0a5ffd4c8df6dade88e73ef32cd0deea531bbfb3f7f6c13ebef7e8dfc6f07cd94eda9845d86973683fea7d5ddb999f55b8b7ef0d9f39c0a2c647765657f69359e9157e3dfb4ee3393bff3371b8b71f1b3e7b1a985db08b76e9a5b9446f7f6e1c8f97c556ec6ab4d9f7eed33fcd58e335b175bb6137dfbb47ff3cc3efb5f4364eeb351ebff51a8fdf7a8dc76fbdc6e3b75ee3f15baff1f8add778fcd66b3c7eeb351ebfbdb6c6f6b3ddea6dd45e576356f84b6fa3f6ca1a4785bf3e29ed0dd66b3c7efbffaeb13e1d7f1bbdc6e36fe32735fec16f64f61a3f67e3d178fc3d7fad16de4a63bb6d77ecae4d6cca3a6536b7852d6d05356d6d9b78adedc869d7fd5dbdf9158d9dfd3b69f3561a3be77cd42f38fe9d29c7bf33e50edc21347647918e1d6be84edd597c3d178dbffb7d4368ec2ee25d97ee327e77e5aedd8dbb7577188fbb770fee7144f10937e9a6dc34c63a5afe1b1a2929e53fba1937eb3eb9b92735cebb05b7e896dcf233edafb855b7e6d6dd86db749fddd61bc68a53f7252ab7ed7658c75d97b8549f39fcc6df69f7fbab2e976b852be36bf557fdd8d5ae89afadd7f8a957fcd3cbafed777f8d1f5fad6836527e94464be2d53befe36bf07b4f6adcf707fc7ef84cfb47f1e7c7fec49ff2fbd95b6afc34cafa737ff144c7916b2fd5d85ffaabf87aed6f648cb7dfb61f4b441ff3f7a2d948f9efe8494929ffd0ad1777e91f476a9c78f2fd68fb9391a606ef6ee7dd349ef61fe3ebcc731afb59ff29becefd658de7798cf77ee1e94fff44e391f2dfd0731acffbc5ef6a7c78a2f1b3ed3f7d7f1f8dffecafbbfd925f76e457fe3c1ec751adfa357e5ff71bf175d37ffea1c65b3edee1b745b391f2dfd0484929bfe377f93d795263ea337e3ffc51fbefa2f1cb73b71fd850e3dc175dd4f5a5af7ced1bdf3e1ddbd3781c74e8fe07061338db182d3f4aa3255157f73f638410f6c2fed77ac341380c47e1389cfca8fd77f2e3aff62a1aff750ba721ee3ce13c5cbc5ec997d8ff5d3f7e81c697e12a5c879bf0dd6ef8f3257b8dff5ed66bfccfb0d7ff1c24dcf5366afde779e3b7fe73e9f15baff1f8add778fcd66b3c7eeb351ebff51a8fdf7a8dc76fbdc6e3b75ee3f15baff1f8add778fcd66b3c7eeb351ebff51a8fdf7a8dc76fbdc6e3b75ee3f15baff1f8add778fcd66b3c7eeb351ebffdfe3ffffedbff02e7efe704</data>
+ </image>
+ <image name="image13">
+ <data format="XPM.GZ" length="137155">789cecbd49772339b2b6b9ff7e459dcbdd3d7df8d167f7452f488d9c248a1445497d7a01c0dd398b1267aaff7c83785f209491115595b7aa6e76d78df24a851ef90418cc0c86d1fff77ffee5b9d7fdcb7ffeefffb5d98aed54fd454dc4fa2fff99ef96cbd3fff57fff9fffcffffa8f3048fe92c57f09829af717ff3ffe8ffff51fd5ee5fd45f2a35f3bf332f0f964571e643c3b24acffc3e729c99f3178e8539ffecd8dcfffe623937ef7b7f751c1aae398ecedce8582e4c7a1ab163efcc1747c7e6791727c7e6fe4bf7be429ef96a68b934f75fbaf797e6feab89e3c0f093e3c45cefd2579afc5f4d1d9bfc5f7d3b6ff27fe939c6fbbfbd4f99f3a1e3dc9c5f3a2ecf3c45febdf361caa3706ce4b5fcb42cccf39627c7e679cba36323ffc523d9af99fc7c541d9bfcdcb61d9bfc9c1439c0f9039eefebf234f239d41d9bf39f6fe400f7b78f8e8d3cde5a8e8d3cda13c726fd62460e91beb7dcb149ff76e1d8c867b4b2ec19fd78b7e98b3c23af37a42fa8d5a4b9fead6119e97fbb706cf4e5edca716cf8d2b1494f2b20b33c2a7b7284fcee2a963da34f9507728cfc6f95650fef938ecdfb0e28cfd0be6fd5716ce4bbea3a36f25bdd3936e5bdba776ce455b1d72790efb0424e3d73fdae49ce7c23bf55e2d8c8675f230b65ce1f208fc8dafb644aa63cae3c7204fbddefc9a96fce3fd9eb33df9c9fe379712df74c7aafa03f492dc9cdfbaf0bcb0538776cf4ff5a3a36cf7bc7fbd35a228dbc9675722accf5979165f89bebb16323ffebd231ec31b30c7f73ad1c9beb2bf6fed233f218f17dda60ccfdf39ee5d0e8c3b6706cde7f78257bbeb97f796539847f4a1d9bfbdb2bc7e6fdad36d90fa19f378e4dfe2ff0bc4ce7c7dcbf833fcbf4fbcdf3678aece1fad1881c207d4f25390c4df98c501f08adb1e6796fd7e44418fbba4ac9590e1e9125fcedbc452e03a38fb7909fd0ef33d71f78bd7e9f393f892c47e6fee706398a8c3eb4a1efc2a7ff5a0d0ccb5ae219791cf7e4d4833e8c1d1b79af7a96a579dea245d64f34f54ddb32f4f9ead1b1b1e7ab1959a2be98237dd28b23f3fcf93b3989e07f503ecacaef2a21ab1cf543c3329f87f42a2f8d0d372d0b3c6f744d96905703e9535a1e862f601fb97ebe29cf0fbc3fd7f71b79cc95e5d8f026706cd2bfbd27cbc8a4ef73643936e5f1ae1c439f676485f26adbe7a9d894c7e8835c403e5bf883427b18238fe59e5c08c40f4f96a5d1bf8b8365d8eb55ddb149dfa90fd6ef47fd87f717be97a0fe843f2eb5c5a2fe3a920bf88beb896565f2d3882ca3fc2f9f1da3fecac9a534f9b9467d5a7a359c5f0ec92a31fef38dcff7fd04f5db1d39843cd6157284f2696f2cc7e6793bbedf8f23239fcd856373fefd1b1bfd980f2dc7e6fd1fe6bc76d611fcd36a6b19fee5f000d6ef37cfbfed91d3c8e8d3dc948fe7690f0efbff2417d294c7aaedd8e4a731056b7d32f23b5e82fd3436cf6ff37e9ffafc16924bd617b78675f18526fd43a4d7f7e3c4bc7ff54c4e63939f45cf726af4e5ad46ce5293becd2b5924861b179653531e53638fdeb93e37faf1d4077b29fc4dfd9e2c608f27b22f13a4dfb79c9af2db56c8796af4a973050e32c42b5b53bf7ba17ddfa9424ee0cfe60bb2f48cbc768f60bf447e961958071026ff9d90ac10ffb4bbe41cefebdc900bf0c2d88717e91a18fe664d2e501f7526e040329e32faedc5f6fa954f667a572bb2f48cbeac707f1c8429ca07e94bbc14e7973d32ebff37c82309e218ed8d7b7212439f07e414f6b3447e74fdeb9be7cf66960393bf9689a7bd2cc8511e5790bfd087c9df66073e073c26bfb85f448167caab2b0ccbf361fcd706ec079179fffb0d3984bcae1ec86960d2df91601d8e221e42f9697f0efbd8bf923369cab78bf256be08119f9afad4cbb57c11efdf93d39a29ff679447eec59e91cffe89cce7cd2a648578fb12f9c9f5f351fe77e03096f04f253911f03f3d7289fab3c3f35186fa7566ea23aff052dfa46fff4cce98bf2159203dfb9163939ec6869c2bc40bb165c42b62422ea01f179f960bf3fc29e457f8351ff10f9fef2bc4471de8a7ae6d90fef6b56373ff13cabfd4f245fdff4c56c8df3be45b7a09e2e3d680ccf875f74616c23c6f81f22ac32c33cfeb34c902fab38cc80af55b1bfa584629ec7b69d2ef3b7fbc7f214bc86fadc021f5f973ead8bcfffd8a5c429f3746df7cefac9126bd05d88f61cff537b2a2be1ec939dedf32fae6fb5a23cdf305de67fe67caa36e19e57171e9d8a4f7f9444ed01efa688103c60b4f0d70e465a85f0a722811ef56c82cff4e0d1c87f01f7b531e7ee0e588df5a9fe4429ae73f46606d9f46bfdedfc9996feebf19580e4cf9ec37e028a0fe37c905da4befa6fed14f4b208ff71939f34d7e47789ff6c790df24046b8769d2df6e9363e4a76dfcf739fbd4ef9c2cd0bedd2dc1be7649676e7e927d61f47b3a200b94dffb9eac0273ff07af8f04f4ed6a4d96e81f78da92159eff88f289b5bf33fabe9760bf06ffb01d913de8fb519063b4d79fa76489f87ed303076c3f2c50beb17e9f91f7c52d3947ffc545d331ea33e8af8e5ea4e116efd70934cfdbe3fd891fe0fe66460e71ff3422b37c775db20c4cf90e67e43c30f2dc439f75fd83f6c868088ecacc700bf94b7406cdfbb6c6dffaba752b8c7c6e53b22f101f97e4c037cf7fec9013e8cbfe9a9c06465f871372067fb6395ac6f9e73559207e7b1c900b94ff159f1724a949df14e599eaf4a27d057fa25bf7e86f1856c9ec4f69de59c6f9db393981ff188564fafbc5802c604f9b7bb2847d1c727281fab8bd279701e2a99163d4b7d0b72c1019eaeb1639473c3c85bcb338813e740459a1bf62027f269c7dcec919d2db8e1d9bf3b733b244fc70d5242be477ffe918e53521e7ca94efe782ccfc3d2fc9ccdf23e429b43e19fdfb48c90af1c3339f1f4bb437de905e796e51187d857d486d91887fa7e404f979eb3b467fec0739a3bfef9105d2ff189225f46bd6748cebdb8ed11eed92298fcedeb191d76449cec117357281feb319ca4f066cefedae1c23de813d4b1d009bfc762796d15e69f2fad047bc3d4379cbb844ff5d670c4e24eae37713bffbeadc4233f246fe74e9413f9e956393ff75499690cfe7c6b1c9ffe30339f7cdf39a2d7281f3cd4bc7f03f909fd2e945fb05faa17473cda46f8df4e6670f61deb725b3bfad73200bf88be7dcb191ff634666f93da68ecdf9d91d99fafaf84ace690f3bc7e6fce4dd31eab7825c20bf6b94471e48f8ef0efc699ef8787f1de55f58f9ce3a64be7fda776ce435ad91999e754e2e0223afc72eb9843cdfeb96e11f3e917eeded22c4af7c5e58403f9e91ded2fa9f5d87ccf6cc342497c85f07f92db310f2ee5c920be8d3c2946750abe5e8bf7dec83831ae555216b076feeaf92a300f25e80c310fd11f32e3851e8cfedc464a6efd9d86fa01b98f0276f07709920fe7834f9d5e14c80f6f8471d1c4bf46f2e5b64d6e7ab35b940fd3d5b924b89fe109e2f53c4b75ba38f41a0c339638fb7277289faed790c0e3cc86fd625a79191dfe4839c217d9d1158ab3b58914be8439fac0af6371b7b0fc2730d69fc490ad6ef43fbae4af611cf4d1fc821fc6de7199cd5f0fcf90bb88cd09f300fc8ccef2338d2111ceaa7889ca2fc370732eb8bab1e58a7c794dfdb8363d47f03b20f7d7e3e92437077071621ae6fdf81650c7b7943f944650279ac8cbf0b62edcf8c3c6ea7609fed8f4be85facdf8ffa6447e6fb5a778e513fcec0a9c078416b03162c9f91f12f41a2e56be4d79d930370eb891c52be484f1271fce0087d4cd204f146e79a4c7b5ba23c92ccc3f844bb43a6bfe9e76099a2bcdb376481f74da09f494effb8447e9292e53532f56590d60ab48f2b13b0f65f267d1723b242fb74fb060e43b69f60df69699f6ffc6790e9e7a1be2cc1e71237cfbf2367b0f7466219eda191074e63c4a3ab26382fa03f6be44f5f0d5e415e5999a33c0fb03761f333813f11e788d2e81bf223ce2566f207fd15a187f6cb5b8f1c67d0ff07728af6d614e913518cf6d208f915698af1c2ee1bb980fe74a19f22b3fa0cfd112a4179ade12f4511419f57f01fa2a4fdac8dbf0d747cc0f63ae42d03c6b7174370e8a13dd7467a651a05a67c3f8ee4589afb17cab1c9efa9454e50be57ef8ed1fed991d93f5247fe6516a2ffa1439612fe65c2eb5500eebc9205f4f51de5294bc6f327d8830a14e2b72bc847a529fa3bba07b2427eea789ecaa21cfd0bb03f250bbcaf0d7d56e70103f3be477091c21e967332fde9bae9d894ef27fc7baeeb2b8c07c17e75eb9eed65e8579e1618af6f29c7e6799d3eb954e6790ba427cf921cf507fc7d5ee478df1beab3e2dcc36ee4e1836d7fe345080e03bcbf037f51c80cfab55e810bfa8b35caaf2859df7cccc921f46d69da0b818e96513f7fe27ca9c32f8c3fefc809fa5f1e5fc81cdfd923bfa52e71b467abe412e9ed227fa59028af0eefd7cd0d93de29f4b9d4f66bd2f301ff50daf44e8c3cc29a95c7e613ecd5305ebc1f83831ced9963177cbec2c8eb919cc01e3f6ec1bafe36f632df816d7974f87c51a23ddb7d07ab12fee163002ed85ef9183b46ffee0799fda71f77e0b2067d3c187985bab6417fd5f3829c42be171d7206beed3a467f4d01d6258eeb7d7018a1bfe722700cfd44fe3c99223fed16b94479acd7e02243fad74bb200cf368e315eb1254b9cdf9bfa26f48392e9f1c0363d1da4c71702fd0533a4c7cf25e5c9fb75f882f1fc377204fd78bf2727d497dc31daa3a6ff4b3bd31af4e31de78380fadd407acf68caff28c901fdf10aacc2c0f8c37908ce13a467983a36f2fb7800ebf4613c70448ec1ab4f32d3f73123d33fbfa3bc429d5ec4ff4f605f203edd97602d4f53de27e887fe1fdb63157012213e58bd9063cc2fa83e9025e213d5726ceecfdfc90a2c368ef13ca4374c15fa873e501e614e7fbb3a800b8fe5b5268790cfea8accfaa66bcfc738bf44794536ff6f437092288c5fb6c929daf3155eafd36fe4517d252be44ff61c9bf4cb1139477d906fc905ec5bf51d9bf775795e7ae8df6a0bb0928847e67c5f5e407f3b17605d9da37fbb430e99df2b32f3db32eda130f63c8e47e17c1c05689f2f50de719261fe4c352533bff99e5c623e47a5ef18e3610958b03f6b8df28c8b1adb4f5db28ff47ff4c821f3037d486cfa5acf64ce5f1ac2bf696b40bc71823e2421fdd70cfa962402f36d160bb244fb6cba748cf623dfa7cbcbdc5f1c1d9bf40b7b3e0717f0a749caf96d22718cfa04faada3658ec7c2bfebf83640fad6e492f9ef3a36e999a1fc132baf37be5feb37e63b30bf567ead77c7902f9e9fc61efa2b2bb83ed5e5097ff742a67c26b764e67fd2758cf6fd8a5cc03e25ec31d5e13ce633411ea948c16fd08f54fb53f3bc8f47720e5e2fc805b805f9a53abf869b1f8ed13ed9923d9e7f2607e00afc77a6cbd3f07844cea1af93177281f21bcf1ca33e6f914bd8eb746b19f62aa04f591a607ec81cf549a6f3639edfbd2417e41bc7688f7d904be4a739748cfe25c8473797909f29ec51587d5fc0be840eaf4c7aee604fe27c1879a3fe17511663be1dca53e8f236e55129c902e55f7d212bc867dc23531e6542a63c6623cb90c702e52bb4be1b2e078e116f3c3936feacd892b5c736fa5321c790e70cf5a3c87cfa7ba657c7ef8827e16f858a31feb1be24e7d0f75604d6f501e2c79563939f15efd7e585fe9a1a99e5d5647a6d7994286fa9fdbdb167794fa63f98413e32f598ffbe63935e693946fd7e91914bd41f9d395872bcb60b794ac5f95befd047a9eb77737f2b254bf29accfc8d10cf28dd1e30cfaba0be50da81c13f8dc92c7f5590999ff21aacedd95c5faec901e6e32c78bf2e3fe48fefd30ec294c733d2afb4c1a1be857c952873d457882f54eea3fc3a393940fe3f86e418f9bf7d26737ec87aeb18fab521a71c0feb9033707344e6f85967ea18e33d2b32e57940faf290fa7481f7e711c7c3de602fb9d607a3cf25ca234f3de4bff0c8faffc69e2ec811fce106e5916b01a23d7447a6be7ea03eca738e0fdff27d36bf1b5c5f04eccf6c23de29e232433c05fd2c6cfd34867c0bad7fe67a35212be8e307e2cdc2faeb35caaf5019ded7817f2e6c7a5a313906cf9fc909e4394c2ca3bcf6a67f20d4ad15d4cf9fc85f19e799d1af09caabd4e985bf863d9469067fa06ec9aa30f7cb577281f99a73f8ef526698cff90e7bd5de09f26d57c93eb8d3768c78d7e427aa7912f1ebdb8cacc0175db06efe9bf7579fc831e2dbf11d38e57c48c9e7a582f5c7a765cc6f5ff3f94a427ecb05b908112fdc82730fe93b1afd8a3c9bbe45020e22ce272ec0492dc37cae3b7280f163f548a63e4c1ec8ec0f98541dc3ff23fd5e9ac1ff2fdfc14a60bec5ea829c633eea724966fabbd78ecdf5eb0eb9447eb6a67e8efcb090e6fadb4fc7188f843cfc38498d7c9edfc03a3ff0478a1ca23d577f2647289f8904a705f47b7ab48cf9c502f2380f5862bc8ecfb3f9e906e402bc33fe4137a6d8de6943fe419ca526fd13bc3fb0f25443705ac2fe1b641962bee0a642ce311ff7bd07d6f686feb33959303db76489eb577532e7bf54501e3a0046ff46f5999c62fc523d9019ef4c7232fb7bc621382d614fc59563f8af1638ab613e74f748d61ed2e823ec21943eecf563025609e291f73b72caf45f3a36e9edfa64e6ff83cfb3f96d42ffc29cf3979b6bc7e6fa12e98d74fecdf94a871ca1bf65d226b37c66afe02c807e542c0bac2fd96460c1fa7c03fd88a4c2f8ee1ae511e9fa19f9e3f35504ee5e90391e5c853ec5890ffd7e176489f90cb947b6e5d307676c3f7c4cc12ae0f8f23d99f2bd5d9199be29ec25d1cf33f2b9dc82b302f1d3e51e2c3cc863d7278788cf36f007898c30df78bd23a7188f5b7f90738c17aef93e59401fd6280fdd5ac6f98f821ce0fc01e94923f6f74c9a60ad8f88a721df5470fc60097b4da5427fee479b5cf0f90b7289f91c6f9087d67e9c5fdd38c6f8b347f6919ee60b59e1fc11f2cda20cf303ef95658c6f2bd8ebb97d609edf28c122463cb4843c33571fdd9225e64b7fd8f339deb79196717e7d4de6f86717f699d9f46f4dfca5d55362fef706d70b3f467f7407fe45c7f3e84f2ce10f4456603dc501f2145abe98ef7e2087f007cd2999f9b9589213c483ed7732ebe79d242bc4776bf80b2163a4fff3dd32ec697524ab08fd1b11b940fe9b03b012b8ff09f74b5dc1e17db05769f39be379d296c70ce527850ffdcf4fe4b0447fcbc831e40d7bd7c583f9bf6f3bb2407aba35c7e6fc11f25691f230de067d53690afb3dc1ffe8e423be6ed5c819ec7964da1f51eed76a88f7509fe8d623e2a3ab5b32c787de511e7918a2bd5745faf384f3b5a63b32eda7f2e418f280fee4c2873fdf6cc912e5d5199273b4c7de217f1d0e47a6bcd75d728cf1df29fc5971eec134f529f459c78f585f778ffaa98c0a5c2fe1dfcb94eb95c6f07fa58850ff4e1be4b830e5b9b8b28cf2eaf2bcf22223bf2753be71ed3c03d85cdf2167987f38bb05071c7febe6e090e3c5ef2b32e579df00eb14637ca005d64f44fdee8353aec7da0ab0d62fcc6733f61f7bf67dcfefe030827f3bd5c0b1c7782d768cfa2101271efaa3670138a3bd6c917e4fdb23e67bcfc95cef2333b2367053be6f6099613e55b7492e38bfcaf8c3d8d7f233e9af77c802f3459bb8de0f395e3cbf036bfb47fa1e2da3fc8a3d587aa5d1875be4dfd7e585fadad48771609f57f6c0b1447c2aafc825eac371044e7df60f5f930bacff3a403e61ccf96bc72bcbe8efacacc812f323ca1bc798af04f987babd86f99f4bb0b5871ce51dd9f6ec18e5a71d1ce4bbb39ce3facd925c44983f84f2d10508f936666405fd5c55c839ecff7d030e39bfafb205c739da9b63054ea90fef6332fb0f04afd7f10ce215e4371605fb538c3fd0d1740c7f28209f240bd11edce1f9a927909efc039c29f88331f423d50ed6bc6f83fc67f6fabb1df87c98fba17f992c4bc4a790b73877209bf7233d2265fd3ec5fb847e1fe2a757b0e0fa8be586ac30df4a40de4246583f3536f55b2cd380ed5dc85766d4d72ede2f4582f529a305b9c0fce412f673eeafc0fc47e8bb5219e2f53bc8373f1f465fa760fd3ec43f295857c026bf02fea08833cca739bd900b8c571e52c7e6f9bd7bcb983fbc41fa0a99e2793bf8a332e47c93ddbd63f85bd857a90f93fe451d7ceed032e9837f296589e749d8af8efeb1def9deb4bf929ace1fc693e6e034407fc226076729fa13372bb00cf0be5504ce7db4cf1f4d7c9678518cf6e0b801d6b71b7b2a3db06ecea2ff794f2ef07e89f79d9723a13fa902ce04c76f795e703efaa3f1274910c6b0ff05d27f9e0062b8d3016bfdc1fcaa6bb0f2b03e6961f42d0903ae1f14785e68cbf7ee1e9cf9585f76c7f359006ebd816504f96c276015a03d21e6e41cebc93f21bf48d7fff027822cb89ef8003e1fc67f742dc3ff54a6e434417f32e41749aea7110159e1fa7c085605de7f6fda5f499c8490c718e989d314fe6389e7c7da5ea08f0558e70fefc7fd89ae118dfe8a1b7284fe9c3d394b30de3742fe1391415eb38965d8db9b89df9254970fe2f317b00ef8d03f82f2d7a9e37a5ce857a6df8ff49dc019dbbb1f2bb24c4c7a7a7db050e0e30c2c7dace7172f6459c0df1dc805e4b734eda144f801e28d650ad6351afae39ec182feeb382653de93129c733f819389c792f37c5694f7bde504eb6552cb884f15f44387cb88af0ae44745dae3197bba25e7e88ff824270af6d9af5a4e4cfe7a0fe04c24687f27609163bdd5666819f9196fc05a9f8cbe8ca08fb995c713ec2bd7118c79ff3dec333f1fc65eeec019f3d759827579203e30fe2a29acbf28efc90af9bb437a0b9d5ecc9f803e16a2447cd87a049f271c99f4c3bf147900ff227c7282faa284fe9611ede784fc9609e71b4c515ea56ef0a0fefc2097904f13fa554aca6f0cf9955a7d31bfc1d4a7692d8ad0df787f054ea87f8d1db984ff3a45e0b486f1fe4acf728af921c232f4e191cf933ee4d9e2f592fee6e983ccfebee93d38e77cb596f177e979be06f46f0e4e393f6eb7b58cfaff88fc7882eba1db03b244fd38d89373ac8f6c4bb0a4fc9a1bb06ede603cf5444e919f15d2e3fb29e2cfc3809c311e9d90ad7f9c81d328c57cdd18ac1bc468bff6c15a3ef07fbcbee07e1d25d213e8f2c7fd4d32c7cfee13b02e2fc4976d701ac05e8f2558fb0fac779d9353f893e6029cc7d0bfa9d1ff34b4f652457a431d61a1fecec05a03513f1cc0fa2f263dd58a65ac2f3d4ec132c6fb6e47e40cfa3c813cc39ce9b9407a223f477bb55280a33435f2ed1dc14991405f6fc05a438dbef7b68e4dfa7a55c7185f1e8233faa379442e207fc9f7291ffeb4e583f304f2d919fb4e63bf447f4b0ffa116b79a0ff05fa1bebf781efc81ed3a71ca37ebb26fb48dfc58a1c633d6d23b30c7f3f240b0fe96fbd805589fa6608fdd60107e66b35ea8ee16f52b24d3fca2f71e9bf756c9e770f7b4d5c7eda8e71de778cf8ac4ff678fdc031aeef90b9debc973b467c592107d0a739e4a3eb67b4b7d413587ae81f5ae17d69e8215e5d96e400f1ea3dec2575f96b81757ae1ff1f1d9bf4f5f68e919f0732eb8bdece31ca2f726cde7fdf25fbd43f49667eee6ec9b497bba663e4bf2047d0c787313906cf9ec119e7df4ca14fa908611f47f89f5466b4b75732f57dfc0ed6f11efa0f919fccca6fbb24733ecb3dec35b3fa7bef39c6f921d967f93e3b36d7df35c801ebd71b32f3df138e515ea96373fdfd891cf1feba65d437624de6f8fe9ce9cd4ac4174de43f9311f23f82bc33c5f18429ca23b3f5cd23f22342ae7fbc87be09a7bf2fe480f97f758cf2af3946f95e9399bfbb0bc7263fdb6732db7f0f253945fdf479240bf45fdd2d2c63bdeddddab1799f7c03ebf6b5d18721fcb7d0fec2a46fb02327f02f1dc85bc81a7832207ba89f97b057a1fdb3795f1df62fad7f2ea1df32e27ad23bd4f7d2e5f7d2b191f7dd2739c5fbb67bcb28bfdbba63b45fe664e677077f2a05e77f1ca0ef328f50dfaf603f2a607fcb6a4a8eb17eba82f4aab044fbe73e005bfddabd9333f41fdfcdc812f26b7c5a467fd21d9f7fbec3d4df9163c4af1b7281f8ff12e9575984f5371f287f257ce4ef1ee5955b7bbf3b9115da2fbb8d658ed7ed2d333d4b720e7db8fb706cded79b930bf018f563aef505f35191fe42c737a8ef43f0b94638f3fe9e5ca07fe36e6219e9eb2d1cc35e578e919fa363f3bcde9be5cc947fef835cf2fa83659e4779e8ab71beb7768ce7bd5bc6f5e31b32fb23e728bf4271bfa61dde576a79c2ff8fc905caefee8d6cd3f3ee18ef5b5ac6fb1a07cb88177a904f79def0c8f0d4319eb7b78cfbb70db28ff177057d2945caf1d839b984be3ca2fe2a6582ebc7b0df5209c45f2be87b990bac7f9f1b7dca6a410a7b383c83c300ed89dd1a9ce6985fd12bc905f4a9b72233bf7763b0cddf5de918f92b2ce3fac58e9ca2ff7f5307e711e425437289f8776ffc65e68535cc8f3c7864ce8fade27a2ff2b11f4d5e03eb1a0ee355ef60edefb03f588f9cb23d9f80f302f67334fa92f9998ff521378f60c5fdfd14f2e7171ee373539f6481f627c61f6e919f20f3515ed51639c0fe0b6a4c0ea18f97f67aee3f70794b66fb76dc074bb677f217b06e5062bd93a93fb3f3f2198caf36c0fafd581f0179990978a63cfa64aebf793f80658efcbda76095713ee4825c20be6cde83730ffd67ed0b7288f2bb32fe3e8b8204eb9fead7e08cfd43f715cb19fa37717f244b8c571c33b06ed0a33f82d75b79af509ebaf58df9fbdb2358e717fbdb7c92d91e9c0832fba3efba6091a1ff6706f9c4858fe76f611fe7fe66c30f137204fdde1e2ce37d970159a1febb84fc13e1c13f5646e05ca23fba34f6acc31b85f5c50f53b07dfe69464eb17ea77e6519f1c735f2930aae4f5639b9e0fc44e8b376cfd08f2ee4970502fa7c0f796519f5e9be242719e267d84fa62b2c8cd7c5e48cfb57a27c8508d07f3e857d082570bed1201798df533e817385f6e707d22fc318f3f3ef907e793e8cbea3fca528613f13e447e635e8db0cfa2b8b08e5357e2133bf624456d8cf720dffa0ce3b729db980fda930c2f89c42792a1dbf98fc3c40fe2a4be1df4f4f648e779e62cb181fb884fe2a11c5d8afd4d49f59aefd11faebe05f731da1c0ffe1fe3cf3119f3edc9013bcefa12067e07bc8ab381f67bec0fb0ac1fdc36e90be420648cff306acdb8346be15e84f19e49cff712497f0a79577cb985ff040cee82f1f9ae414fee27e47964c5f95ccfd2856f017a50c60cf37288f528528dfe71999f3cb84c9afa8853ec6afa70770caf95d0f1f609d1e73ffc39a9c91978e91fe4bb2407d73d9058b0cfef9f60dac6a182fe89cc805f4ab6eea57e1793ee29fee901cb03f22016b7999f4cd16e0a8c478ea34036bf787787e0fd6fa84f45e9059be0faf6481fe95073ecfc9774b56c8cfc3dcb191575f826502f9775be40cfa525f8115fbaf2b38efeb0a05f6de04470afefa02f9f363eac398e733ce8f7e782367888faa55c790bfef18ed57cf31f2bb210b5edf768ceb1b8e71fd812c79fdd131cedf5a46fd7a6f9f9f433ef51bb06eff401f3a64d6b7ed3e580ac8af82fb8380f3758e9f601d7fc01e204f5d5f23ff0f1dc7484fcb32caebfecd31e4774556a87fee0f64a6f7a14bd61668d20bf99cc783ccf539f43f5002fdb7aa06b6feee19cf0b9318feed610776e9ab5be6fb6a8ea17f27b2d5b74f32d377bf768cfe45e8472842acff3d648eb1beeec132f73bbd22e7a81f2f9b8e31dfabe5d85c3fe5fb747eb1bed3c4b7220ab87f567941ced11f2f2f1d63be1de4198501b8c7fbd31ce3ebf7b0cf48cb1bfa03fb8ab407c1f8af47e6fcf1fb82ccfd33ee42722cd09fcde729ae9f2a919f38e4fea7cf92ccf56d8b2199fd0defd7e038467ffcd53d99f6f80c7f10dbf2bd873ec6b63ceedf1d23bd1fe482e797e412fbd9dcc3dfc482f371ef67641ff67017916381f831708cfd2f9a8e911ee918f3ef2fc90aedcb12f28a25f7a37c52e498fdffcc7f11a0fe5aa37c93f30ebe67fe88c809d69faf03728af56f25e493040afa7009ff942435cc475b439e89d630a34fe33d39667bdf272748ff439fccfdd414ec3db1f1e8dad4ef22b5e9b91f8305f7abab1cc929b8716719f1e05d4ccef8be07b2c0f5ab165942bf1e068e11dfc25fe9f002e3f76b53dfeacacfcae7854cf908f803dd60c1fc8d3be8b7ae7ef0be3ef43b9335e47782f4662ebff017c23ddf778cf9f8af64be6f06ff2742eebf55e0fddadb231e7ac0f3f51f90bffa2599f395ef5232f70b7b782633ff0f2f6405be22cb1af6fb7844790bddbe44f9c3dea44bff1399e95d43fed22bd0bee8c21e6412a13edff0fa24c7fea62bc85ba635e8dbfd146ccbfb34214bec8f749758467e2a27c7e8bfc91c633e4edf32e2e707be5fe717f5d1d031e4f3e818f12f58b9f2f1c836bf037286f55af51999fb33aefb8ed1de427da4747884feba2bb20f2e51be2a4830bfa185f4a924c1fcbad6822cb09eec01f6ae534ffd1e39467ff0844c79d48f6485f6e4c3bd65cca77fe83936f9b9ab39467fd8ab63f41ff27c9ea1fdb4c6f3f39ac0fccd05e207ddbc45febad03fdd9c637a4cfb4907b30af38bba03c798effb422e705e20bf858ebfd01eec900bac4799c3df15b1c27a9406f2578802f5fd16f656c81afaab05eca3c839bfa80efb2d5d7a1e1c637e2dcaaf0c387f6b83f22db53e9bfcf62be0f361ec1ffeb19421e4bb867e9739fb37eac67fcb9ad58ffad4b1797f7dec18fb77f4c939b85e055b7d6a3d80531ff3d36e07e08cf35f3eafc0fa0e8c477b96b97f85a97fa4e7de3f718cf7df93f9feeea36393df7a05ec71bf836e97ec617cb7db01fb1c5f2d1be080f5f93e039f67f89bfcd41da3bfa1002725fa7f8b4bb0e47ad4ab0b7288f9bbdd14ac0294c753931cb1bedc834b0ff1dff8d631f26fdad7d277fad0235bf90b7281fc77efc8dc6fe21ae9f3430ffad8823ccedb11617d09f2e767ec7f5bbc83a587f642fd83ec63fc65535a86fd2c783ee77ce7d52359c01e9728bff3865c581fa9c89c7f5b187b9081cffe925290b97f5eb92773ffafeb153850582f770d7907a107fbfb2cc901d7b3541d1b7f7e8cc1b63c3b7c5e14c31fcdb764017f7f80be04718278ab5d38c67a69e84b207cccdf7ac8c925fce109f20cf461e4233f1c233e5c9023ce5f677ef318f63967fa8b12fa31823e85dade112fbf804584f8671d9353e8db67029621e6e3dd29cbdc9f87d7e79c1f793c9073ac2fcb618f5160d73be27c1471bfb9e3061ca7883fdb8f8e31df1ae98b1285fa634bd639427fab4766ffe361478eb05e6bf341ce581f9afa56c6f67b3202f28e3deeef5d817c625d9f617ceb93ccfdaf2abcdeea5b0e7b88031ffdd13be8531c2658df72057d8823ee47370ec082df93d8be826584fed5cf17728cf1960afc5facc589f571f07f71e9a3bfab843ccfdd0d486f9d1c932b64eecf740d7d4a02017f790dff95845c0f737d45667be30afa7dde4f0bfba17d90391f6c5b03cb18fd2779484eb81f12d3970bc4bbefc8bf8e9fa11f1fd057173f4bc82bf524dadb454c56e04ad331fc27de97fadc4fad08c809d277e2f536fd0b4956dcef10f24a658af9f59f978ef1bd869e65ec8f79f14a56181fbf43f9a43a5cc27acf39d8f6f71e607f69c1f19c0fdc9f39fd83fc332fc178a53c92393e53b9262bc4a36595ccf9b805f435f36b3c7f748cf98f9047a63508f6302327f02777f04f99f2b01ead7b2287b09f620dce0bccbf5d42bfb3f3064a67be8c1dc3bf3f38c6fad48c1c82af2ae498eb1bf1be737739fa379a64967f69cf2bf4575ec1df0b9ffb3b5d0564eecfd482ff16b187f5c67be8bb48d85fd8aa9205b8843eebf608e45545fd61027063afd007d77f7d89fc089d1fd4f70dc7985f0d96b67c25fc9bb4fd89a24a0e104f0849e6f777c4919c8073414ea11f79872cd1ff21eb8e110f411fb403477bb7939125ea870eca47bb1bc8a71c8205d7bfd7113f48ed2fb15f4c489658bf7a0b79499542df677c5f21e18f5af01fb2e4fcd135fca772faaec88c2f2a489fd2f19691873c913d9c2f227240f9edc921f4a5724b8ec02a24d35f345ec9dc2fbb51239728ef1ce5a5ecfe8e273e2fe1786fe7de31e60bf2f9763c2b9f9305d65728e8b75b3fb586ff53ba80305f94efd71685f9f5bc5f3f01e34b1f96313fb0057b504e9e28efdcc913cfcf6dbc5a2464caef62e3d8c837bf21fbd4bf0a39e0fd996394c7ce31d6efac1d1bfb2d143964f9d41d633dde3d99e553f92027ec4fb7cf4ba1ef15fbbc1cfeec02f5416ee3ed0b5eafeb378cdfa3fcf290ebe3aff9fc90fd7fc503b944fb7d8e78328f6bd0ff9624d35f3c31fd31f75b6c513e3ac2827ee464ee9fb29b5ac67cff31e2bb5cdb03f617657a6cf915a6fd250bbb9fb2807f296c79556ec83ecf0b32e57b291d633c392547e086bd3f833c0bc8bfb0fb01e7c84f61f703bd40bc5f9c77f432f27b23dbf122a62f617bf108ff5f645c6f57e6e408ebd566a80f0bc1f51392e9b3f630f6c902f1e605eab742db87c97fdfb240fcd9677eb4fbc1fe683d7281f6fdf6dd32f6d76a32fd2a82fd7cc0de4ae78ff764b6c773e4477b23c8bbf1462ee12f72945779de61d6bcaf050e23f4f73410af9511d7efae513e65c2fd83f6905f99c518cfbf9d9013ce0f44bcabdbd7587f503f910be6b749667fc36e6219f97b877f2d7501c1fe0cabdaf98b3726bf0732f5a9b1025b7d188ec8fc5ec93e054719d2fb3901270af919bf826df93d28b0647f4d7d0d5635c8e3a907ce53ceb7e3f38b94edbd809c81a5290fe59d77f037f5fb181c6488b72e3ec05180f1c2cd1e9ca5987f37a98105f7f7e9e3f99e8e78b03f3ade7ffefc08d6e76664cec7de858e218fbe65ee4f0079794580fed0f72599edd14bc8c3d7f127c6ebebe084f3e3c68f60e1a33efd1c806d7baadf24f3fb1155c8cf3f1fc6ff08b03647c493a6fda302abdf4517acc331accfb8064731fcdfa820737fe48b1d39035f7d920bf46f5ef3fe98dfdf5aa13c822c847f904f64f6ef3f217d81149057bf452eb05eb4fe0e3ee7d0d8d3c032f2573f90395ef3f96c19f6b1bf758cf5cc906760cba380fc74758078bfb825335e2c4ab0f577170fe40cedfdcb1c1c713f807d4296a8eff7d0ef5037c0301fa96d19fdf7f30e3809b8ffe6099c46684f9cd69633ccbfbc23c718efbbda9313e8fbaa0ace7c8c372f51bea1e0f8fa8ee76d7bf73623c7e03aec29d41a87ef911564ee97dbeb5ac6facc05ec3d2c7cb437a5200788ffa7bcbee078dc87f1e72ab2faa7e05fa280fbd3e67532f723cea15f51c8ef095e9dc821cae3949163947f03fa1d59ffba8fc9767d54e418eb9920df28a9a1bf7281f28c52aeb7bbfa708cf57cd0c748707fe83ef363ed6fc3e75bf91c2be488df27482df3fb5a7dcbb87e1738c67ce42d3983be8f17e022e4fcda2ed9ca17fec8f557e4785f7cde91ddc87b49e67edae28a4c795fc23e63abef852453de57486f1cb1bf71097b3b6f6783fdaf619fb164ff7bbf4bceb15f43ff855cc2be77f00ff1f938f30d9fa704e4f10179242e3f28efc47edfe002feeedc3f81f80dfe230913c47723d87b9294d0af3df42d4939dfb09593b95f9a447a12e921fe5826e414e3017d3e4f723ca0cff7ebfc613ff83b7281fdb27b3caf4b10f345f6e404f1c02eb28cf1f39d6f19f2e8751c9bfb0b706abf6f20611f6910a37fa601ffa5bd35ca671f900bac37dc878e713e728cf99f906f9a7958af3a867da492fba32db7e498df0f699353f607303d92dfcfea3f90f93d9cfe905c521f469611cf0de6605ddf9af7f5f97c5dbf82997fc5fd9f0f7b32e5f3f94ae6fe3bd38a65ee07c9e7175c7f58e07c66e38511fcbd9980689e0f7dca12ee47de807d64698ddf7bb8040bae0fe8c33e325dfec85f6699f1ea3399df2f182c1c9bfcf4f97c9d7f9caf92d91e1cccc83ee42bed79eebf3692e414f2387d90b91fe6e2936cdb9f883fb2dcc77aa125f4e7dcdf82782921dbf59a48ef797a28e237e88f4862e8d304fa2652ee2f3d7a2127dccf7f42667ba8332073ffc83efcb5901c4feadf83750489f38965ca33750c792d1d1b7defbf923db4c77a4c9fe27e45fdd0b191cf832433be9a64e48cfdad3764ee6fda3a904b7e7f19fe41d8feae3dec594625e47344799c3b54b13eef44e67acbfd1b38f5305f6854234bca13e5af9b37d437c85fdafc0ede1c9beb7b09d9437e7a2999f6d363fa14f7d7ea79e408f16eefd531e47f458e717e72240b7e3fdda687fbcfd73796e18f1bccafca91de31d39307984fbd823f96e70fa29afa09e52fcb18e35302fe553717d0ffabf07c75de71dc944f959ca13fbd403caa2b488c9f1d437289faff80f8ef5c8160be0dec5f9b0ff64b7982bf50598df3f7202fa5fd21e4097d555a9e58ef5523b33d79e0fb14bf3f77482cc31e86af96119ff5da8ef1fd49f84b9573fef0e9912cd11f5e205e523adec2fed8884f5c7f8fec9203c84b20becb23ce37541fe408edf302fa9d9f3f8866eaa33a39c7faf52be4274f24daa353a42f4fedfee2b087f3701cc65f603fe7fe0eecdfb92473bfd51ecfdbfee307418e619fbd17b28db76ec9fc9e77ef929c537e778e51ff5e91b93fda82f2c8038c979c7a6485f6d182e9d3f2c47e2f0f64eed7a320bfc2ea9f6892f97df202ef2f220ffda7059e5fc421e6af1d907e5ddba23fa2b12467a87f874fe402eb9f56d0af22f3b83f7a9f9c603cee03fa5d0896570ff6579c237a23cf2a39020f2ae414f23badc805ec73dfb28c78a1629fc7fd727b7c9fe27e4c4dc8a7c843c83f37fd5baa3c7fb1dde8df3599f2c9c931f7dfce13c7f87e2ff4afb4f2a9a3fccb8cfb1fbfb5c921faab8b777281fefe1cf6510a7e8f5222fde7fd33b19e25264bf8eb1ef4597b6fd40f0f1532bfcfd1bb20535f2f783eafa1bf7bc7f4d9fe09017b2acb04fe4a19ffa8cd91f9577b709ca27d7c7c072711e2c9d3069c6668ef9d6ec802edbdc31d380ba15ff39c1ca13edd56c1c2833d9f1ec811e64b4ec664ee5fdef7c0e7056a26bfcf64c6dfbb92ccf9d5bb19b9e47c82a963d8d32b38aff17b2223cb182fabd42da3bfa5c7fce51e9ef77145e678f0e6125c64883f723edfca3737f14bee69f91afeac80b5ff87bf0fc0b1077f7f7922733f9ffd129cf9185fafd7c809e291c232c707ca77720efd2a2660e1613c31bf232bf023f2a7a3378cdff61ae09cf31d064c7fcefd8d06053944f95cf179458af1a31cf2f0cf3b0c1a7d42fefcf30451733e069f273c9afc7e9243ccffdf36c13abe307cbd269798bf3fed81b398fb0715e412dfe73d0cc1a286f6c5a34ff610df34c6e400fd43bb8163ec2f312347a85fc5022c19bff6216fdff9f71199fb3d0e04b9647c9b8073eebf369064ead3ecda31fadb96641ffefbf36499fb53b8f3e89fea3d9159df0f72b22d9f36b8e07a97f9819c73beb5f13f79107bf077c71538e1f7946e519ee7ed79d03e833c822cc4fc86fddc31ea970199fdcd97f02f81f061ef176fe418fa3147fa035583fc567c9ee2fc11017d09b4c6211e5a9303f47fd5b796d1ffb21096299f9663e877dd31e45592b9ffe660ec18f39b20bf40b737e01f6a6481fe8d0fe34ff3d0c6339f787f1872ffc4cfdc31da7f8563f48f207f611241ff8f6fe404f27ffc24f37bdc876bcb8807afa10fa15daf787d438e315f7a0a7b0a05f7fb6e79e414fda1ed4b32d70f0c4b728ef5cc4db2ac21be7a82ff0e55c8f1f7109c73bff8f1a765ee4f322153de9fcc6fcefe9ac1d432fdedd031faf36e1da33c9b8e610f15c7188f7b214b8ec7c31f9ffbfb108f64e414e74b5eafdb8fe89f857d463adc33e73f9563ec37027fa26b2beea782f23cef1785fd95513f44e715d2866fc839da4bd790cf798352f4b7f37d2244f95c1d2dc33fe5b0c7c8f6f748c827d23538f6bf833c22eb9f677cbe95dfa92447887fc7b097c8cae3087dd6de14edbba3e718fd8fafe408e7b7d0bfd8aebfdede92b93efa0af67faebed0be9c39c67ac02e58e70ffd572139427fc89b3d9fa27f67fe48ceb1befdb3035611e377c827b6fa53f5c9dc6fbd1c9115fcdf02e51d1705e6971e117f2411e7a776dec839fcc911f6952476bf8e842c608f05ec3b497dacc7d95e9259deb71764ae177f437d98087e7f7e08ff9bd8f54c43946fa2eb03f4877b6496e7be4a8e381f7147e67eeff3d432f2dfac91b97e58421f922244f93ff2f9458cf989175332ed63774dce50bfcf616f898d6f1a88c7d2acc07cc012e5918a1ae6f39ceec821fa13db277286fae6d0738cfe8982ccfd80daa965e8dfe685ccf6ef06f541aa32c47f9b2999edd32dcf6b79613de390ccf5d2776db284bc2e6ec8dc9fbf057f7e9eef84f59c1fe408edd98b3199f1cfa241ce787e4ee67ad2d2b78cf187b70ab9843e3621efb48c30deae503e66c1ac91e7969c43dea76bb25d9f8af2cd848ff920b7f764aeb7da8dc8dc6fb00f7dcd723b5ed52447683f7d66e418f2fb0cc919f46d3ab38cfebabb47b2803c6f9fc812fe6b057dcd6c7ebb282f2d2dccb7f94079095b9fb6216f2104eaab4d83ccfd0adf2d97fcfe3be42b6488f8b2cef339d74b5f96e40ce3c9939365aecfbe718cfae082ccef6f57ef2c231e39417f84b60fe487cf2fb93f94ba24a7b0973dca53eaf818f30df17ca9d511fbb3415e52ebb779dfd3865c603fb936e423a587f5d28d0139c0f3de5ec91cff98a27ed1ad49e4ffb34b16b08f47d46f52fb1b7c0fb949e6fe2d9b163965fdcdf4e712f595443c785eaf8cfe9d4bb2803d94b00f2502e8e3ba4a9631e221e457490fed9d378f9c205e1c5d9105e24f85f4ab9cfb170f1ec8dc5f756b99fb9d9c9ec9fc9e76656199fbabf2f936fd222227b0cf0fc8dff55729b4af72bb3f47c332fb43779fe41cebcda6c87faed8be7a3b91f93dc131cfdbfa6b724f8eb0bfc54890b97fccf6912c604f870599f39fab7dcbd8ffbcf140e6f7c217a8dfcefd45f0571bc7985fd3708cfd739ec809ce579e1d9bf3e3936323af2749e67ab0b79163d447a8bf736d1f889fe10f0a2bdf1339f3d0de3d5d917dcc9f1e3e9313f4373460efc57905b1f1b77d7286f57b12e553a800edb7f1902ca1df07e4bfc8b9dffbac6e19f1eb43e618f34fa19f85cdffe24466feca47c7f81e17fa538ab206797cc07fbbf93b05eca13cefb061f407cf2b8587f589bba363f8ef8363d427137280f52617c8ef797d8bd1bf47c8ab547cfe00e92f750b0bedfb88ccf1dd47e9d8e8dfa047e6f7482a43728ef19862432ec015e6e77c18f9c0bf974e7f1e1d633c9eefb3f2aaf864d68fcae86b51d31520ae6f903394ff6e0fd6f280fc79bd9607e2a3c432d68f97537288f393395872fdf9e71d5815b0d7810fd62d1ec8ef911ca37feeb142e6fe2f833e3943fbbe7f41e6f8435b914bd41fb735c7886f3fc105c7ef4e4bc758bf6e99f22a5fc9127c34fea0f074fbd0a4ff04f978b67d7eba244790879a930b7ebf68462e292fb29627da4b0bc7f0ef4b32e7a79473c7d0a73a99eb31170f6099a33c0f280f4fd17f6eefc83efa6b6e4bcb88afc75d32eb673120737f95c1169cd7307f6cf04a8e30bf66109363f4cf0c86647e9febd1decfef090cf8fc738d69cecf2dc31fdf1cc105df57f5c81ec6d71617e40cf1ce55415658efb65859863d14178e4dfab6cc6fc9fddd9f4c7c52f8aa86f699782373ffdbc1815c22de1cbc80757e91bf0939c178eb20738cfb4332bfb7f63825335e1874c939f7238ac905e4ffb8209788ffe67c7ec1fd611733c7d8df4591b97f9f5c9229aff1355970ffd8c031e6af3f9273d497cd1ed8caeb84f239f74f197d3e9d1ca33ff8d332f70b3f90691fa786659eaf3b867d5e90633caf1064da53e30a2cf97da5a7365809cce7193d9115f6b7ca2d73ffdf4504ce6bf03f9ff7648ff1e98363f42ff71d9bf40c9ec909cb73ec18fa3f22a7b48fc431fa330372c6f6764a96f4572d32bf2f77bc05dbef411eef1c233e4a2c63bc72fc460e39dff0861ca13f7bb1252718bf38b23c0b89f852e0fdaeff4d411f75e9d29fedc076fd72ceeb75f88efe18a43754358c87ae96e40cf5c1b44d5618fff9847e9dfbb7600f35720af93c168e610f07c7f01f4c4fcefdad06a963c4e333b2847d3d56c9fc1eef0efe273cd72867de6fc9f437d54732d7732cd6646b2f03728ef90207e86794da7803e98b32ee8fab50ff4576ff8027e42f52ec0f7e3a92335cff087f1de9fc60ffc9bd63c4b30999df3b7c7b26733fae3de415597fb18bc911e6c72eaa96d99fc3f7ebfa10eb4d3232dbdf0b72e9c31f5c203db1cc383f07f616ab14eb3d571b32f70719f0bc2e0fccc73838c6fc862399e3e3fd2db960f96d2c235eef7f90b9bf67ffdd31ea2bd84b5cf0fb5307beef5ce3187dad9063ee47d0b08cf29e5c3b467ba0e318f113eccbcd573bc25f2411d77fe590ef79bf08f8a71cace83f3e1ae414fd116ff027bab588fd31373e99fba33ef27e27af3d99e5df3f91f97dd8fe866ce5b3728cf947d0e7a4e0fe3d830ed9437b6fd326b3ff79f249a63c2e99deb3048c7cdf2dc35f0d6b96b1fe6f72e118fd0357e4143c677a4bee479d2fc921c65704d2935a79ef519fa6a2807caf91fff3fc2f533ea377728efe9c39f2af5b7fa87f463ed947fdb4cbc901f6d79cdf5b667b62480ed15edd4a7284f30b7b7d8cf912737b3e867d4f2f2cc3df4cecf352d42fead932fc4f7f47cee1af868f64c6d3e30732e3df3ef429d511b7d1871b3edfc9bfe118f2bf748cf1d12e3945f94dea9671fdd0778cf2f5c819588464ae071428ff549727e6bfcec8ec2f9ff0fe32c3fc6c85f273eb1f2fe11f336d2fe8afdd9173b467e7485f96c7284f7543e6f74e963e99fb47f53fc99c2fb21993f97d99be7d1ebf3735823d64d61efa6f8e4dfa6f5ec801ec61742427accfafc919e4f9105946792c2a8eb15f474c66ff66734996f03763fb7cca7704ff989535c67f2bcbe81f1b535e56fe0bcac3cabffd4ace707d6743169c7f85fcbbfec34613acb83ee109fa27ce3dcee6fe1d5962bc6b36b58cf6f56c452e115f0d610f42cb13f3f796647e8ffad132d7af5c34c882df9bf8b40cfd7b48c894d7db3d59a13fb1b0d7b33d90c3decfeb31313f14f6257582d07e40faa50cb09e32bf27e7e03af22fcf33c08cff43bc2af318fee620c909e281f696ccf9d2b71d728efe85f9915ca23ceb88afe4b94637f9e3fd05f7177e1a934be4670efd3f7f3e10f537ec59d53ce44fc1df2bbb1e4a65e412f3ad72f863755e0163de0f7b5639bf3f575f9013f8c7e5b565eedf372773ff9a8b3699eb9546889794f64fe6fc7444f610ef3fb5c81c6f1ef0fe82fd7d8d2359a27ff7e285ac90bfd3dc32eadf7ddbb1d1b76a6619f25d0b32bfc73587be292b3f8978d6f557e6e4f38a3e931fc85fd7b68cc720df5cd70788f7df2d33fd237282fab8bd20b3fd5e87bfce0bcee71cae2dc35f3dd9f39c4ff22c1ce3fb483dc7a8bf4ab28ffd2246f7648ef70e6f1ce37b490f64ee973d9464ee7f356a3b467aebe404f557d79e17f0677de118f31726e49ce3fb35cb98cf5f758ceb1f527281e71dfa647ecfe012f15f5e72ff4ff54ae6f7703e51df14dafeb0bef38d5cc29f0c717f51707f8a4d97ccf9c1fb2339c0fcd7e1c132e43f93e490fb7185e408f30d9e2e2c437ec33bc798efdb23f3fb94a38a63b4e74a32e383cdad65cc9fd8268eb13f6d4ccee01fb69163d447960bdac79d63b41fecf3d97ea80e1ca3fe9c92f9bd9a47caafe4fcddc795659cbf7c207b8c37466496cf11cf2fa312e97984bc75ed80fc1f208fb2a8c19fbc87640feb2f86ef64ce9778ba23f3fb69a367cbb0b7e1d131f4bfee18df0f15e410f3f9470f9671ffd3a363e8cf3539427bfd7d428ef9bda896653c7fde242798ff3ab4ef4b614fdb1e3943fcb7b5f9a5fddc1cc839cae3f28d5c72ffdb0bc7f0776dc7d8dfd13ecf961fefd7e567e4f9b8768cf29e59c6f59382ccfe52f5425625d6a798fc99ee78c40b0138b7eb7963b02e3fd8d38accf219f5c921e3dd9365dcfff4e418ede70199fe7536b4ccfd89378e51df7f63535ec32b32e3f1a70399e3fd4f23c7463f9f7cc7f01713cbdcffbbea18ed477b3e45bc34685a467aa7f67919fb8f5a9631be32548e91de7bcb78dfc032f7e7ee2f1cc39e04b980bf7b7cb78cf2eccfc9d4977e6999f63b0597763c29b00c7bed4f2cc3bff4c78e311fefd231be4f72e518df0fbab7ccf5bdcf64b607a47d3ef5abcdf2380f889cb940797bd2673c968215c7e7ae51de5eceef473c4dc8dcafb1fd46ceb9be32b20c7d5b22fd5ec1f591970939807f18f2fe82f34946378ee11f5a8ee1ff97647e0f70d8b1ccfa77e018e37f9f64d6bfc33e3941fb66ec5986be8d6c7a53ea4fc331fc934d2fd7076dae2c533ed78e31ff636319fad5a0fc740b00fd454dc748af7d3fc7f3953b0ffdabdf9125e2c9616e19ed81edd032f5f582acd0fe6feec839e301f80fafe47cf98baa658c6fdc49cb984f5c3d91f97db3719d6cfd17cacb77f15ee118e35f3db0563fe80bdee7dbfa62b821737eccb0e918feeb4466fcf4f4ea18ed8b67cb68af3d79e414e571754366fff1e0da32bff7b9b30cfff77445e6f7cd4636bd12e539158ef13d979d637cffea83ccfed27dc532ce3f8ec82c8f81cd1fbf6f519d38c67cec19f82c51f3bc8e6594df746e19e5335d3886bfac3ac6fc9794ccf943d52399dfc76bbf906df97a8e313e62eac7f2dbfa78a42f9029facb739477a042f89747d85390b3be6e207d41e1c3be1e1332f7df1beec88cef866dc726fdcf7572c2fd723f2ca33df6d4b5cceff5dc3a867d7f3a36efff88c929c6a766378eb17ebf43a6bd0eae2c737e29f3a7f505fbc90f2c433f669163e8d389ccf91f1bfb7ceac753e0d8a4673c718cf9698a5c409e6f825c429f576f8e8dfe3cdbfc33fecf29ff92df5fbd9c9303f6477e58e67a1acabfe47c8c7649cea90f48bf1bff383e8263fa974fd46f61c1f1bcdda5637c5f6d6199edd71bc7b0e79a63e4a7708cf193a6638c9755c91ccf18dc5a46f90f569691ffd3802c581f7d3a86fe751d63bed6da32cae73d224b8ed75f3a467b445a46fd7e559215d353770cfdb5cfe7fc9959cf32f7e7db38867f7c738cef57d61d63fe5fcb31c65b6dfe18dfb4aec925dae74f4bcb1c1f86bf0a4b8ee7ad3ccbf097cb6f8cfdc4ef1c63bf8db563ac4f9a927d9c6f7b8e4d7eaa7c7fc9fdceaa0bc7189fb31cb23dec5bc67e81772dcbf0870f8163f3fc5648b6f38b1499faac209f6ffb2f6cc176bedd05ec31b2fa7b31230b70e3d232e4753c9139dfe724c90afe6770e118edfd213987fe1fba8ecdf9796299e32b25b980fc66f67d25e45bff748cf107e84fa45b1898ef9d5b667db323b3fdb90d1ca3ff7e4ee6f79eafa78ed11ff1e118e3450bc7688f31bf678f6ef233776cde77bbb48cf25a3e9143c4cb7715c78887af2d231e6ef4c811e2cf1bfb7ceee73b7d26b3fceb880f635b1f5d1464ae0f6fb4c8f4e7a33d59818f093947fdf4f9e8d83cff3d738cfd2d6e1c637c7aeb18f6f7ecd8e8ffea895ce0fc5bd331f68f6a904bda8f748cfd09a68ed1ffc3fcdaf22f63cb1cafbd760cff3d24f3fb44d39363cce76f3b36f969ac1d637f3be518e55f25fb4ccfda31e45d718cf5fb03c728cf5b7280f45ecf1c633fdab963a32f37dfce1b79ddf8e410efbb6938467f4bea18eb8ffa8e511e363fdcffbcfa6619fab78c1da33fa2748cf1ea6fe7b1ffbf9547ccef4de796717e291ce3fb0d978e61ff4dc7f07f237282f7c93b32fddb11f15d1287585f5040bf121963bd5e03f69b687dc77abb6f8cef453d90a97f4f2bcb90e7a565cebf3b9496612f938363f88fa3638ca7401f92b286fef6aab20c7dd92d1c435f0ac7f01fd231e6a347648ffe8fef2f39ffe7e6c631f463420e989f77c7f81e97748cf6dad431e66b1d2d431fae77e490fe70ef18fd4def8e8dbc6eed79f6b7dcb6c831f4e9a6e918fea7434eb05ff68dbd9ef31d071bc7f87e28cbbf4ca15fd54f32e72b54ad7c14da530af1841b3fce4bc7e8cf457edd7866ab45663c71796f99f1cd8b65e857dd778cfa13f5736acbb39a93adff9938c67e2355c7f8be9c728cf6fe1399fee6fa95ccf2aa5e3836e9bb1993e90f2e7b8ecdf3af94633cffde31cacfa63744795d77c911f4adba716cf4edfa6019fa72e39163c8b33a25b37df66cd3cbf2eb7d3a86fd3f9333f88b9b3659a0fff829214bb4ef14fc9f1b3f3e425e591c72bfde9163ecb708ff9a49aef7cde10f3295b23f09fe3ab3f1493d23b37eaaa37eccacfdd603b287f2b9291d9bf43dafc85c8f592d2cb37c468e8dbc6ea4637cef2127d39e6f2cd39f572f2d43fed53199e535529621ef6be6e75c431bbe736cca7f56b3cce7ad1c63ffcf6fe7315f93f22c395ffd76e818f331a68eb1ffd43539637b6d6919f1efb3cd0fd783dfb8f3b0ffeaad63f42759f9737e56eb44969c2f1f3936f2bee93846ff6fead8c8a3659f6feb1be44738fd41790999603fd206f22fac7f6f4832edfb9ad7dbf8601d9103d8e375c731e2839e63cc7f5464daf3cd0799f5f7f0c532d73fdd92399e74b3b2cc78a0b08ceb5b0dc7d82fae49e67cc19bc431e2c789635cbf23a7d0b76e46a6fd0e43c7267f873732bf5ffc7c6599fd7db163c86fe818ede71b32bf7fd23c394679a764c5efd9278eb15e774ce6fee9cd2ab94079e738efe6075c23be952ebe138ee1af2b8e517edfcec3beda64d6bfd52bcb946f410e19ffbd3846ffc0b3637c9f82e9d3e58bef1128c7f08fa1658ef73c9113fad31a3985fe343dcbf4f7f78ed11fb0768cfd78a463d4ef0139437e5b4732e71b3f5f3bc6fc997bc7907fee18fd19367fdc0fe933708cf42f2ce3fd9dae6323ffa69507e77b34ad3c723cbf5a778cf59156be05fb5f73c758efdd21f37b09ed9963ec2f5b718cf9cb28bff3064ff8bee4ab639c7f266758df7f8d7843d978ece6d231ec774ae67aad9b37c7688fbc3b863f28c8ac7f9b0d72c2f51207cb28efa78c4c7db84ec919ecf1bae718fe7ded18eb77edf3acbd868e315fa5e218f1c38e4c7bad361c633c61e618f10ae5552af697d8eb15f4e37a6019e579fde818e535245b7b0f1c63ffdd47c788bf6f1c637ec3885c203f37778ea1ef7372096ede38863f81bfccad3f39223f79ccfd3f0be8732eb97f7f8ef6da79411ffc0bfc456ee3b39b6bb2ad9fb7e414e575133bc6fcb43732f7af68d71cc37eecfd9cbf71eb98f56fdd31e4fde018fedf274ba66f6f19f2bf0e1c633dad47a67d5efb8e311e1238c67e3f3bc7188fb3d7733e497b6a19e57b7bed18dfbbad3b46fbace718feef48a6fddf3d3986fc53c7d0077b9efee0a6ebd8e4ef11f5ef798203e26941e67a8ca7c831beb7f144e67aad9b9363f8b30359d21efb8ee18f0764cae73a726cf2dbb6cfb7fa2f1d43df13c728ffd831f4f1e018f30d1f1ce37bbdc231e4e9930bf6575e38c67aecb663ec4f32748cef0b5ae6f7beab7bc7f89ec0cc31fc5fe618fe15f18e160fbf0782f851bb0f7e1fe3cd31f6ab1a9073d8db10feb73cf71898e70796597f8664d65f37af8e8d3c9b7bb24479dfde3a46fd173986fe278e11df7d3a86bfde90f9bd89dbc831fcd7d131fc6fcd31e2cbd831fab36cfaadbd541c63be6fcf31f47fe318f5d38363e87fdf31eac3c231fcc19a6ced69eb18feda730c79ef1c9be737bb8ed1df3b2797b0ffa6b04c7d9939467eab8ed15ebe718cf931db6aa52aaad21c4a1f397f9eff95e6b78247ce43fd8da3e47df6eafc0777e67ce2df7a96facdfd38e4975416d57175529d5667fa985717d565f5adbaaabe573faa6bfddfa6baadeeaafbeaa17aac9eaa9fd5bab9aea1af3c5f7351bdac5ee9ffaef571a3e5f0d3ffaab7d566b5f2b0fdfdf1dbbffeec1a2ddf56b55dedf0e89aa3e38e3b7db655bdfff2975fc7df7ff474e9fc3dfffee9c7176b7bf81f7ef4ff86bdfde3d636a83ebae36c6ddf6868acadfde52fbf8e7fc3e377d6f6541d559fab2fd557a785af5f7eff773efea1ba4dfbcfdedfb4b65ad5fb7274bffcee1b6b1bfce6fcafe3dfeef89db505d5b01a55e36a524dff74fdffef3dfea1baed1cadfc4d6bcb2ad59f1c15636db59f9eff75fc95e3ece9fe9e7ffffce37b6bab888aaca84a5e292ae5cf35b332ae4c2ad3caac32ffc131d3672695f19f6e3d7ff4f897b7db1eb695c54f8ea5b1b6eca7e77f1d7fe5387bbabfe7df3ffff8adb555de2aabca7be5a3b2ae6c2adbcaeea7d6b6af762b87cab172fac171ac1cf4d9fd9f6e3d7ff4f897b7db2a9fd5bb1f1f95fad9daf4753f39ffebf8f738be595ba551b9a85c56ae2ad7959bca6da5596955da954ea5f1436bd36dfcca5de5bed2fbc1715fb9d367715dbf32a83c568695a7bfaf76f9f2f36f5d85e78f2acf95e7eacdf967e5e56777545e2bb58a57f12bc15f7feebfb66eab84dadea29f1d676bfbf9d95fc7bfc7f1c5dae24a52492b99d0bf0a21a45022178528c50f62c28ae9c1161331fdc13131e766e7ebc45c2cf4cfa578fb7bac4dacfea8b5fdf42f5f9ffa2e3ec45affbb11db9f5f53fdc7db6d7fa39744c791a189177f7854c2bf76f6d7f1ef717cb336b1137b71104771129fa22e1ae2425c8a2b712d6ec4edefb4b3295aa22d3aa2fb83a3a3cfb4c49db9ee5ef4f4cf87aab623d11703fdf3510c85aee9c4483c9fed44bc885751139eb51ae1a3a6d2bf0522149188cd7312918aacf22cabbfbbe737d6262b529c3fd32673fcdd7cf27e2c2772fa2ded7226e7722197f2edcb352bf9fe0ff749fe955e12f9a125dcfc75fc4f3fbe599b5ccb8ddcca9ddccb833cca93fc9475d99017f2525e7d6f6df25adec85bd9942dd9969d2f475bffa5a9cfdcc8aeb9ee4edeeb9f3d79febd2fb5b5c94739944f72249fcf67b4aeebf84fbecada17aba1ed484ffafaa789fe642823f36ffcbb7b7e6b6d894cf5cf4c55f1775539ffab843aefc494abc250a9746dad266afaed1aed0fa6ffca761bededd7f13ffcf8666d6aa6e66aa196ea4dadd4bbfa506bb5515bb5537b75f8dedad4519d64537daaba6a7c77d4d5a73e735217dfac4d6c24eeba94beba52d7ea46ddaa266b167d5eb554fbf7d6a63aaaabeed4bd79ce44f5bed9d66feef9adb54dd4f9cebe1ad0921ef9aca17a5223f56c7e7f31adbc67f5faf51a55fb57b6db7e1dbf8ef3f1c5da3ce5ab4085e7ef19a944a52a13f5bc9a9fbf3022bfb7b65c9dbfe39097f9389f7c778ccf3bf0ebb3d3ef23497dd72c9fe70bd9cb97f95bfedb36dacdef7e3ee4eff947bece37b090afd6f6bd8d7db136ef6c6df936df7d77c5f9affbfc806bf2e397bfdbb79dfeb575dbafe3d7f1d5daf2cfbc9e37f28bfc32bfcaaff39bfc366fe6adbc9d77f2eeefaced2ebfcf7bf943decf07df1d7dfdd79e3e6b6a8c7c885e92dcf449e6a3fc59b78f1ef297fc35af557f6f3937a89f72cfd89a7f6eafe52692ccc3f357da7e1dffa223fcb3b5f07fcaf1c5dae2f377e7f2aca81666875b9515caec8c5916bfeb952c26c5b49815f362512c8b377dacf471fe77a9ff32d767a6c5bbb9eea358571e8bcdb905a649d71085ae758a7d71288e3fb3b6e2547c569ee5a8a8178de2a2b834d6161557bf8e7fd591477fb616fe4f39be595b715ddc14b745b36815eda253748b3b512fee8b5ef150f47f676d83e2b118164fc5a8782e5e8a571e2f9a46faaf437db6f6fd3dffc8a1adcdfb75fcab8e5fd6f6df757cb136df7cb3262ae22291fbf3f704ca6a8975dcea7bedc7eabb725c4eca6939d3c7bc5ce89fcbf24dff655caecaf7f2e39f6b6de5fad7f1cf3b7e45e67fcef1cddaca4db92d77e5be3c94c7f2547e96f5b2515e9497e5d58fe793fc771edadaae7f1dffbc238ffeec91a7ff99c797b924a2bc296fcb66d92adb65a7ec9677e57dd92b1ffebfb0de465b5bffd7f1cf3b7e59db9f73fcff6335a9b6b6c11f3daa37e5a339867ff5baa7f335bc7664eefaed337e7cd773f92265f95ad6fe507afede6bbdd2d7a909caf01f7ccef77776ed6fbfacedcf39be58dbd79d09b06b4269f74e30bbd446d8cb133b7cfef6e08e05dff62ef8f12e077f7d1704c57d196c0a74b3d1eed7a0ad2df9a387d6cabf7e45faa36bbfbb2bfbf1bdf9ebb8aaff1d8c2b7f20453f79d6f7c7588ce558e97ff371215ffe0bf9fab944badade90fe5fd6f6a71cdf5bdbb81c8fc793f1f437bb94e4ceaee21f1f6e17126b2fd21dbfdf53e4eb796b6fdf5b206c4d7eb3b6f1ec8f1ed59b2f341f2fc6cbf1db78c533efe38ff1fa47d7eadf36e3ed7837de7ff9fb617c1c9fc69f5f9e571f37bed0c5f8727c35be1efffeea2fbff359dfa7e4cbdb78dc8e9bfcad356eff244d9d71d75c7137be1ff7fe6e8998b9e4e7df7e59db9f73fcceda1ec6fdf160fc381e52d3cdee3fe3277bfcd8ea6819dfac44fec69ebeed2a64edadfc8db5fdfef8bdb58dfee8c17538cfe3674d2fe357fdb336f67066ec7f7fed97df02fd6f585d7dfbbbf4c6e7f7c75fee48941ca7e36c523dd3a43211faa754d3efaffefa3bdff17d4abebc0dc7444d72fca6eba0c38fd3545e4f8af355937232fe0312e9d2de46ff356b9b4c26d3c98cd4fd27685ff707bffdb5f7cf278bc972f23659fd3334ff37b9f92f9caf7627efe6f8f849be7e90a7efad6db29e6c26dbc96eb29f1cbeedb5f5cdda606f93e3e434f99cd4270d1e17fab8d4c7f9dfabc9f5e46672fc8dbd4967bb3faadbd46f6ac1afd6c6fa328f26b77ff4a8de7cfb5d4e264dfd6f4b0d78a6fdb36bf56f1dfd6f57b5bffcfd6e723fe94d1e7e734f7f32983c4e86e7dfd5cbe4c91ca3df5dfde5773ceb7729f9f2361e6af2ccdf5ef2c34fd3f43aa94d5a136fe2ff0189185b3bfff65fb4b660124eec9d7f86b5c59344ff4c27d9cfae9856ffd633be5df19bdcfcaddcfef5d47fff8ecacfceffd6daa6622aa76a9a4f8b69391d4f277657bbb385395bd375d9743a9d553ea7f3e9e207c75c9f994da7cea6bedff14e7d57a7fd3ee654bff98bb6bc3c9a2effe851bdf9f6bbf4a66ffadf55befbfeccf7d7dadff02fe97dfa315d4f37bf7bc7363ff0e9bb2f7ffd7af597dff1ac1fa7e43729da4f0ffced383dfd344d9fd3fab431bdf84312d1b686dffe2bd636bd9c5e4dafa737d35bab4bd3e6b4a57fb6a79de999eea6f7fa676ffa30ed4f07d347fdfb70fa64ee1c4da2e9f3f465fa3aad4dbd9f5bdbd72ba6fe349886d3681a7f4941324dbfd06fafe84eb359f5ff6defcdba13650276edf3fd333ecf5989260e6b1f31c80ca23218cf9c15649e596bfff7af0a1c0031e94ed29d7eded7dc4ba0064a245c545170537a4b5fc090bed457e01b9b72ac9b7ecdedb6d57fadbed1b7a009be6fa64d3fe8ba6e80f951378b14dd2aeabefbb4e9b6eee8aeeee9be1ee8a11ee9b19e14754dd12f726a4776f554cf7454c7745c27f4614d0488c5402a09d7d3299dd6199dd5b94b8f47c1d21afcf689ce03093957822eea3c881955aeec4eb4e9d2fa551fffae10aa149ae853309575e526a596f7bc54cce1f460ea2a58d6d69dd21a33fd0d4ce7fa531e7ad6dbf9bc53cd5d5df35472e39654b6e8457fd5bb60ded3fbfaa0799ba00cc468198bdfda23c279e933b4194b6305a66b63733ed68cadb103d3bd713074c3308e0638d20c2bcf6b1be038335cc3337c300f8c104c232306d3e43e6de51c466a64608a1a58690b708330860669500d390403706130066b7060ce1b42738ee65f73bb6df55f6b88203432a4f2d6172d49639ce79f18534336947cdb7ea12569a88666cc8c37636e3c19cf46dbe8182fc6abd1357ab7bd1846df181c11f86293565655f15a1690ba80a41c974740cc717ddcd4aedc36605bca759f50eab32cd76ba736e8faf5b8fd5d215429b43bee41b5ab1f8d9b945adef35231cfa7c7a379b48ef6d129ade11ebda37f0c8e611e8a8ef13139a6c7ac96bbb2e6a9e4c62da96d117ac4c07af891b8bb4d50c323f9fb7ba5d067683b524770b41e99230b09caeb36e2c819f1913f0a47f1383ae647e2717c9c1ca77be728e721e5a81eb5e3ecf80696e7c7a7e3f3b17d9fb6728e63a738968f2f956d783d768fbd63bf218770ccdb972662b6cc85b93457f77234fd9adb6dabff5a782631d7e6a671eb73995b7367ee4b29efd2061a18ba699847d3342dd30653c7744dcff4cdc00cebb4999119e74accd4cc4a4a414c9182425a4cccc4c1943087604a9a94498375199385755b8db67a2f498d36937ba826de143ebbeeefd3668ae6c89416fbc5de1c9b93f3b1644e4dd9544cd5d4cc99f996c7cccd27307d3ea5b7cd8ef962e6df6676cd9ed9374b47bc8558f9158eb5b096f51c4664dd71bb5b2b6bdd90e3746c5b1b6b6bedacfdfd1c4dbfa6be6dcdbfb646508526eb60e996611d7f9536cbb42ccbb61ccbb53ccbb702b0145a91155b8995d669b3320bb5300bb788938640e7651ca4a056de92b4280bf0653116e46b6d71166f0996688d4e6d47204b2a68b3c6d6c49a5af2a90ebca1cd521e2a49b5346b66bd7d76fddfa7cd9a5b4fa7a567ab7d3e96ac8ef502af94ac57ab6bf5f298be058e591b391f6b76cb5ed880257b65af61dbb2e0ea94b6b1b7f97c67efeb39ec839df707da4629fff1300353b368cfd5729cbfcfb26ddbb1ddfb396e7fcdedb635ffdaf768d38fb667fb766087e79443cf8eeed366c77662a77666a33666e336610f6dd2a66cda666cb64e9bcd5998cddb822dda23f0b90a86049b07a9d295367b6c9d4ab027f6d496f3fe46e172af00c62bc8d2566dcd9e55def35fa2cd7e7be8fbf4fbb4d973fb74fcd9cf76dbee144794fd82083628cbeeda3d3b6fdfd90307715acee27c2c3a4b6705e786e1ac9d8db37576d7324123efe0e88ee11c1db39ec3b11cdb711cd7f14af97d2770422772e2861c9763df499cb4a8d3eee5a8ff1a27ab6f5bf3afadd356b4531d147c13e6e0f08acd219ce13997433ad4fd5e128776188775388777044774468ee48c9d8933756447a9d3e6a88ee6cc9c3767ee3c81cf5530f4065234e71992e4b49d0e98be8096240cbd3a5da7e7f4f33e4aa172cf2d9f3b0317b9479bdb7ae8fbf4f7ee6ebb0b77f9f552fea7e84a9bbb72d7eec6ddba3b77ef1e5cdd35dca34dbba66bb9769db665e43aaeeb7aaeef0640e14970d907b12e488d20416eec26609aba190c998c8bba988bbb444edbf93e00cc37844b2ee952f75a922efdd0f7e9efd066302ee3b2450fe2435025da38977705577447aee48edd893b756557715557736775dadc3777ee3eb9cf6edbedb82f605ae80584da20f609a4bee6f9ba6e4f67dcbe3b40d61ee2b5bc05b2f296de2abf6e833dfebc07c95a7a1b6febedbcbd77b8d74bf2d3fbe97f961efbf36774a5cdd33dc33b7aa66779b6e778aee779be1778a11779719d362ff15277ee651e0a94016140d9390c52520fafacb1298dd5767b277b5b796ab9f10ec04fefa7ff597aeccf9f518936c21b7aa4477934e08cf1588ff3784ff0446fe449672a74a9b8daf2c6dec49b7ab2a778aaa77933ef0d7c66dedc7b0231cf5edbeb782f17d22e4f5b5e465b5c5d9fee2f68f25e4f2c9e9f2ba98da3f8383abe578ffdf9332ad1d6f57a5edf1bf888dff217fed25ff96b7fe36ffddde5f9c6ab0767935f5b5dfb38eacff897d5100fa82d7b0556b5e72757272e1fb4fd213df6e7cfe84a9bbff70fbeee1bfed1377dcbb77dc7777dcff74b4f1357db78e7a7f497794d75dfc7b6be9079792232af2357177e6f3d37d5a7251fb47db31efbf36774c74d5abec25a5d08aa3eb55fa6adee64ab93b3ad796c2e77da6a5e80fab77d85b6d3fd103ff8d49e11fcf0bcf43bebf9911f83ef4cfcf46ffe177ff5379d971eb4fd8ceed05657ad6e3ab156ae9fae5cdeafdbaae1268eef384e3f475b3de6633f46796d3ff3d1e672eecbc77cdc27c07ce893febfd7f32d9c7fcb83b69f519d369ff6199ff5399faf1053f78896dd9e4df553535d55a5e95c1b6e4aa126daf2b82fd376725bf8822ffa235ff2c745ac3ff1a7beec2bbeea6bface9f95d7f0dffcf9b59cf29a4d4e9342fe937f726df86dbf53acdde0d5f8290967de1eb4fd8c6e68e3fd1744f25ffd6e859fbad7bade4b5fcedbd432bc6d612ecb6ed14a4bf496d5cd975a92f0f9bd93dbc2effb03840990e0e4f70b1620b40c56c13a9f579ef00eb6c12e808c08f5359b9c268582437072fb0646707a42b5c1abf15312cebcfdfefe0c4cb82f8b7d1a585fccf74f7bb63fd4273cdb67ddd216d88113b88117f8b57b602572822008832888832448832c40032cc00322180664400574c0046cc035d05626757bea29595f7a4a9adda6f9dd83afd76d85db22e003013efbe614575542fe9c83759ed7fd1481188cec7e514e79cd26a749a1326dd6faf41db75e8d9fd2d7ebb6da9174b76dfe3e45ffb467fb77f741e93bee7ab6cf2ad1068ef3400ac6c124709145300de4e0fc6e929bd661a0065a300bde8239d053f01cb4834ef012bc0275835ed00f062152b94efb48b5ab38eff572072ea7f3ebb415732382cc98cf6175bfdc7dc23b5c84cbb3d3b1bce6add3a450b83ab724c3f5b925f9d1ffe82feaebd76d254e60db3cdc94ddd94df96a6df79b52f2b5ff25cfb674f59e23dfe6d93eeb4adbeee077c36db80b9c701f1e9045b80bf5d0088f4dbc8566688576e8e48f477aa11f06611846611c26611a66211a62219ee723a0773b1c86648dae6a6914746eeb7c48874c1e66432ee4432114f3d02894be8bb6701c4ec0741aca951cf7695342f5b45459f3d669722a5f0b67e11bec2509e7e1d3ddb27f4a5fef932c71927ba52beeeca67cb5b6fb4d2970fa4f79b64bde73e4db3cdb675d690b9fc376d8095fc2d7b01bf6c27e3800a1768444ad5bdaa245b4045a45eb68136da35db48f0e911e818d8f8e911959911d39793ed74d90d5c5bbfd81222ff2f37900898cc228ca43f177f49214f32889d2288bd008abe478c7bd14e1c55275cd5ba7c95911110df74e4446d43b65ffb8be83b6a26d5e766737e5abb5dd6f4ac9cbf8973cdb15eff97779b6cf2ad1b68be88889d8888bf84888c4681449d1389a4448e0df70318de44889d4488b66d15b348f9ea2e7a81d75a297e835ea46bda81f0d90dcbb1d831665dc3287c82a5e94bcdbcb7819afe275bc4184f33561bc8d77f1fefa1df121d6cfedcb471fdaf7ea3b682be665777653be5adb3dd7bfebd9ae7bcfbfcbb37dd695b6888ec1a57f6cc6566cc74eecc65eecc7411cc6517cf354729cc4699cc5688cc5784c381a980e6332a680e89889d9988b794849ee265dc642e1dd8ec578144bf1389e80b8692c83a952a24d8db54bf9b3f82d9ec74f056df1f383b6efd5f7d176756737e7abb5dd8b35fe59cff68df7fc9b3cdb675d698bdb71277e895fe36edc8bfbf120419256b24896482bd4ebb425ab649d6c926db24bf6c921d113233926666201d98993b88997f857da92a0a00d592761122571de1fc327a08d99a48870aabf564996a0977e9565822578427ce97edb4377f59db49dddd9cdf96a6df7628d7fd6b37de33dff26cff65957da926142265442274cc2265cc227422226a344021c4637b48d9349324de44449d4444b66c95b324f9e809e9376d2495e92d7a40b39c9df02b4cabddb90b55ed2777ac9a089b614495be9e2d237b94296e932bddc0b78d0f6bdfacefdf97067ffbaaeb4a5eb74936ed35dba4f0fa99e1ae93135532bb5532775ebb4a55eeaa7411aa6511aa7499aa619109a62299e12e93025532aa57386989485bd246e06d73a7bb7530eb40ea729686ba6b04f3aaff552311d156d4a505cfe4e93749c8216673a4de5076ddfadefda9f0f77f6efa9449b92aaa996ced2b7749e3ea5cf693beda42fe96bda4d7b1767dae939abb49f0e32246b658b6c99adb275b6015a83a5258869650848cdef5c67bb1beff63adb67076493e999911d3333b3727e37999d39c5bd81cccdbccccf822ccc226459841eb47daf1efbf36774a52d8bb30454515986665886674436ccc88ccae88cc9d83a6d1997f1999089d92893b2713639690c4223102b80d42952be337ebdcb762a2793330590a76645cfc8b9fc6bfef3532779e871747caf1efbf36754a26d96bd65f3ec297bceda59277bc95eb36ed6cbfad9c0e74f94151e6c40018aa02d74812ed115ba4637e816dd81cf16dd83f00ac41e501d35dea56d8d1e331f35510bb5cbb195fcabebf2e3e8f85e3df6e7cfe84a5b30461dd4453dd44703344423344613340de4dc0db02ed1b63e796eaee329deaacecc0d6def3c5b528d5d3f68fb7e3df6e7cfe84a1b9aa1288aa1384aa0439444299446199445b352cb6e7d795fc8d973f3fe386c9fa3ad21d7e3e8f85e3df6e7cfa8c14ddaf81cf23bb435e77d9fb6a65aec96b6cb7b83be6174bfb384bba1f79ead12ce774551ee6ebedff58a7ff8e4c19fd383b69f518db67bcfe837d1763beedafdabaff769bb3e45792ef3ccda89b76f18ddefac4fd286f22848474574749fb6dfdbba8ffd197f4e0fda7e4615da60ef85848ed1093a45e5bbb46d2ab43533fa3bb49d6bb0336ddbd3fb25bf485bd55b812aa88a6ae8ac38baab21a8ab53a2d92382bea173b0de139a3f41571d07f09ca7f4dd35df46a347fc52b73596f647f5a0ed6754ba6e6ba332da415fd057b48bf6d03e3a40dbc80a43b016d60214ca65610b6c09e6ed93e41a71ab0b29278f5a75ed5b612b6c8dad776ab914f0cd8536d8a7dca4556f85dfc7b60883edce4eec72e8a4d372b34704db6307b0868ee61eb146a749c92b5ef76d347ac42fb4ddf5adfc317dce53f1b9f722d54b69587a477fd0b72d7c98f6eded8e2a6d98811d3113b3301b7330176d83231dc13cc01b52a3c3c7022cc4222cc6122cc5b28a229012607ee97dad1fd396b3f6bdb455bd1585f3e3fc6c773554ddfbf73c22188a61187eced7e034299575e3db68f28897fea3777c2b7f4c9fa4ed13ef453aebe29dfe5ddafe9c6fbb4edb6dda1fa40d0364600436c4c8968b51188d31187ba16d73a9c772611cc663022662234cc2c6d8a42211a4f018576e0bdef0d5aeaa42da89d10b6d405f1fddefd7696bf288e4b44d311953cef91a9c266567c7fbbe0da13ebde35bf963fa246d95f722951dd298faabdee97fc5b75df758df8e2a8efc51daf631a66133ec0d9bb7a8168d3d61cf581beb602f8db4bd625dac87f5b1018ee02d7c511688ed615d1cf6746cf0150e4721dd148ce11b7c0b9ddcf80e9681ef8b31b9f103a40dd70b97376e201b2f1fb1e36bb4d5c7bbc38fb809a656b107aba1f3ffb5704a347944909c3fdc861c5e3c1e75a749d9d9f1be6fe386b63bbe953fa6cfd1567d2f52d921fdebdee93a6d3fe7dbaeb2d498f60769c31ddcc53ddc5f208bd662b1582e623cc0433cdae7b4557be8f1184ff014cf7014c7701c274a42416c0a5287396d244e41da8a5aeb3c0a370e9f58aefabaaf690ca40db61eb10dce7e9eb6fa78773887f3a8869fdecc510d153a3b259a3c224d75e08dd3a4ecec78dfb7d1405ba36fe58fe9b35ef8f27b91aa0ee95ff54ed769fb39df7695a5c6b43f499b888f16f12259a48b6c812e30504d11b8848ff1093eaddf0fc3655cc1555cc367f81b3ec79ff067a0365007e805a428f8eba525299cdb88a551b84119b9af7b8577f350392d5f07efe17d7c80080442b488c5bfd887f6bd4e93bfeb5bf9fc9b27caef452a3ba47fcd3bfd2ff9b67f21ed0fd2462c97fe325886cb68192f9365bacc96e8122356c49ad8947b2fa0882db123f6c481d0098338966480980348d911e6a5974438f7585a14618175edd328dca510e180904b78846fb1791fa84004444884601e113191fc6bb47dafd3e4effb56be40dbe5bd485587f4af79a7ff1ddf76d5637d679ced3f48db4a5f19abe3ca5c592b7be5acdc95b7f257c12a245222bba10d2530d06c24882141121441130c104b70403c2180148c10efd236aad09687080984c680b6c985b6e9893619d0f68951d91f7a4f5f79abd2f9bd487597f5af78a7ff1ddfb6dd297bacef8cb3fd27697b5eb5579dd5cbea75d55df556fdd5608102285aeb05a1c26b27422b942fcf8837624e3c11cf449be8102f253d83d839487d2d726208229cd73531a20b967b44ff141a10da1021fa20ce33b1618b70860ba23f5c0e5780b270b8c63c44186e306fb87dd0f6bd7aeccf9fd195b675b646d7d81a5f13ebe19a5c536b7acdacd935b7e687bb26da86fbe161a80f8de171685e45bc80d83d48b5cab4151ada43074cdda107cb4999a10f68032148db30188680b668e801dac09501a8e13c2206b4c5443cfce75a92ff753df6e7cfa8445b77dd5bf7d703d0fc6b6d169be56ab0596dd69bcd301d66f089124801146ce90dd1136d18a00d6fa62de78b180e0131c32199af450de9213364875c5e127f0ee5693024809008bf09d46d31145877349486e3c7d1f1bd7aeccf9fd195b60db9a136f486d9b01b6ec36f848db84037a38d349c0ca737b4c9802765a80eb5e16cf8369c97f404621590fa5cd467a71a3184826b16ba965408a61531c552c11aa4ad98978f8e887ee8ab7ad0f633bad2366c6f3a9b97cdeba6bbe92da34d7f33d822dbd6b0337c19beded0d61df686fde18044c816b92097e40a7ce0744d6e40ec96dc91fb72ebb34adbb9a42b6fe481d4731dc803e292c659e03ad5258fe4f171747caf1efbf36774a58d34498bb4b7d136de26db749b6d51d2215dd2237d32a8d356d07355c115bc239d5fade5f7a6abb455385be55a5e95d3160241de0c32ca598b0a210e193f8e8eefd5637ffe8c4ab425644a66244a62244e12e49024498aa449866449ae4edb8d10922779c819c917d45d69cb53aeac01ce90dd89b70b75396b424e9b0ef8f2216b602a92235222c7e4e471747caf1efbf36754a26d0a85a0a40ca4ac3ba48af8580bd9901ca9c1678409ed5dda66e41be40bb27576af95683bd14ace11ff2a727e658e14901d2980f98936c4416cc0da847c229f11fd71747caf1efbf36754a2adbdee00c664b243be90af6497ec917d72403814b253b105d5a216d4925a51ab21bc4130a7d6b0562a7cd6d406a46ca925acd7e0fdec9d4aeda83db5271c200910c45307f26db822624a4748ca3017d4913291031943dec837ea405980b537caa61cca450804a73ccacf155021d4e3e8f85e3df6e7cfa84c1bd9a6222aa692c3914aa98cec512839a0300aa710c01a410d29d0b43cd140917340ca12438aa744cab441a71a45032114427884036baebc8e9b230ec5502cc5513c25502239a546e48872415db829aeee862b4a02b90884c8491b0341d626d4e75a92c2ded1456a4ac9bfb75639f4292fe32f3e81f06ed9cdcf317f9b1eb4fd8c6e68532895d2a819f546cd29947aa29ea93685807a87a43ad40bf50a3e5dc0884e1a440c6b2d0f3e7dbc02b42d216d901ce80c3d91e6c1f623190d57b04d49ada91ee06b4a89549f1a50031a4174ba452f288be4e92501ea39d2a057e4915ed39b32699fa70d4ee92dbdfbfdb5cefad8cb78abc39d276beb7ab7ec1a65bf5ae6afeabfe3dd06ffc13d7da075daa08f9ffea6bbfadb5eee2a6deb0e6dd2166dd30eedd21eedd3011d52cf7444c7808a17c04642b7400bb347a77446a3e771b769ac34ee3649e33411b0f410d46a4b78e72cef59042d4f72846034093903a451541fa1206f9447d3a0ec35cd90239a052d4d87de90eaf7d166aa3407e75597e13d0fe38dc7f01d2f63a58cf288b2f9f7d6de6ed230a2ecfdb2cf5b51da1ae1b6149aa70554a3c55b57e6c7faef78b7e9112dd1601fd2137afabbdbdbf8fd15fd6d2ff795365a06526895d6e819fd46cfe927fa19f0d6a63b402ff42ba0ac0d3f7497eed1fd8fc6dda6076408fbf1291d12047b16e9572aa011c05a3fffe2162540da98051412324bbac7ac10033930eb2b65cc06ea2bb4315b26afdbaa2ec3773c8c558fe13b5ec64a19e511650bdaaa6f37691851f67d9f64ed08106e4b61f6e0106218fdd695f9b1fe3bde6dc6602a755afd2c56dd3fd7b351f94c756f84f0bfefe5bed2c6ac1893b1189b7118d7c6188ff19980099988899998f29804c198941a3129ecb964b28fc7dd86a43128f46ed36bf2890a005918833304336448065cc03134c3302cc3313c02fe194804a7b44c4e6912fc40a1aacf5eb731a2b5664630547519bee361acedd1fb5ec64a19e511654bef62b8bcdda46944d9777d92b56353b82d25e019e9fa3686db316ddfd37fc7bb1d1c82ca1b41eb67b1dafe299fd32e69f74608fffb5eee126d6366c24c19995118d5b4198d99316fcc9c79629e9936d3615ea823f3ca74c1a7c7f499c147e36eb308a5d36bb6c52e1021afad421a6197ec8a69b16b76036963b7ec6ec5b17b169c3e589d35c00788122861c581cb3eeaebb4816371c11e59b3f8af965d86ef78181bf668b397b15c466544d9d3515479bbc9ddde8ef77d928d6eef0bcf65da6ec7b47d4fff1def769db6fa59acba7f2ae7b44bdabd11c2ffbe97fb4a1b6bb136ebb8bccbb32eebd16faccf066cc8466ccc264ccaa64c1f411194e9533cc5b3d947e36eb328600d63d6eb0ea04d205f591c9045b043401bc9522ccd2020c45003966539401b8f08acc08aec8895d8313b61a7ac0c2903b10aabb2da57aedbd819fb567519bee761ac8ee37adfcb582ea336a26ce1baacbedda481b6f77c92e7adb86c4d036dec9c7d02d39cb6a6316ddfd37fc7bb0d2acd4a7d5d3d8bb11df605fe8f1bdf4851dbe7f5372dfd8497bb44db2be3b25dd67525b6c7f60169030ee15adc825b722b5a2e4803f55a0fd2c6ad3f1a779bdbd05d70dd9513033e14ec1bb1286ecbb4b81db787751b0c5103eec0edc1145c7d7006a773476bc999549fb3381bd66f20d66104cefd8afb91f338bfea327ccfc3581dc7f5be97b15c46b5bce27b6b6f3769a0ed3d9fe4792b2e5bd370fc70011772111773c9cd167ca8ff8e779b4bb92c7c835472790f4df52cc6611c0ea644d3fea99da998fa9b967ec2cb7da58d1b7224477134c7702cc7713c27702237e2246ecc4d6e689b7e34ee362717ac41da0ad64eb4519c52a14dbdd0a601da6660fe46f5290fb4060adae680b6a7c7fda15b71cff0bcceb5b9ceefaffbdff16e835ff8c2bdd23ad7e57af9b757ce625c9f1bf008df6aa2ad76a662ea6f5afa092ff795367ec12ff915bfe637fc96dfb932bfe70fbcce1bfc9137617f2539a58e509038defa68dc6dde5e28392f80988502aec6006dbcc3bb60eab1d44d083049e542c0555b7edd2614ebf23e42f1c183b65bf1211ff1319ff0e9efaffbbf737ffefc08e125da321ee5311ee7097ec8936c0f546134cff02ccff17c712fae78929217006de247e36ef3a38235c09cc04b0549fc989f00bea6bc9cd3560ee594e5fd2375da00b3bcfabff3e8f873fadfb73fff8d11c24bb469fc8c7fe3e7fc13ffccb7f90effc27afc2bdfe57b7c9fec15f7db2ec40d3e1a775b40202d424b582082b0109690246125ac1942d8085b1aa111619787f6c2811a40caa809e06d02e7600a388379c0baba60080f7fdb37ebb13f7f4657da0453b0045b700457f0045f088490f5844888854448c91e0569eb51d9ba43776952c87e61dcedbc6e038ca1020a5b923004092a0bc6c194f3ddecb3ce794fcc518fa3e37bf5d89f3fa3126d984d09b840f034eb084381044d3fda4e044660050ed246bd82faed89ee01daba022f0882288cd083200963742b4c8429908c1e40cc48987813412948a2044115b43269880eef74237a85b83367a727b62e69427e0f6eb07e59bf3ef49dfae9e3ee7fa74ab4cd8437612e3c09cf425be8082fc2abd0157a42ffd862d6a45ad46d67dac8367ce908e5314b61408a22825862cbec2206a8f990e26a0dea429b7aa52d7ffa31a8d66f8c50a22d2cd376bae33d1017e202f66f8acb832eaec4b5b801dae6dae59f9db8170fa20e3e46aea3688a16902d3a2067f171e15126ba79a85148ebfe07ace9893ed84f372a6245d8937309dde611c39bef73ee6fc9b7281263311153311351111371911087222952222d328fb3d7cfe84a9bc88a9cc88b82288a235112c7e2449c8a3265c0be4870bd96bbdfced76dd4919cb2b8a8882a7cb651d4c499f8662e2893c5f32b3214f674ac38162fc2058157d5c3e7e746e0bc9e5213630cc21de06d7ed153316fa5e2b3d8163be20bd02b5057ec894f20b62f0e2e39e6d1788480987993462df059bcf3598e56a3458356ef84aeb1ebca776d46dbd10e6ed117f494eb6e7a2b1ded4787913e3246c79139b246f6c819b940dec81f05a370148de251324a47d9081d61237c448c86d00235a2470c103be246fc48188923f8278dc6e033c935059281142075a48d66a3b7d17cf4347a1eb5479dd1cbe875d41df546fdd14042a496b49096d24a5a4b1b692beda4bd749074c9908ee01cf9d1d9a27a2eb26ed2e1d9149eb11cc9cc6549e629652b5ae01b22312a528a9224bb2a90ea9c95e775252f9f7ba7b97f4afbe259560aa4508aa4584aa4b4eedd2e449350e598ba68326709e461ba520648332843cae0338ea046c2af6aa2ed0ba291913138e8ad9b3f099530099708a0a1440251122d31209eade4e224be65deae7d4a15def9e092288d24a141a377429758715df926491a4b13692ac9f7b6e5a33f8991945c4c2d5e05bfcfccd3356926bd4973e9497a96da52477a915ea5aed493fad2608c8c5be3c578395e8dd7e3cd783bde8df7e3c3581f1be3e3d81c5b637bec8cddb107967c04fc81b9350ec1dc05b2f270340ec731584ac6e9381ba3636c8c8f89f1704c828b017acc802576cc0125631ea461202c8cc5f1682c8dc7e3c9780a2457cf1c63e524192a3f27ed4f671498a6c2b44b581b6bf5b34bb1de5570fd4acc6c3c6ba550e03c0c555ee3ed24f9faed9733e317cfb2e3f9f869fc3c6e4335d3f6117745ec39853a4a19c5522cd32de8fa73b49132428f3be21219d5357e419e5ad9f815a80bd41bf775421f82142e4f9f9e72054704c44c6fd747462d14a40fee7ff6e804190f6e558dbd9767d22a7fd76431594e5693f56433d9366dcbc7d28793dd643fd9e9c3fc57c2320f40fa29cd981c27e6c49ad81367e282cb687f124c42a068124f92493ac926683ed81e3e2126c309091af1f48499b0136ec24f848908aa306902a098d4ffc693692e192c29402a900634037a039a4f9e26cf93f6a4337999bc4eba608ddea43f194c665364329fb6a68be972ba9aaea79be9069c17cae78e5cd32dd0ee36fe746651cee1f2f965baff95b313f8ce5d2ef00d123d3d4c0fb552d6d5fcd76ffaea5976aa4f8de9716a4ead49bf4edbd49e3a5377ea55a97aaf962b729de6396b45bdf747eab6bb5a28f06d2a907af14d7c63525a86df0ddbb3f0fa514061ef2842f1c2d42f424d02fbe1ee0781cfb1b7c6c1ad8a5804349baea1db3cc8a274ce50a6c1343cac0f9b69348d3ff77b616fd3b5a709debf3cc783146c9a4cd3693645a718100e444c87c525c049341033dc4ed92937e5a7c25404cd4309543893e9742a4f95a93ad5a633a0b792e620fc04e6cf4073b0d406cb9de90bc8ff3aed4e7bd3fe742023724b5ec84b790596d6f206680bb493f7f241d665433ecaa66ce943d996edf18bec4cb6f06c03cf8b40b88ecbaeec4df4e29c713daf5c257bb2f7de39a8be6ec3598ad009709602ba96dafc6de06cb68367b3af9e65655f0ea67d39942339aed32627722a677070de4dfc1e6df953255d383db72acf6cfd0c6d90215ea04c2903d790335a16d5336d850ac60414d48ef74a987cc0db47b4d1bf469b8ccb843cd43dddd7033d9449999269187fddd6f31683bc8ccc22976b59999379599045397f724096409367224f65f94c1b8dc80a22c82a45c99a3c93dfe4b9fc243f43d2e4b6dc915fe457b93ba5e49edc9707f240419496b25096ca4a594f3365a36c959db2570e8aae18ca5131154bb1154771150f7c5cb064293e108845042550c23c2e02cb3150a2a44aa6a00aa6e00aa10c1552a1145a611456e1400e56e141aaa088ca889cd3cfb4ccbc527c71ad7eed2d637124ef51cb9f84e843b77171155ff49441c1544183fba6ba66717cc1f8e209c1423007fc9cf7deb92701f6d2957be2cac7672946a77c45826fecf8f25976099ac01365aac88a72d3924c1415b3144d99296ff75b92ca1c119527e5596937e85979424489fbdbb4c13b7bf00cc0a44a4704ffd8326d301d7276e5ae495fa9db9a4375da9417e555e92a3de3cd981b4fc6b3d1363a4a5f19a888da6aa24d5da8cb2b6dea4a5d83e946dde6a11ddcb3ea5e3d14fb58d555433d22826aaa966aab8eeaaa9eeaab01a44d0dd5488dd54469c19a4da1d554cd5454c5547ccaa9843a5449955269955170955539950787b57861cd3bf1e6e731b66281ef18a99262ab637502964145a8ca80385a5540a5a8aa9a3a53df40492a6010557840db549dab4feab3da563bea8bfa4a6f1052edc23e37e84c2eee07e53add5d5d28a7d7dae482e4a83d86e2744e57fb9450ec1d90b35708b0135c8fb4f33ddcc2ab5c7c4abde1674daab4dd0ad256bc8beaab675975a0215a4b5b68cb7057a54d5b696b6d03c7ddd6b6da4edbdf6b3bb6d083deca0ec6e1d82003a4e82df4efd306fe07e7ebc9d3d563f19f817da465dac0fe6b2ae14b75dbafd0a61d345d334cdd34cca3699a966983a963baa6a71d355379b9f3cb6afdb49aa5e5fe8862cf6a8ee6164787e669be1680637ba4855aa4c55aa2a55aa6a1803642c3341cbe664923cfb46994466b8cc66aac4a689cc66b8226aa9e36d22455d6c6e0526c0a4a72206f60ee6ab2a600ce5c4dd5346d8608da9b36572ced497bce69cbb4b6d6d15eb457adab3e693d90ded7063364d69a2d66e06c315bcdd6b3cd6c3bdbcdf6b3c34c876f919a19b3e3cc9cc1b19831fa199e1d45a5a06d66cf9c993bf3667efedf1266c12c9c813a7416cf92593acb60ec0c9d61337c46cc86c24018ccc819c5a4456be6449b0079bc50ac97680397a80b85d9c0fab1a8fb9a94d789603df29946befa7fa7d0193d63243eec849dffeffffddffff3ff03c4a1599d</data>
+ </image>
+ <image name="image14">
+ <data format="PNG" length="72078">89504e470d0a1a0a0000000d494844520000031d0000028608060000002f4ff6a70000200049444154789cecdd777cd554ffc0f14f7257dbdb3da105cade028220221b14151085475c88282038708b0b1170e2401e1004791c282e501027a0b20504454096ecd99652e86eef4c7e7f5c7abba72d6dfd7ddfaf575e34c93927e7e4847bf3bdc9499401cffe46417b7ff94a2fb450082184104208214ad125e6b0527099115df3ceec5dbd4c0778f9f56917b15a420821841042887f8b679e98ac031c5efb8437f830ea17828e7d6b96ebb3e64e0760d9968ceaa89f104208218410a296cb89299af47e52cf093c8cbaaeb37fed37faacb9d359b231b55a2b288410420821c4ff275df9a842f9b630b2c696951353cc9a3bdd1b78e4bbbdcaedd28acb2f841042082184a844571a173161c2848a659e3d9b5f5d236a7c593994fa5d27eacf4c99c4cfbbeca596d1587f153db209c6c40e24bb2248320557ac32420821841042fc3fd6cbe733264c9880d3e92cb44e5172c761eb7ad1cf7732994ccc9e3d9b75b65bf39595376f59e8ba5e6c5900aaaaa2eb7ab1f5c8d95ecefabc6501f46f67e1e5292f620470385cb89dee522b95acf7e064bfe958329650efb389b8b9b45c8d12420821841042003e9e7fdceedc7370455170bbdd24242470f4e85182838369d4a81156abb5d049bfc964f2e477babd65e9bace912347d8b4695399aad0bb776fa2a3a3bdf379cb72bbdd288ac2be7dfb68dcb8312693a9501d545525252585e4e464626363bd018cb72c3c71067021e870ba7195e1d6aa80a0d5289a8acbe224307a0d2712db97a94142082184104288c234cd730eae280a0909094c9c3891afbffeda7ba5a161c3863cfffcf3dc76db6db85cae42f9f39ec36b9ac6ba75eb18376e5c99b6bd64c912ead6ad5b64598aa2b061c306860f1fce0d37dcc09b6fbe898f8f8f37f050559553a74e3172e448ce9e3dcbd75f7f4de3c68d0b95e5b8107c78830eb7abf82b1d75f5dff169f423fbfbee45752b181c26765cb79126eb5270ed1bc20963bb32354c08216aaa16edad8cbdd2171fb713549d63fb4e316de979ccd6308c96800a95d96d4008a39b2824a72572efcc63ac9bdb9b7e8f6e07c0e21f5999d5afb0eb4784d2dfaa83e6a269fd200e9e4801c096769207de49c66c0dc3e41354a6b27e9856cfdb3effa818a6dd17ce81afff62ee361b666b1806932f00aad1c0fdb785d0d2d78d9e96c433f38e91640ac1ec1702e4de16307c6830fd1afa503fd848f77b5662f18ff0eeb7a8e6569eb8da178bc389d9e0e4bbaf76b1e4901f66bf3054a3a512f790104254ad9c2b1d168b85071f7c901f7ef881abaeba8abbeeba8bf8f8785e7ef9651e7df451ead6ad4b8f1e3df25d1901f29dc3e7043015d97e5165eddab58bf4f474162e5c88cd6663c68c19040404a0280a870f1f66f4e8d16cddba958080000e1d3a942fe8c829cbe154819ca0c351f4958e40259ed888cf38d6733f69f5cf63cc36010a2e1f07c66c337f5ff327d60e47885e751519e7fa719e887237540821aa5b78f320a65d6963ccd4b51c3c9f866ab2d2ad6f3b1cb64c74d5070cd60a95fbd8155606debd94e4cc64fc421b3372eaaf381d06000c95f0e00e830aee7f58cce279475894750e677632bf2dbc81a10f2c04c037b83e66bf505c2e0da50c753578be53c84c89c737249c57ee0fe3b70f563367cb392cfe91a8961074c553ce25832289debe9d9b961fa3f955bd997ea38b5b16c5e3d6947c01ce1f9be3f9eea3e37c39a33f5929f1b85c2e0c3ee100bc7c7330339ffa815527cee01fdd94b5af77e2c3b1bfe074baf00daaf7cf768a10425c449aa6a1280ae9e9e9242626d2ad5b3766ce9c49bd7af5301a8d1c3c78903973e6b07efd7a7af6ec5928b0c87b0e9f73152232329256ad5a153bbe43d33476efde9d2f4fc1b29c4e27a3478f262d2d8de9d3a7b364c9125c2e17b366cde2dcb973de8023343494993367d2b76f5fec763b168b255f590e47be2b1d85c77404aaf184b77b8fbffaee413768f82506a000b6c06c0c4e0306978a352188cca854b26eff8ac61bf7e3fc7d1c29ee9af1eb9d104294d54d37faf3e1733fb3f7743c8ac18411131b576ec3e41b8ac1e546351b79665428f58c2e0cf6545e9db997dd5a3026df1056bfd19447bf4ee0ce4b7c880c33b162e166feb7d787579eba145f15e64cea4ac2d60f79e42b858fe6df4de711cb00f08f8ce585b1618438b239ba6b3ffd065fce15a37fc168f167c3dccbe971df6f0098ad91fcf27a23effc86b9973379452237373793bc7137cffeeecbc47b9bd3cc0a66839d8fe7fdc9caa400cc7e6128aab1d4b6bb5d6edc2ecdfb8b54766a3c0016ff18dc2e0d1fb30f93ee892cb6ed79eb020dd00d1a73a75ec29a392b98bbf108467300468bfbc2778c671bc3db1a9933e730d9a967f97be516eabcdb81ecb7d7a26b2a6a98bfb76e3b77a761cf747aebe576b9b186b506e0f764177e24919d1a4f7083a6d8528e93951287e606b35feead02420851d3e58c9df0f3f363f1e2c5389d4eead4a983d3e9242b2b8b63c78e613018888989c1ed7617bed291e71c3e675d9f3e7df8e0830f5055b5c86dba5c2e860d1b962f4fc1b25c2e178aa2f0d8638fe176bb993163064b972e252b2b8b53a74eb16bd72e22222278f5d557193a7428369badc87a392e8c93cf73a5237723418604a25b7ec481abfec2e030628d0f26232a15cdecc69cee8331db4466643aaac340d089306cc1591ceeb99b6659efa1ec1dc3597b68f9f6b6104254a3abfd55fa9d4844d35502c25a61f1af83e6ce7da2dfc0d191642f5fc70dab4fd0e08a9e7cfc5830fd9f3d8dd9e5069ad2edef8ddc32ff04a14dbab1fad556cc1af32b8f4c4ae28f4f6e60d0ddb3505413a18d1b02e0be706962f098081216af61d4da93c476eb49bfc19071fe38663fcfe767d685937fd512966f1ee0f23deb1936f3287e218d193e7520bb3ff889670fa5e31b5e8fd5af3462d97d7fe172b9b0f8d729bdf1062be6002be680fa00f8863401c01ad5018021f7372cb1ed79ebb27d247c36fb3abe7dfc19e61d8ec2e81384c93f0693b52eba62f67ecf5ce2a3b03d2d0bd568c5ec1f81c91a83cbe9203b3d114b50a33c75f3c31cd0c0f3a74f289aa679cb7875ca76de7fed76ee4ece203254e3d1bbde45d302d17425dff7991042d47439572e323333f1f3f34351141c0e0766b39951a346b162c50a3a76ecc8c08103b1dbed850673e7fdcccbbbcee17014f9642cc81d845e308fab885bb5344d63e2c489984c265e7ae925befffe7b0042434379ebadb71832640859595985b6915396c3e1993702389dee7cefe888f5ddc1915efb31669bf14db69256ff3ce8e09f1084c3cf8eaeea049c0a213d2699d4d87358133c97c38f77df4fab233b49c8ec55f45e1542881a4807745d45075473289e1f7d72c7058c883670fd2f47b0a59fe3e8c6f5043d720bd9a97fa0699ecbd62ffc7c105b5632a9a70f60b676c1967a06c5680640d374147434b7e743dd969104c02d510606af39822dfd3cc7376d069a624b4bc0edbaf0cb7eda19007c435be79b07787ee5016c19e7b104c4724f630b89632e67b0e6c997e1f22523f16ffcc2c0e853fe2bcf394151ce7742696dcf5b17808fd72532fae68ebc3ff520582f041c980bbd074a77eb68ba677f03e81ab8ecd905d2192e4ce0f9eed3bcebef7eaa23bfbfb584296b0ed3a8db352c7ead3b57dcf7279aa6c83ba78410b5caa953a7f2cdabaa4a58581813264c60f9f2e5f4efdf9fb973e762b7db494e4ef6a60b0ff7dc6e9af7332f3131d1fb777a7a3a494949456e3322c2332442d775ce9c3943707070a1b2f2d62b383898010306b070e1428e1c390240ebd6ade9d6ad1ba74e9d223b3bbbd87a39f35de928f0f42a539d8338026c041f8d20a5d159cc19167c92ada4d74dc16837a2e80a197552093c158a3d209bcc3aa9841ea8c3f9660998a20ee23ad3bd845d2b841035cbb7a92efe136ae4bd330e5c2e37aa9eff97721570bb9c28a600fcc2dba0e379a4a12dfd2c00598a0f466b5d7c435ba1282a1a062e0c5fc012d81000a39fe79184da85937a1dcf256dd51c884f680b0014831f9a5bc3ad036e0d0d705f0856b43c833752f1c1e41f8d25b8290605c6ddff01c7d2cee11bd214b73d15a36f041aaaf757a6e84e7578f56a13bae666fbec0dbc7ed61fa34f08aac15c685fe46c27276f696dcf5b1780f7a7cd429d3c81efa6d5e186d74fe0c8cec0e893ff36afed591a6d2d0abf65ba514d169c99099e6047a1d8ab1405eb757b3d235d3727e3d6748e6ffb8dc069f7a0697fe27239e54a8710a256311af37f469acd66929393f9eaabaf68ddba35b366cd425555b2b3b30ba585fc9f9b79d7abaa5a64fa9c75390c0643896505060672ead429c68f1fcfd1a347090f0f272323834d9b3671efbdf7326bd62cfcfdfd0bdd5ee5bdd2e1f47c8f796fafca4e39e24de4f4b3a3b855dc661706bb11dff3fea43638073af8265b51dc2ad9a119a4d53f4ff0d1083493862d241373860f593e9964a71c2eb28142085113bd3bdbcdb2c997b2e2de65c49ff913935f0457f46dc1af3fed02e09d23b13cd9d1c1c36bce11d13a92d4a3eb706426a01a2e0c96b37b9ef8e4c83a93ef5f007b6602c085cfc556def9f74fda78bc9d8dc7372413d63ce242be04148385cd192e6e083acf67a76d84c47a3ef46d6927502e04092e9b677bf68c38fefb770ba65d65e2968fcea09a7c69d4ba2ea78e66a2d88ddecfe243abf671c3b769b8ec6900182d8118edc9286aeee5758f5605ea5b86b6e7a90b7444d71ccc99f82c7e73dee4ab87b218f4ca66f0af8bc19cfb04b077374731a1a79bf54be2a87b8995b88d3f62cf884335f916f3fd51b85ebfa43565646c0ab3766713d9a11bf6b47dd83313703952e5e95542885aa5a8a0e3dcb973346fde9c6bafbd96b0b030ce9f3f5f6c0091f773336f005196a04351947c79f296653299b05aadc4c5c5317af468f6efdf4f83060d98356b16870f1fe685175ee0a79f7ee2de7bef65c1820585028f9cb21c0ecf13adbc03c90d86dc88c72f29005dd130659bf04f0c24b5fe3900024f86921e9d82aeea041f0b27a5f159521a9e25f85804283ab6e04c7c12fdf295258410355dd2ce3fb9777933de9cff107e6e17188c1cfa7317ebb2e2315a82f9e2f99f7875d20856dce1c4e84866fc849f510d56cc7e9ecbd1aaeab9d528e7b32f67bea4759f4e59c3dc69635879670ac776fc81a6c5a0bb6d184c3e4c7eeb0fde9b7d3fb79d39cfa1df7f079a5c58e73999562f946530a87c39e5075a3d712b9b87de825d3113bf7733f7cd8bc768f2f16e5343453528180cb9753118549422061816ac6fa96dcf531700934f00aaaaf2bf57bec032f956be795267c81b07c0a07a038f1deffec28949c35871ad1b25fd14773fba07833100b35f288b5fe9ce4d4fac00e0a617afe39e70cf97e1e6250f931eff0d43269dc6e41bcc8b93d733ebc9f10c74d9f135da99fce07c0caa1193c55fbe838410b54ac1c0c06030101111c1edb7df4e6c6c2c0683a1d8e0c193bef0550b4dd3301a8d8486163dce5a5555ef988dbc65e72d2b303090b8b838468c18c1c18307a95fbf3e6fbffd36575c71053d7af44055559e7ffe7956af5ecde8d1a359b8702156abb550590e67de97033adc188cb91b3911d78cf0bf0fe2b4da415730675a70f8db4101dd78e1d60083e75289a229a083d16e22f85804274e37cb57961042d474aa3598ddebf770ebaa5f713bb2508d66cf5b557d823c9f67ba9d479ffa02972d15cded405183f0f10fc2e417469bc1b3f1f1f70cf63618d57cf325ad539c76c6dcbf10872d953a1dfad0add70614050c4623e7fe3ac0c03b37e3b4a5a21acd3cfade93f8048463b404162a5377c3941796e2b2a5a2eb1aaad1e742bd15ef67b1c1e883c9e2034495b81f0a960de0b257a4ed6158022298fbe2c7ccb6a76330fb6334a8b9df0dba81e7277f89d3968adb9189c11c8ac51284d91aca2d4faff2a65b36f5271667279375ee209ae642510d58c39aa11a54b21312b8f3818f71d9522fd4de074b403026bf30f90e1242d42a45051d070e1ce0c9279fa46fdfbef4ecd9b3e4a0c35838e8f8f5d75f19397264b14fafd2348d1d3b76e4cb53b02cabd5cad2a54bbd01c7c2850b69d7ae1de9e9e9288ac2a851a3b05aad3cf6d863ac5fbf9e8d1b3772dd75d7152aabc02373ddf9229ba3990db974d515240e5d8d39c317539699a416f118ecb997e20d179e351f723402d569c4e9672762792ffecc6c489eba0b2144cd67b0a01a2271992c9e13615736aa6ac268f6c564f1c560f44555155c260b2e7b1a46b33f469f208c3e4118f25cd53018547cfc8b7e5f51c17501512df9fca59eb8750d3f67224f8e9f81d11486c52f188b35d47335c26446d75c17ea1188c1e457a84c835f20068382d3ec83cb968aa21830184d188da672ffe29fb77e39790dbe41156abbc9371055557139d251f07ca979cb34585195080c26332ebb8fb74c934f202e5b9ab70c4555d00c2a16ff7074cd89a2185055c5d36e9f500c06034e930f6e470606b3df8532828bbc82238410355551414774743477de7927ad5ab5c262b1147a4c6efef4f9838ebe7dfb12181858ea76478e1c49972e5df2071d79cacacccce491471ec1e974326cd8309a366d9a6f5c49666626c3860d23282888f8f878060c1840666626414141f9ca2af446f2825f4ebb123bd161898abbed7edc1627aad3407648267e670370fa799e7d1576a00e4127c2306559d00f376647524709388410b592c1e08bc9ec8b6f50d18f99351843c01a5268b931203c7fba02f3c5ad73a49de0b6497fe1b2a5e0c84e467737c61a1a84d92f1c93d982c91c856f60c95726bce5fa0563b970bbd33f515cdd2bda76835f2016bfa2bff88aabb3a1c076ccbe8158431b145986d1148e4f09fb5b08216a83824187a2283469d284d9b367039ef76594f5f62a4dd3080909e1aaabae2af3f65d2e579165298a82aeeb3cf7dc73b85c2eec767ba17a389d4eaeb9e61a745dc766b31518a09e3fe850ea779da8b7b8ec7aec799e495f50acef5102ace708349f4337e8a86e155dd149b785919615c6f1ec46c5e61542085198ae6b38b3537066a7e2b2a763b45831f90463f20d2ad34bfd841042d47e37b5dac38409132a9477f6ecd92cd9d7a6c697653158f8fbf76f3c4147a3f603514d7a09d985104208218410956d68f35d15cab7f440bb5a5196e65438baf37b4fd011d3ea1aac41f2cb9a104208218410a2f264a6ba38bd6f45ee988ec0225e12258410420821841015956f20b9b38881e442082184104208f14f38f3061dabdfee54ad9511420821841042fc3b751cbc1ab9bc21841042082184a852127408218410420821aa94041d420821841042882a254187104208218410a24a49d021841042082184a852127408218410420821aa94041d420821841042882a254187104208218410a24a49d021841042082184a852127408218410420821aa94f19f16b065cb1676eedc59197511a2d2b46fdf9eae5dbb567735841042082104ff30e8c80938ba74e95259f511a2526cddba1540020f21841042881ae01f051d3901c755575d5559f511a25274efde9d19336648d021841042085103c8980e210a48defb238fde39844b9a37a44e545d9ab5edcccdf73c5da9dbf8eed95b6956bf2e03efbc9bed194e00c68e1dcbd8b1632b753b9521222282888808ea35fb0f4efdc242ddc9b0a6f5bcebfe49b9dd1e595b685945cab9d8cabadd173a3521222282170ea6e42ed41df4691843645434db321c35b6ef85104288caf28fc77408f16f92bcef3d3af77b8674acdc74ef23f4685d97f4b843acfcea23e0954adbce03efad26d3adb1fcc3f7312a9e650b162ca8b4f20bd15da0fcb3ffeef694754cda7e96e99d2238fbc7b3ac4fb5574ad58e7c318ebf5edacd257ea64a29af4a55603f8e9cdc895963d6b0ecf92d3cf7e93500241f7899dd990e429a3d4b677f339dabb2ef851042881a40ae740891c7fc3b5f21d5a53164fe1ade9efc1037ff6738631e7c86256b777bd3b8ec47797eccf5b46818434cc3165c3fe6798eda5ddef539bf802f7b753ced9ad4a3418bcb78f9fb93f9d667ba3500ea464614ca97c396b48ee13ddb12d3a005a35ffebed0fab2ce7ff4d85062a363bccb3547226f3d760797b668489d3a3174b8f23ade5cbaa7d47d3328cc97af1ffe18808f1efe1adfb041f9d6cfecd982c8c83aac4af60423497f3e4a444404dd27fe5662b975d534ee7bf1f722d79556d7e2dabffbcd7e44444470ffae7380c6150da28969321880b8f52388888860e0c78780b2f767c1fd98d791ef5ea25e54242dfa3fc449873bdfba9801af126054895fff0ca92ecfa5a24d93970370e50b3715aa7b69ed2e4fdb841042889a42820e21f278ff543a002f5d5b3fff8a3cbf6e7f71fb0dcc5dbe99a6773cc7e4914dd9bc7c2e37dcfe45a1b2de3add94c71fbe9eecf3c799fbd0c3dee5efbefb6e917f17aacbf071acd977860e773ec265996f57b449bc937939afbd3ed93bbf6ccc35bcfcd10a7a4cfd824347f6317da88be9e3fbb1e0647a89e54c9ed695e4bfa7f3e9be4f79ed400a5da74dceb7fe8eb76f46d7dd4c9bee799adddac93fa1280a4f3dd5bec472178c6bc9c185633990ed2ab4aeb4ba16dc9739f3b1375f07c01f0b0e613bb78cc336378eb42d6c4875b06f8ee7e4fdb601d140d9fbb3e07ecc71fcc757e835e6bf04751ecd861fdea2bed9906fbdd1a7312f7408c7653fc9e41d49e8ae649edd9880c11cce2b3dea16b94f4a6a7779da26841042d4144afdae13f5eddf3e51a1ccf3e7cf9781e415e0b6659079782bd927ff20ebc8afd8137e433167a3bb4035c5901ade1b637427225b7625a659ebeaae6ead949d9dcd8c193318376e5cb9f235ab1b458a4b635fdc19c24d45c7e4ad62ea90e470b3e7f419c29524a2a2db60304790707a2f90fbebfbb65309c49a9c4446d547510c24262678cbc84973f6ecd96297e5db0e8944c55c926f7dc1f4c5cdff7a229ee6beb941539b983a243adc180c3927c71a6eb7cea5cfaf67d503ad0ab537a79c33a7ffa253e34b49f453d1b2a2d871e477dac644e5d9a6c65d2d1bb232ab3e7b0e7cc5158d3be0aaff20877e7ba6c8fd98536efc895f69dfb42791f77dcfee99d7e46b4359ea5ad4bed4b52cdad46f4c56c808d6bf7a941e13a3e9e0584ad087bfe3bcbb0beb6cb19c3ab111b5e07e2ea13f0beec79ce57e06154bd3bbf96dedcb84e4dc2b57c0d93f1ea1f5358b88ec3c8b35537ea5cdc02f88eeb1809d4b6f28b20d25b57be57db1656e9b1042085113741cfcba8ce9b89852138e93b1e97fb8ce7e814fbd43581beb847406a3151403e83a68ae5438bf17473c24fee6c3af5f77c7d07a349dae1e86c9540bee79afe5eeae1fc08ca3a94c5a798a79831ae459e3063c2780dedfb1152067607511a7780d2d066f6a5d77175a5f564abeede432280a6e5dc7a681c975bad8fc794f94c1536d80c95fafa44f90d9bbdc14105b623d54731d66dfd4881b171da4d91db38832176cb3ca94577bf0ddd855dcf1e6dd9c73ba19f2eaa812cb0430fa3667c1c8660c7ba7f040ea8ad65551fd78a84120cf1df98c1f670711d5fd31c627aee389d73ee14cb28dc84e8f787bacacfd59703fe668136862fbd1af59fed7e38cba34acc834e11d5ea089cf171cfdf339de7fc2b3c5212ff52cbefe17fe2daadde5699b1042085153c877d345a0b99c1cfa6626a9df7625b8d58bc4de7390a881adf16f7517e6b069a83e1fa0983e45357f82d16f2ec67a8fe1d779200d470472e5033fd3dae75636bed68f9d5b36567753fef5c67d309100a3cab2b17d79f0c5d92cf9ea4b3e98fb1a37f7bdc49b665a7fcfad2b77bff83f16bc781700d1fda7557a5d1e6c19ecd9ce0bf37967caa842ebbb057a4e46a77cf61d1f4ebbbbcce5be34a01e00b39e7f976dbbf6b063eb3ade7bfd29267c7ea4d4bc5da6bdc5942953786b6ad1efe6a93f6836cd7d4dfc36731b469f46bc51cced4305759e349700ad70e05496bad6337b8281198b16f3ed0fb963437a8f6e82ae3978fecf24daddd394b6f7b62471cb6b00b49ad0d99bee9ff6e79235efd3c490cad383fbb3787f4a916914833faf5c1383e64ae5cdbde7315bdb31a96568b16596d6eeb2b64d082184a82924e8a8622907b77170ee3584873c4283b109585b5d0bcaa7c0329cb657c9387f1f9929d79199d297cc947e64a6fc87cc94a7c94c994f66ca8fb88c5309ecd7983e133660dd79352be6bd486666667537eb5f2bb4cd3dfcbef23d6ee9df8ad50bdfe0fe7b1fe085599fa3351eec4d73c3ff56f0d46d7d39bc702ad33e3a42dfdb9e62c5ff6ea8f4badcf5c53c7ab78ce48ff767b0cdf71e0054638077fd7f67de4b6ca82f1f3f3b918dea8832973bf8dd55bc307e28c171ab9838e13e264efb2f7f26f933e48ad21fff6a0eb89cfbefbf9fcb03cc45ae578da1bc3dae39000d87ce20b898db8d0a32592fe1dde18d2b54d7390f0f2232c0c22b8fdccf038fbde75d5e6fd05000dcbacebd2d8389ec7c27baeeb99431b65b9437dd3fed4f6bccd57cbf7206617a3c0f5f7d2ddf9fc82832dd6593477aff8e1dfa12e612764d69ed2e6bdb841042889a42c67454a1b4bdeb48dff01f22872461aa531f780a188027d6b371f6b88e7f881f261fb5f0ed338a4a76aa0e8a4e407802f00eb090ac353aab575f4bf7c73e253838f822b7a8f6a8e8988e9ac491b18d03e96d685bd78f63aba7d0f9e6398477789e7d3f3d50dd552bd66fbf6d66dbfc0798f65d1c0bf61d6548984f75574908218410d54cc67454a1c37b7761597b1331a393502c97015380c64032a0e1cc0645f1c5375001b402b91534970b7b663221f59c8019980834c2afcf8b5c13f5233fccb89b01cf7e86c562b998cd121791336307a3ae1a41bac34986d3cc1583c6f0f2ac7baabb5a251a34e87a4cbea1dc30f133093884104208e125414715d0759d84e513b972cc59b05c0abc0e5881246f1a5ba68ed9d78a27e02878994325392e158b351d835101ec4026301848c5d8fa6dba755cc69a251f71cd08798bf1bf95b5ce587edf5dbbfa37ef13a4841042082172c8988e2ab0e9eb0fb9acc74a88a8033c8167372703b60b5336b67407163f239e8023efa49076261d5bfa1902c26d79f26402e78061c03d840f04df43533871ecd8c56e9e104208218410e5224147254b4d4e26fcc4542c572ac0682002380f64e1091c32d15c99b86c0a66df828fc05570d95da4259ea64ef34c50b2bd793cf933f0041ed781a92bdd6e8b63d3a2e917ad6d4208218410425484041d956cc78a8f69d6f73828970197e2b9a52a3bdf94959289c16441518d789ec8af7a26dd40e2c19304849f413564a26b1985f27a028f6ce03f989afbd0d8f80907f6edbbf80d154208218410a28c24e8a8446eb71bdfb84f515b2b406f726f8bca1b34649175ce816f4030de60031530e0bf5f9f17000020004944415476b97164649075ce4ac23e2ba777f99072ba60d0910da40075808eb4e99bcece9fbebcc82d154208218410a2ec24e8a844c70ffe4dfdbadbc1100d7a3dd05241cb022dd333e99968ae0cec1946ac61a178c6f15b001360c060b210dba523912dba12d5a21b0a6168b6742033b70c2df3429959a0b7c3da52c1757c15d9d9d9d5da762184104208218a234147258afbfb0fc21b3a815870732140b0e54eba0d477a26ce2c7f9c36157b861b479613cd059ec0c384a29a3198ac38b2ec3833fe22b4a10d5cb6fce568d9a0a58356077c7ca8e3b79f8484846a6dbb104208218410c59147e656a2f4c4a3989a01ee70d01c786eafca4307b30f5803f67376cf215413a4c53b086bd29f88966d0127a0a0b921ee8f2d44344e028c855fe30180028a0a6a38a1a1719c8d8ba351a34655dcc27fb7f1e3c757771584104208216aac79f3e65538af041d9528c6b60797098c8e743c4f9b725030625051886ae379d3384e278ef43a04d56f89e74a87e776ab849d6b319bb71210630687b398ad993cdb303ab006ba3979fa047065d535eeff812fbf94b1314208218410c5494a4a2a3d513124e8a844c6cc04cfc3a8b2d683aa83e9323cefde70e74fe8064c3a2736d9f109eb86d91a8c273851493f7d82acb8e5c476cd42cbf24135180abc3b50014ca09f07c70af03983aa822d33f3a2b4f1dfec9ffc47124208218410c593a0a312d94d812876c0e506d75a30c583a9332821800bef550f03649fb661cfec444ccfce17722b0038d21331589a9278c88afddc511a748cc3e867045d01c500ba06eebfc1b109b4143080e604c522c373841042082144cd244147258a3737e3d22c3cf1850b70fe0dea49303603536350834051d0dd0ece1d0ea27eafbb3098f2be205027ace56584b5bc8cccc473249e791145b5835bf78c1171c78173bfe75fcfcbcbc106d9a9e0db34b83a9a2c841042082144a924e8a84486b0e6d812c1a70e9e31e10064817d27a87bc1180da618745710b6f3119cdbb10ad5ac10d9f16a0c162b39f751d9535338fdcb1b34e874180376c83c03ae53e03e977f830ae08684042b613da22f5e438510420821842807093a2a5164a3b69cdb05316df15ce9c8cbed04e771c83e8e6af021a6e91eb2ce7d43e2ee68c2daf4c360819c5bac4efcf016c1019fe363c9829424cf2d55455101279c4ea943d3a8a8aa6b98104208218410ff800c04a8440d5bb6e1647cace7c1556e726fb32a38d96df85a4f1012760493d91fa335c05b46c2866518cfbf4464d363909e084eadf87214b01d8764cb25d4ad5bf76236550821841042883293a0a31285848410e73708fdd48505c5050b2ec00d49bbc11cda03d5e0b9c29179fa28e95bee27f67237d84bc97f61daff1b847718808f8fcfc56ba8104208218410e5204147256b76d55decdfe2e319d3e1c2f36fc1c905d820ed380436ef0180dbee2471f978eab58d4735e079c54751797326403b0d1b0eb6e6cafe575fc4160a2184104208513e127454b24b2eedc44ee50e5c47f00cd1c81b68e499dc2960f06b4760f3cb00485af50ac17eabf08d00b20ba7cf7d2216de5bb7fe5809e6ce77d1b871e38bdb48218410420821ca41828e2ad0ed8e6759bda13124e3792055c12b1e6eb09d81a04b47a15a7cc9d8fd33eab19708698a673c48715748728217e0dc1ff063c2d55c7fcbed17b975420821841042948f041d55a0416c2cf47e8dfd3f93fb4ec0028183235dc5b7711f348783f45fee23ac89a3e4dba9722603b84ec2a72ba2b972d44419402e84104208216a3c093aaa48bf4137b035e061e2b7e07dd214ee0b930ddc7a34967aed49fef91502fc0fa25ac8bd75aaa849030ce03c09df2cf3c5d0e361ba77ef5e1d4d134208218410a25c24e8a8220683819b1f7f9595eec7d9b2dc07ed2c9ec04303772a28e15791bcf15dd8ff22fe31789e5655c2ed546890f007ccf9bc3ef19da630f29e7bb1582cd5d134218410420821ca455e0e58852c160b239f9ace2f3ff6e4e3e5d3b8baf1efd46d09aa06f684bfb19cfa8ab0862ecf93aaf43c19950b93c1b3dc11079b36a9acb50fa0fb038fd2a3470f0938841042082144ad21414715535595ab060e26eed24efcb0683ed6ef167159d41122833711d8e0422237392f23f7dc46a50176389f08bbf61bd992dc8e80aeb73066f8add4ab57af5ada218410420821444549d07191444747337ae254fefefb367e5dbd82e4ddbf60fdeb6fa24c6709b3a46136b9d134c8b09b399d194c92164556504ba23bf665689fbe346bd60c45514adf90104208218410358c041d17598b162d68d1a205595963397dfa340909099c3d7b16bbdd0e80d962a151440457d4a943ddba75f1f7f7afe61a0b2184104208f1cf48d0514dfcfcfc68d6ac19cd9a35abeeaa880adab2650b3b77eeacee6a881aa67dfbf674eddab5baab21841042d42812740851013901c7a38f3e5add551135cc8c19330024f010420821f290a043880ac80938323333abbb2aa286e9d2a50b5bb76e95a043082184c843820e2184a8029f7ffe79755741d4322d5bb664fffefdd55d0d510ae9a79aa765cb9674e8d0a1baab214a21418710425481b163c7567715442db360c102396e6a01e9a79a67c18205001278d470b53ee838bc622e0f4d9bc3faed07c8c6876697f6e4be4933796060d90768df72cb2d40d97e99cc796cadaeeba5a4f438bf6b394f3dff16dfafff8333293602a362b9bcd7b5fcf8d9ec32d7af345f3d3c90b1efaea2f5801b98f1d1a774093095ab4d4288ca93f319e17038aab926a23692e3a676907eaa596ebae926962c592241470d57ab838e339ba6d2eabaa92801ed98f4c63c629478fefbf40b3c38b83567d79f646af73a652aa7aa4ecccfef9e43934e0f92863f231e7d967eed62483bf537df7cfa2e507941c7a8b75790e1d658bb7409c60baff2a8d26043778152ab0f1d21aa5c597f9810222f396e6a07e9a79a45faa37650abbb02ffc48cdbdfc2a9eb4cf8e5279e7b603477df3f899f7e79005d773173c45bde748aa2e47bb15e69f39a239e97ee194c83b0008c663f9ab4ef59e4f60f7ef50cbe069588cb4673ccee2eb47ee68d934871690cfff44f164e7f8a91b7dfc1034fbec8aa1d71de342edb211ebfb91711013ef80444d0ebe6c739647315aadbe7936fa75eb02fd6f0264c5a763cdffa0cb70680492dbe4dd9893f73cd25d158ace10c9fb4acdcfb2467fedd71fdf0375bf2ecab045e1a3784d888008c461f1ab4be92173e93c7c80aa1ebba4c32956b92e3a6764cd24f357312355fad0e3ade3d950ec0531dc2bccbc23b3c0d40c6e905152ef7f39bba3169c17728978fe2bdf7e77357dfba85d21c59fe1ced6f7e95e06ef7f3d7a60534b4180aa599733c0d80993734ccbf22cf55828583fbf0e6e2f5b418fb0aafded382f58bdfa4cfe08585ca7ae9440b263ff31fb2ce1de1cdbb477b977ff6d96745fe5dd0dc6b6e63e5ee783a8f7b96ae19af159bae343332ba33f79de9def9cf875fc1a477bfa1df1b3f929c7a8639b73a79fef64ecc3a9656e16dfc5b444444d0bb776fef74f5c00965ca53d4df059dfded03065dd9859ebd7bd3b35b7726bc53730735ce1b7e9d771fe4dd27d70d9f57eeb21ce95b888e8ce4daf9ffbcbd25eddf92d695262758d734addabf8465aa5d13c8c96c6d98a49f6ae6246abe5a7d8f4cce21a692fb8bbcf7cf3cbfd297d7632b4e02b0f2abb768e96b841177144ad36ed8cbf8b6b89f3d6b66116a2c7a5b39ff074aaac933ebe301f8f2d58788546ee5911975895fff2c303a5fbaafe73d4b63b383714f2ec29ebad6bbfc965b6ee1d65b6ff5fe5d9cd7f69ccfdd0e37f3d87f634aa855f1962d788e567eb987cd633f7af6d547a37bf3d16800cf89d6a225c779f0894b2ab48d7f93b56bd7962bfd9a356bca946edcedcf71c78a3ddcdc3408341b7bf7d9ca5d37974bc758ccb15b99658c5ffc03e32ffc1d111151ee7d92d7a1f72753ffb6f1ec79eb3518f77e85cb81b2efeb8a2acb17615858186ddbb6053432dd21dc3fe37deeea125eee6d7df3cc2d4c591b4758d815fcf4edf4d2335492b0b030ce9d3b57e4724fbb3c4cd6b6fcfcc39c3297555cb90067b7bccfa847e69266b6a2db9db41ff93e73ee6bf90f5a51b3689a56e2fa8bd9fe92faa12ce90a1e07973cfd096f5f53afc2db298faa2833af9ad44f95a1a4fa96675f56f57e2f8e041db543ad0e3a4647fb33e3441a6fec3dcfcbed3c573bceedf27ce106c4e43e59c2a028b8759d6c0dccce9395b2ed764166b61e5acce23f2733be73d1bf8adedf3090170fa5f0c8b7c7f96468a33c6bdc80e7ca88f7fa88426e1455c405a8263e06c017005d2f7c2b575929f9b693abacfb286fc001b901d5f435bf312024f7b62b53602344d132e3bee5f29e33f97cd70adafa9958f6d095cc0d7e819fa6f6a54f9f3e9c3d7b961fefb81e80debd7b038583973d592e9a447a8e07541f5ab7f1f1ae7364fcc5e3773dceee730e6c0e7f1e9cff11b7b409013c27fdef4eb89e791b8e9278f6300143be66fdd44b01b09fff9ea65d3fe1c4814f7196b18c88dbe7734fd21b3cfcd95f040518b0b67891efe6f72ad7feb09ffb9571b73dcee16c232edf26bcf9d97cba855a8a48a9f3f2dc7d3cb7f91bd6fcdc9279a732185fcf9f3d33fb736ff2eb45b6c35142d939fb1ac076762d23873d42bc3192e6fd4abf22551665fd12cce9db335b5ea3d36d0f30ea60e12b96a505770ffcef17fe8a3b43a04129d7976fc1722b128816b7bd82c76c69f55abb766dbe34c5a51f7bdb24ee58b9d71b70efd9672bf709c7c50ab82ba2b4b65446fbcbaa609f94a4a2c781cba5976b3be5519527a217a39f2ee6715a5a7dcb53f7ea080024e8a81d6af5ed558f2f7c00a3a2f056ef6b79e59d0ff960eecb0ce83b1b453132e1e387bde97a05794e329ef86029f39efa4fa9e5be794d7d00ae19f6280b3f59c42b8fdd5c28cdaa1d4b686e4c6642cfcbf8784f7291e53cfce514028d2a9fdfdc91bb9f7e8d459f7ec23b6f4ee1da8eb95719debcceb3ad9b9e9ecdaca73d75ab7fdd9b65dc0365f764db50cf769e9ac98c2786165a5fde7d9463e6f5b1004c7ffcbf6cdabe936dbffec4db531f60d487072ba1d6b55fdedbab06ddb618006bf460964e6bc2cdff799d13ab26f1c4d6ce2c7fbe4fbe7cd77efc0de0f9c22eeacac0db77776348fbaedc32e661e67eba922c2df70377d1f05b6837f93356af5ec3aa4fefe2c99b9ecd9777d5254fb2f2a7d5fcb6ee638e7df23c3921ecbe39afd3fc9e6750ca51c6a251cd1833e36bbefc753d6bd66e60f10b5dcabd8fdebb6934e6f11fb361fd063e1e6fe2aea1ef16992efdc42c7eb58c6050a80ff73ed98ef7a66e03a0d95d938b6d4759cb7effe6f1844f5cca86d52b79b6edb7e56e435ee5b9bd0a72af884474be1f7bea3aef7c7878384ba7decdd5fdfb70e7c707b1a7ef62c27faea64f9fde5c71e5203edb7d1e5dd7b9f39a7e64ba3506f7edcd2d93b6a3eb7ab1698b2ab7acdbd1759decc435dcd4a303ddfb5ccddd2f7e9baffec5b52bef9471fa1bda34e9cb5f990e745d67e983dde83ff917745da777efdee8bace0f230603d0ab572f7af5ea55a88c3d592e1a47f878e6150bad5b0779d795b5dd97758aa5c7e4edde75b673df51afd9ad68e5dc77eb5ebf874b3b5e41ef5edd1978cfda4ab93da4b43425b53f3c3c9c6fa78d6640ffee74e871136b12b3cbb46f9c597ff3f4a8ebe87c650f7af5ecc12dcf6ecfd727baae7378d1e35c7df555f4eed983cb7b0ce1b33de74bad7771cb0beec7bcdb296dffff32e301ae1bd08f4bdb74e1a5ef4f94e9d8ac69fd54138fd3e2ea5bd4ffc7e28e85a2d286878717eafbaaec1751b329f5bb4ed4b77ffb448532cf9f3f9f2e5dba70d555575572b5caeec077b379e4e5796cd87e8074bb0b4531f1dc921d4c1dd6da9be6d857cfd26fdc4c4ed9031874cf0b2c9d710f901b19177c0caee688e7e507ee61fe576b884b7551bf55678efdb5a150dae4dd1fd2a6d318928c4df962f7366e6c1450a87e49db97f2e4d499fcb8613b09293602c2eb71799f81acfac273ab81e64ce0a5f177f1f6e235a412449fe10ff0c1bc67a963528bac5b518fec2dcbb2ecc49f18d277246b0fdb19f4d01c964dbf0dd51888db995aa17d9443739de3bf132730ef8b151c8e4fc11c1841abf65d1831f55d1ee95d782cccc5929d9dcd8c193318376e5c95943f7ffefc52df481e1111e1fd25bd28efdcd49e57376b7cb8731b7dc27c0ae5292dfff943dbf965e3267efc7c2e3bc29e64fb277702d02aa60e51cd722fe39f4d4a61cfee1dde320fc49f21c4e839bea677698af6e9ef3cdd34901b9b36e4c1df0fd127d85cae325ebcae2dbf445ec35d370e62e8a05ef81b8aff55ada836b58caec3c6e371849b5434e759eac65ec999b80385f2ae1ad58939572f66f96d4d7066fe45d35677b3ebc856828c4ab1ed28a9ecbc75c99f2e89a8e85625eefb92ecdab58bcd9b373376ecd87c0f63284a646424898989001c5cf134573d9accb1bdf3bcebfe337f23736f6c0ec00703dba2bdba81d19784907162296daffd99637be6162aa72c69f3965b9eedccedd78add8ffcc0dc418d38b27c3c5dc72ecdb7ddbced6ad3a68d77de3ffa3ebefde426000e7c3a8ea19f34e48787b2e83725839d1b67e0a72af9da50b03d79fdf4dc30eefae4283dfaf5a2479f6b1875cbd5f85d78884659dbed48dd40b3cbdee0c8c1e518801d2ff4e171dfd9fcfc78db72edbb163175f8f1f0291afb18c94accc62fe7ea63057df1c517dc7c73e11fb9cadafec8c84886fd6f0bef5cdf9823dfdec7c0996dd9f7cb7da5ee9b8543daf14dff397c35a10700a9a7b3098af1cdd70ff6c47358223d7714a41d5e4abb21eb39b67ba677bb65390edefe7e156dfc4c451e8339f94bdbff233fd8c21b031b937674216d067ccbc9035f02251f9b35ad9f6ae2715ada7195b77fcb732c94345f99fd929d9dcd37df7c53e26de6a27a751cfc7aed0f3af23ab3f943060ebe97d32dee60dd4f7369ee57abef1eab548ef4cdec4d6b4787182b87573c41d36bdf20f2b2d738b3ad627d5fd3d5f4a043739d67f4659d399ca130e687df19d93cb8509ed2828e1c6efb09a21bf6e64cfc11009a4747f1cbb138ea9b0b3fdca06099277f1cc1f51fddcada97f6d0e9661787b63d53ee32d09dfcb5e9677e58f63f3ef8b335fb7f79a1d8ba16d5a6e6d1516c3a1eef3de18f8ebd9284b8bff3a5d19ce7e9d4e8121c1151582e9cc7a725c671f5e21dcced56a7c47614577655071d63c68c2935e8888a8aba7052a6610a69c603afbcc1e0e641de757f9f8e27f84270d7a65e3451cdf30682c9fcb5eb4f6fda3367ce78d79596366fb9e5d94eeb7ad1ac3f7acabb9fead66b936fbb79db55d4f21cf3865fcaf42d1a1ffcf91bbd2f04dc79f39496fffca13f59fdeb26567cfe0e3bc226f2fba291e56ef76b5d9ba32ddaca534d0319dabc310f6e3d40ef6073b9ca7869503b56470c60d40d83b87150cf1203eeb258bc7831c3870f2f355d71ed8f8a8a62cfa9dce3bd5ea35ec49dda53eabe695d2f9a9f8f9c24bac0fff7bcfd90b4f5531e79e9038ea7b8301a14f6ee3b4842fcc942e98acb5f7079c16330275d69fbff587c02beaa02b8a953a7010909a7bd6d28eed8ac69fd54538fd3928eabbcfd589e63a1a4f9caec97ecec6cbefdf65b093a6ab08e835fafdd633a0a8aba6214bf278daaee6ad4488ef46d0ceb3c9854bb930ca7859ec326f0dff71faaee6afdbfb5fcb1c19cbafe5dbeb9ed049d878ca1efce2fa857e00b3fd464e08c4323ca5cf82ec8afd6ee6368ef562840eaa15f30f977f4ae7ba27d388f2ddccee2b19d0138bafd008d3a362fb21ed1fda6631f3f906f9f862e53be2d7f19ba837d491a975c792dad3a36e1ada63700c5071d4579a86508937e3cc6bceb1b73ec874904b77cb0509a844d13c96af80c7f6fbcdfbb2c7ee3587a3fb50cd6df5b6c3bca5236c003cd83787ee509e60c6ac8f195cf95abfe05e5bd2a58964bfe3ffffc73bef9bc035403d5dc79173a1ffeb032df7192376ddebf4b4b9bb7dc8a6c47d372971537a0b6d8e5aef36c3d9841ac054e2465a385984b6d4f41c18ddb33b4717b860c1f4883a6fdd1b411e56ef72d932fe786c9bf327eda1efe0ab9879e8146344d2b57194f2fdfc6e0cdbff0e3d7b3e932fb6776af9a5a6c9dcbaab401ca507cfb73f2e7f68f5ea67e55bcf90a9ff4e5a41975db93dcbeec776e6e1381e64c22a6c12565eaafe296173c06cb7afc59d0d1341d50d07557998ecd9ad64f35f5382dedb8ca519e63c1a028b8340d15d0b5ec7ceb2bb35fcad21fa2fad5ea311da2ecfca31fe4705c1249e752b1a525b2eecb59740834979e51fc2379c774f4e93b0080d33f4fe689ad97b17c4a5f825bdec5a7635d0c19f771a1bc6fded183ab7bf4f20e26cf6beb874fd3b55b0f7af7eec975f77dc3cb9fe43e7e76d4922f88fee929baf4e845cf1e57f2eca23dc5d6cf608ee1858e1a8f6dc862fa55d1e52e43d76c4c1e710dbdfbf4a157af3bb973daa765dd355e63befc00fb3b23e8d9ab2723e6d9f9e0cb3185d22c79663d974f19926f59d4e52f6338fc12bf67388a6d4759ca0618fdc53b24bc3a841e7d07306dfbc072b7a128e51dd351dabac7da85f3c447b9f7771fdd7ea052d29627efbdcd8298baea38baae737ce5f3c5d6bfa4767df3c40d9c1a3c97a5cb9fe6c5a16339657715ca136a3290e07017997fe9babd6817fe4e3db41a93b54385da5da7cfcb38364fe2db499fd1e5b9dbca5f866667ef59176dae18c0c3535e2465ffb24ab927bdb43425b51fc8d33f53086a766f99daf56497081e5ab0c93b9f7a3aab507de2ec1af5eb06a0eb3abb3e7d3cdfbaf21e07251d83153d768b3d366b603fd5c4e3b4a4fa16fcff58d2b15030ed9581663e399a8aaeeb1cfb694a95f78ba8d9fe55573a84a8498abb3d27a6ff340ef5cf9deffce8d7fc51449e41d39730a898b2a77ff875b1db35f9b765e6e25fca5ca761cb7631ac826528864096ac5c5b6c5dcab27d4be8157cf0e3a612f33df46be1311eaa2982bda74f79e78b6a474965e7ad8b6f545fbeda98e7a596932b766b555e65fd122c295dde75233f5dc4de718fd16d910b1f5cc45cf6081f7568fa8fd39627efa84f6631eae661f4991945d39ef7034b8bad7ffffeb907b9a29a59b5f27be2564fe5c96d9df8636d6ffc54858feefe8661f77dc2e60577e4abc7abb75dc975bdfb11e26be0a79f7eca57eed685937863d2797ccd0a363d94690bdff1e62b4fbb55535d9eefa0f1e0061b9bdfaf5bee3274b78da9770e25c9a9e0ccb43162cac24a39f129ad8c92da0f70f51f2f3170d621126c11ccfa627a99da357ce117ecbdff51aee835197f13d4bdf24d164ee990af3e1f4cbd8dd17d7a115c378426fd1e0156e6db6e71f52eebf28af461def9e28ecd9ad84f35f1382da9be05ff3f96742c144cfbfa5bf772eb8dfdf938ba2e2dfa4d003eaa927e91a0a376f8578de9102247758fe928f1c57e151c2b206a87ddbb77f3ebafbf72e79d77963aa64388bc962d5bc68d37de58e1fcf5ead5e3d4a953a52714ffc83fed2751f9b2b3b359b162858ce9a8c1fe75633a84a82924b0109aa65538e868d0a041bef913274e544695442d50d17bd3738e997af50abf7c4f8e9fca57523f15fcff9b97f445d5902b1db583041d42085105fec997e0f1e3c72bad2c51bb54b4af0b1e339551a6285e49fb54fae2e293fd5a3b48d021841095a8b877da08511672dcd40ed24f358bf447ed20418710425401f912141521c74ded20fd54b3487fd40e127408214415c8cecec6d7f79fbdf958fcff23274fb583f453cd22fd513b48d021841095a84d9b36646565c9136e44856467675777154419483f09517e127454014dd3387bf62c8aa2101e1e0e80aaca7b1885f8ffa27367cf9bdc972d5b56cd3511b58d1c33b583f453cd347ffefceaae42add2be7d7bba76ed7ad1b627414715b0dbed9c3973c6fb483d93c984bfbf3f2693a99a6b2684b85872de442f841042d4443366cc00b8688187041d55c0d7d797d8d858fefcf34f929393e9d9b3270683014dd3d0751d83c150dd55144254b1e25e1c29841042d4045dba7461ebd6ad1274d4767e7e7eac59b3064dd368d0a0010d1b364455556c361b76bb1d8bc5c2912347888d8d252020a0baab2b8410420821449591a0a38a984c26dab469c3cf3fffcca2458bb8fefaeb69d3a60da9a9a9ecd8b183b367cf12131303405c5c1c7ffdf51799999998cd66626262505595366ddad0a85123828282aab935420821841042549c041d55a87bf7ee646464b061c30676ecd841606020dbb66d63dbb66d444747d3a04103f6ecd943424202e1e1e1346bd60c0083c180dd6ee7934f3e415555eebbef3e1a3468e07de998104208218410b589041d55a86eddba74eedc99d4d454424343f9e1871f58be7c3983060da2499326fcfec71fd46dd682902bfa70d2e6cf3e82d05108f4b3503fd0c1c0f697e14e38c5be7dfbbcb769c97810218410420851db48d051851445a171e3c6d4ab570fabd5caa5975ecaba75eb484a4a2239391963cb76fc660c463fd99006fe061aa95654c0e5d0894b72f39bdd4cb3a6310c6bd30e3ded3c494949444444c8e377851042082144ad22414715b35aad5c72c925002c59b284e4e46476eedd47ccd583b09bbbd24ea94b8b260583080508a4b933903ff7bb7933f128431bf9523f2b8be4e464c2c2c22e7a3b841042082184a828f9c9fc22080c0c64c78e1da4a4a4e0e7e787b5e525a40474a373700c0d2355340b1882c1140ee6483086811a08461f681f6bc074be1e4b0f6591e186f4f4749c4e677537490821841042883293a0a30ab9dd6e0e1d3a84a228a4a6a672f2e449ce67daa0ddd5b40989a64e34f8c48023dc1364b8fd003f5003c0180abef5c0af2eb46fe883e39c8955499964da1ca4a5a5a1eb7a75374f0821841042883291dbab2a91aeeba4a7a773fefc79dc6e37068381cccc4cfcfcfcd8b3670f7ffffd3751ddfbe26f8c25b67e00be91a01a20d00d9706c0de0c48768125a757143058213806da381bb2f3cc5eda5b6c046567e372b9e40de74208218410a256902b1d95e8f0e1c3984c261a366c4893264d080e0e262a2a8af3e7cf73ecd8310c165fcc0d1bd2243a86d0ba80013440d320d808dd83a1931f684eb0bbc08d67527da07e6330194339969e85cd66c3e572556f638510420821842823b9d25189424242301a8dde8040d7758c462369696964666662f20fc0e0d388d868508d90738394ae79fe551488f18300131cce8083d960f5f12c379aa15e9499a4f39ef2dd6e77f53452082184f897dbb2650b3b77eeacee6a085166eddbb7a76bd7aed55d8d1249d05189bef9e61b323232505515abd54a6c6c2cad5ab5f2be65fcd09973ffc7de7dc7455dff011c7f7def38960c410f15dc121d89693b0000200049444154e1ca95e402d124478ecc859969a269ce5c0d736b65a994a341e5ca95e5caad3970d42fc91cb9470a2a2e40866ceeeefbfb03398e71c71d82a07e9e8f870ffd7ebf9ff1fe7cbe9f3bbf9ffb2eacadabe0e44ce603aac89c78c8ba87ff78b8ce49058d5ca04a0afc2f166e036a7b70712ecbc9530924ba425c5c1c0e0e0e25d24e41100441785a654d387c7c7c4a3a1441305b58581840a99e7888494711ba71e30677eedc213d3d1d001b1b1b9a366d8a52a9c4c6c6066d5a2ae96937d1498d503c9c604880b17bc2cb5841191d681490248356d2117d2b820b362aecececa85cb9f2e36998200882203c23b2261c172f5e2ce95004c12cdedede8c1b378ee0e06031e97856f4eedd9b1b376ea0d168d0683428140a62636371757565e4c8912c58f435f7624f7337a50b6e0ea094c83cc3a1cb594e9a066e3c80bf120007707db897eec5dde641c43f2494ab839393d3636e9d200882203c3b860c1952d2210882597ef8e1075ab66c59d26114484c3a8a90b7b737dedede242626929090405c5c1c616161d8d8d850b76e5d06f4efc7c6b0935cbf958aab976de63d1d12280cce7424a7c3913b10670df6ae99f77300e86488b8188d331a9c9c9c7074742c89260a822008c23341a7d38987b608a55e5252524987603631e928060e0e0e383838e0eeee4e4a4a0a8b172fc6d5d5954a952ad1b991965f2fede3864b1bbcdded91008d0ca91970390e2ea78253057036282f4d0ba7af461377621dd5cad8e2e4e4c4b163c768d5aa15b6b6b625d54c41100441786ac9b22cde8925947a4fd21815938e6256bb766d3c3c3c387ffe3cad5ab5a2825b79dc2efc8fa37f1dc4a16d076ab848c424c29f5ad0ba80da25fbec0640ba164e45c471e68f5dbca82e8faba33d75ead4e1d2a54be23d1d4f98ef7a77e2e77bc9009c3d7b96ba75eb0260ef16c88e5f86a156ab898a8a2ac9104b9461fb9ff5be304769eba3d2160f949e984cc5614e8c6ab55aff7d01605da63e7bb62f32bbced2d20f4fa227e9804e78363d4963544c3a8a99adad2d75ebd625363696b367cf52bf7e7db491e1a4fd7b9cdd1a0d95eb37a16e251792ec6db1534964e840a38354ad8e9b09499c8db847caa92334d63ca05e5d6faa54a9424c4c0cb22ca3542a4bba79820586fdb283610fffad56ab090d0d2dc9702ca6d1c858594905272ca403070e145bd9868aa21dc5dd17c2d3a528c6b6a5df17cff2e7a9a8ca9365199d4e5770424128414fd2a443bc1cb098858787d3ac5933ececec387ffe3cc78f1fc7c1c181cab636389df99b9b7b37b3f7f83fec8b8824f47694fecfee4b111c38b0978ca3fbf073b4c6b352451c1d1d2957ae1cf1f1f1242727131d1d5dd2cd138ad8fe2f47f16a877634aef7129feeb8a15f9f9e789ad1bddad3b66d1b5ab4eac2cf6763f5db0ecd1b4ae3262d68e3ef4be7a107cdca63e8eaea89b46fff0a6d5afbd1ccef357e3e979d4ead56b3696610ed03da3270d515b3cb34962ee9d656ea79becc99e40c00368d6949c0b4fd00b469d306809dfdbb02e0efef8fbfbf7f9eb20bd35ec376347db13a7ed34ee8b7a5dddf4e15af37902d2863e0aa2b46e3c87221a413ad3e0cd32fa7446fa0aaf72064202de60f06b66f8eaf9f2fcddb0fe4cffb6939ea31947bd990b1f1626c9f9efdaa5da1da6e48937289496fbf8a4f2b3ffc5bfbd177727679c6e231d5dec2ee4f637565c96f1c998ac35061facf54d959631b20352a94de7e8df06ddb9ea04fb6e55bbfb99ea5cf1314cf77952959975719fe717575c5cfcf4fffe7e58ec3f34d57927feefd6f099d9a35a1959f1f2d5f6acef0afcf97784ce24ff1fe795248559abd2f1fdf3ab15099434242f0f1f1212020a088c37a3ac4c5c5a1d16870767626212181458b1673ef5e345e5ede585bdb92989884562b93202b89d1a5935ac6091436586524e2a0d1e02659e1e1e682bdbd2d56560a2a55aac4fdfb315cbd7a85f8f8589a376f4ecb962db1b3b32be9a6963a2929290407073374e8d062293f24248471e3c615fa06aefc2e7750abd5bcb5ec28f33bd724e1da72eabcb28d9b97d703b0b4535d749f1f66707d5712af6fa46e87bd449cfb06002ff70aecba1a494d5b2b92efa560ef6657601e4369f762b0712b0740c27f1ba9dff520116717e863eaf9fd1f7cdbddcba2324da5bbb4e61dbaafaacecef792693b2d917ffff8127b8564f6e5208569af613bd2e30fe1d9641ed7ae6c41099c9ce5cf78bbc5ec9b50cfec324cc59145937289fa7507f1d7a5c3385b49848e7889852dd7b0f18d5a7cd3d69b93a3b6f17d774fae6c1ac2ab0b5ee062e8a87cdb6eac2f4c8d1763fbb4b06d37b4bc6b7db6b4fb9a8da3fd00888f4cc1d9c3ce643ca6da5bd8fd69acaedc7d64d877a6e2305498fe33779f7ed3d69b33e376f24de71a5cfd6d282f0dde68f1e5550eeec3d9b6a637f0ec7c9e4ced97fcca33773ce727ebd8a659b366fa47e067295fbe7ca9ffc1af7b2d0f02779fa38fa733e852397b3e95ba75cb5a5446693c8325e42f393999df7efb8da0a0208b8f7b4e9c3841585858b11d2b196adc65aeb8bcaa3845474753b56a55140a052929a9bcf4922f2a5519ae5d8b202222025757571c1d6d298b4c4d2b15d636d668b46928a8802ceb484a4ae2d6ad28d4ea0a942be74a545412952bd7e4debd288e1fff07b55a8d878707b56bd72ee9a60a456476a71a0038d5e84f7afc47faf5734fc55061d4ebac7ab8eca088d36f7baba19aa0611ff276f7cebcdeb9b559790c3d08df4550d05222e23528151229d1978105faed9f76f1b4b84c53e9bcdef89e919b1ae03b48c7f2537f63afb0ec3fa5c2b637ab1dd6ce7e8c701dc41757e2f8c8d389192bae32f998974565988a238b959d17739b2733e1f02d425aa918b73d91cdc1d5015878218e239d6b0250b3f3a7c48d6809e43df82d88b1f1626c9f3e4adbb3cc3916c5bef5d98f6674f6c83e3834168fa9f616767f1aabcb1473fbbd30fd676ed90b2fc471a47d3500aa77fa04d86856ecc62eaf7a563e4f503cdf5505c9eff22a63975cb9b9b9f1f3478104ef3ecfadc807f4fa623d1f75cc7c9f567ae26926be3d9133f7d3494d7760d4772b08aceba2cfb7e6835eccdb7d89987b29f4f9621df54e7fc6d7fb2e11792381c0791b78bfbd0717435e65f0b5691c9e93f9d2c294e80d78fbee20fcfc120cf7fad9640d35cbdb3c8cd39adab5adf531171447c8c8ae841cb9c6bda8ff70ecb68983d31b019016bb83e79aad26e2e26a32cc2c43ddef3bde899acf989f4f53d6514199e73f61eb777e85da0f82714fd2990e31e9282657af5ec5c3c303a552c9a953a7d8bb772f515151942d5b96060d1a51b56a1322226e10131345b56a35b0b6b6c2cece1e8d464b4c4c0cb76fdfc2ca4a49f5ea1e942b57166b6b152fbc508fb265cbe2eaaa2229298ea3478f121f1f4f8d1a35c453ac9e1276fa030625b29cfda846ad2cb372cf3eaa58e7bd8f67f2f61374fb732f3b362de2c585fbb8b06f5681790c0d087c9ffe5b4e12584f8d2e239a0aee3927b12e56d957619a5ba6a9743acd7dc22e2752cd56e2464c2a94b36cec16b6bd86ed78634633ba4ef983e19f9ce5b4cb30da94b5b6b80c637118f2ff623863bafdc8cd6997c06f1e556d32cbd561f89f84846470c8a0942474645efb2aeb524cf685b1f1626a9f16b6edfa684d1cd31a8bc7547b0bbb3f8dd5658aa9380c15a6ffcc2dbba83d4b9fa7e2f8ae32c5d8a52b8697cb39b8bfcb9655bdf4cbdb9f1bc3d6f76a92706d05f53abcc7871d7e0560559fbed4ffec105fd57721f1fa26ea77fa983e67bed6e7db566b243b777bf3206205cfb70ca0ef775bd832ae160f225650f795b14cbcb88e9afdbf24a6fe20e2661dc2d94ae2e8b4b93499bc0a6439c7e85bf87673ba366c86dfcb7ef8fa77644060807e325a501c7beabfcfce29cf911e7f18afa6d3d14cdb8c1238b7782e5e4316822c9b5d06c0f39537b3f3ca0dfd19ac27e900f949f124f5a9b8a7a398d8d9d9111919497878385bb66ce1cc993354ab568d1a356ae0ee5e91aa552b51a58a1bd5aab91113739dcd9bd7b274e962d6aefd9163c70ea2d12450b366252a5470a656adaab8b9b992901087522951b56a553a75ea44f5ead5b973e70e5aadb6a49b2b14b3890dca337ec571fdf2b5e39732ff21a7733e5a4bfd961d193feb33e22e6c28384f2eb7d2745475cf7cd9e4bfabc7152e0e0bd2fd36be0b37bb7ecf966d1f33abdb606ea6e71dbfae2a2577d3f3f935b108da0be0fef2e7a4fdf9315b3f5a83cff4fe969761220e430e1e83e9a95dced0b1a18cf82cfb17be31de2e4cde190e40f88ec994f51eaddfe6eb6ccdaaf0040022f64c35da06534cedd3476dfb241f374687fca95f8e8f343d310213ed2da2fd694cee7164aadf0d15a6ffcc2d7ba49733d3765f072062f7148bdb94dbb3f4792a8eef2a538c5d3bbf6fdf3efd9fdf56f6ccb16d6687eac8b28c63f57ea4c7ffa9df36ef640cabc7f4a06ddbb6741db80807c59f39f2cdeeec852ccb3854e98b36239a991d6be897d3e38f20cb324a5b4fe6344b66e2a15b68d3ef327e4722c1af57cb1363bb99eb39b5fb07bab7f0e4d8ca71f8bdf593d9717cf26a4d645946e5d48ae1aee7987b250e59d632f3a7ab4c0a7acea2326459a67f433543defd889f7e0b45eb6a53e2f73e3c8d7f9ea4871d88331dc5a452a54a444444b07efd7a6edfbe4dcb962da953a70e8d1a35c2c1c101c87c9ceea953a7b0b2b2a265cb9624252591989808406c6c2c010101942d9b7d1d664c4c0c972f5f46ad5653ad5a359a376f8e4ea7233c3c9ce79e7b0e6b6beb1269ab50fc06feba8eb383c6e0f393065b34546e3a81358dbd9075a94c7db32b51e9121949a90c98b9a6c03cb9ad9cdd9fb77c5be0e2ee8a67c00460a7c571989b2e72ef542686bdc8bf7fb4c55e21b166c86f741bba927f960dcc917f7e7f5f5ef16d8d8b9d32c7652545d15e00a5b507b31aeb187e3895632bdd2d2ec3541cb90d9fd110ff299e047994d1af1bbc7e19c3fabd89df7c2b34f6b558b67eb07e5bf0c291f4eae2cf0a8f4a78b77b0f586eb46c634cedd3476d7bdf351b3837740c2fb6fc184715b8fb2e60f5ac4626e331d6dea2da9fc6e41e47a6fadd5061facfdcb283d67dcb9b3dbae11b5c114fff5140f6bd28fefefe462fa332bc095c52d87060ffee67eef3541cdf55a6183bd361ea97655b296bbb0259d6e8d36a9059be6337950dcebc189663a7cf679567d9b09cd673de65dceb3f7263f265f0fd9c2ad68a7ce371a9d9901e351bf25a9f57a9ead90e59ee6f561cce4a49bf1c38f5255e9bfa07c3669ee5b4cb3bb4765221cbb245654cfaed6fbafe6f1f3b372fe6a545fb38b36786d1be130ac7d4782c6dc48de4c5489665ce9d3bc7c9932769d2a4095e5e5e2814394f2ec5c6c6929c9c4cc58a15b975eb167bf6ece1ead5abd4a953877efdfae52933353595c8c848a2a3a3d1e974d8dbdb93949444ad5ab5a850a1c2e36a5aa957da6f24179e1deb021bb1b3ff1696bf5aa5a4431104c10c59c7364d9b3625393939c7360f0f0f222323f3cd977b9be1f2922e8dd8ffda0fac0e7a1180f09397a9def0b902f3e5b73cc9e7794e3f48a7c7be330c74cffe3123cba6431778cdcf1b09883df7134d7aeee0eab99f2d8e439b7e8b2675bbf1fe4bb0abdf467eea58c5b232e4742e44ebf056dba249b94ccddabdb81e7e32dfbe130a2f2525859d3b778a1bc99f75922451b76edd1c4f1dc9cdc5c5853b77eee0e1e1416a6a2a172f5ea44c993254af5e3ddff4b6b6b6d4aa558b5ab56a919696c6d5ab57b1b3b313130e412865d2e30f11d06502c9ceed38f8f0665241109e1cc6ce7418fed02a29acd9bd6b5b8e3cb9cb00786bcd4ace0f9d40cb5599675e3c5e7c8f150d3c0bcc97dff2d0292ff0ca8c5a0ca8649f6f7c7faf98ccfc2931d8594ba4cae598b9fc9b42c5a15055625a431da30fa7f2e7924a1697216b539931b007d1199967b0de9cb6e289fa55fe49f124f5a99874940292c19d995aad163b3b3b93cfe6cf626363c3f3cf3f9fe7ec89200825cfdad98f8387c20a4e280842a994dfa4e3c68dbcef84c94a73e3c68d1ce90d979565eaf0c5aa1d16e7cb6ff9e8ba085acd9c6ff46073f60fbf188dd1923800baadfb9b6e852d43e1c0eaadbbf34d27149d27a94fc5a4a3142853a60c51515124272723cb329224e1e8e868565e31e11004411084a257da6ed24d4ff883ae3d2791ecdc865ded2a95aad8849223261d8245ca962d4b7474342a958ace9d3be3e2e282abab6b49872508822008cfb4d27440a7726cc1cedda1fae5d2149b50729ea47120261da580a3a3a3fecc469d3a754a381a41100441108cddd32108a5c9933446c5a4431004411004211731e9109e044fd21815930e41788cd46a3551515146979f26a5a16da52186e2f2286ddbfa715fa61fbc4579d716ecdef2599ee5a7b9dfcc51d4ed37a7bcc2d459d8384bf3f750698aa5b4c421084f0b31e91004a154d16864acaca482133e26a5251e4be22828eda825fbf937f20e4e4a29dfe503070e3c7ac0c5a8b4ec93a254dafbdc124fcbfed9bf7f7f4987200866f1f6f62ee910cc22261d82f098ececdf15c87eb370d69b81f77f398af9bbcf73fbe6037a7eb19e499d325fc0949e789a096f4fe04c4c3aa9e90e8c0ef989c0ba2e79cad5a45c62eaf0b1ecbdfc007b2554f25dc0dad98d488bf983a16f4ce0bf142b3476b598bf368416ae3640e6af896b3feccdbc5d1789be9742e0dc5fa877fa3316efbbc8adeb09f499bf910fda7be8d32e1bdd8dc5872e7237ad125f6ef8097fb5ad7e5b7ebf98e6d75653ed51abd57c3faa2bdf1dbe86ba5f08ef44cfe3bdb5a771765452e6f9d96c0b699da3cde19bbbd3eff024fe98df94fbe7c7e3dd7a257bae45d2b08c8a453e9e68379ee4bdca0e85eedfdcf12ced995ae0beb810d289c1d7a673648e0f0029d11b78bed576222e2c25bd807d61ec57e7dc71ac1af89cd1b1943bed4cd5f7bcfbd329d2535349915d79efbb6504d6716160c776246975747db90d957cbfc4e6d8c41ccb6b6735a24d9b36fa188c8d2f4305f5a5b963cd927df27d8708faf79cc03deb0a3cd766145b17bead8fd9543987e60d3539b6b26c9b3538df317f75f5c47cfbd59cbe92b5492c18d681831546b07e76204a83fa0cfb5cad56b36e5260bee3364b7e63c0d467de543e78f4ef214b3e33a6fab0341939726449872008664b494929e9100a24261d0f65bd2b23f3da389965c39b31e8db30dcfdc771faf7b9b85a8947d30a8fa6e3ca2da056ebff93cfb2fdb9b16c1f5b93846bcba9f3ca5826755a0fc0aade81bcf0f96116d67725f1fa46ea76f898c073dfe42977559f1e5c68f73561cbfc00888fccfce259d22b08eb51db38dcdd932b9b86f0eaebdf733174943edfb65a23d9f57b6d1e442ce7b916ed7823641bdbc6d7e241c4726ab71bcb0797b39ff5beadc124764da9c9d5adefd2a9cf522eec1f6e715b0b6acf9efa1fb07baa17005eee9bd97535929ab65624dfcbfb455ad177009193d7c1fca65c09f993177b5661c1a91896be64cfd777ed3961f096dec2f6af613c4b3bd52d705f78bef515317507113ffb30ce561247a77dc18b53d72099b12f4c318cc354ffe64e9b76ef4376f72b0740c27f1ba9df753a816717b07ce75ed439f2e65ecec9d8f8ca91a680be3477ac59b24f16f875a6e287bbd8d0b90657b70e67ab99f10c0e363db6f4311b19f31e01f9f76b417da54dbfcdd43e1d8969fb259b46b5315a6f1663e3364b7e63c09c71565cdf4360fe67c6541f0a82f0f412938e3c64968f68fe644f38640d4885d8b585cd273c92d99d6a00e054a33fe9f11fe9d7cf3d15438551afb3eae1b283222edffc738e45b16f7d4bfdb2b3871d000b2fc471a4734d006a76fe94b8112d81ec03904fbb669e8e75acfa06daf489ccee5453bf6c1807c0ec8ed501a8de611671c37c01d3938efc14d49e4fbb64bfd1f6ad866a82867dc8dbdd3bf37ae7bcbf44db96eb46ada4d15c4d9dc3da7df7f972cb30023f3acb832fc2902b8fc64e917d694761fbd7301e73f685959d17739b2733e1f02d425aa918b73d91cdc1d58182f7852986715892f641f82e8282961211af41a9904889be0c587e60676c7c192ab02fcd1c6b96ec936fafc4f347fb6a0054ef3013f8d5ac720a1a5b598c8d7953fd6aaaaf86bdec87eb884d7c1758cf689d39ea37326e4d799471f6a8df4360fe67a6a8c6e6e3d0b4d14aaa5553d3bc8507651c6d90b5202914c828d0e920032b3a67fc8a06099dac4092326fea952409cd8344a28f1ce6fe7ffff1fa952b25dc12412879e20833979f46b5e4ed6f8ee699706852aff0e1802056ec38ca031c79a9d30096ac9883a76d6617669d29593be50d262cdc48ac953b637fd8cfecee99ff29a6dcdb4bf797dfe2c0d574ba8dfd815f3f791dc87eea40ce332d799775e977f86cd450bedfb89fc8d80cdcbd9a3064ca374ce9db2047fa9077da326e692889195a8be2ce9d4f787cb20f9095c8b246bf5e2bcbacdcb38f2ad6cafc333e2419b9745a87e1132d24247226b4cfaa57b2ceb36c18471e064fca504a123a4001c83ad3a7760b6a8f8bc1e47ef2f61374fb732f3b362de2c585fbb8b06f56aed412efd57162eea9bff95dd997e06ac3509cea4ff8ea186a0d0ec991b2b0fd6b188fb9fbc2ff8be18ce9f62337a75d02bf7954b5c94c6f6a5f14d4872e16fce861987640e0fbf4df7292c07a6a7419d15470af6d7639868c8d2f4305f58fb963cd927d52d8780a1e5bf93018f3a6fad5545f75f0afcd9c9dbb49ee5d37bbfd26181bb7a614f4992f4c7de68e7d30ff33535463f371484c9039fd6f022f35f3a06a157b2445667b244942a79348d348b8b709223d4d67f01421196499a40709a4b76c892a2db5e41a2008a5c813f6137ef11bb0f87fb8d41e9ee70cc78a2e6d98ffcb219e1ff21973de799e43bfcca74d971579f27f72fd79a64eea4972cc55e60f0ad2afffb6e31bec3e739b97864fa645da9716c7f573efe64cfe7e0b2fcfdb496cfc5dbeee9bc1b47e4d58189e90235d70622bbef9f6738be3ce9d4f281eae2a2577d3cd7b8becc406e519bfe2b87ef9daf14bf9a69be4e3c6e8903ff5cb5997748cf17661f2ce7000c2774ca6acf7e842460dd3765f072062f7549cbdb2af73f675b666d5c33118b1676a8e3cb9db6a6e7b90d3391fada57ecb8e8c9ff519711736e49bace1c8daecfb6814eeddba2129ec78d7f53453975ca657a7ca66b5c9ec782c48ebe031989edae50c1d1bca88cffcf4eb4ded0b537d684a4163e9569a8eaaee4e00fcbb7a9cd9e5e6666c7c19b2a42f4db1a49c61b59c99fefb0d00aeef996e5e39668e2d303ee64df5aba9beea316b0b1fd73c826fff2f48d416cd232e738f01733ff3c5f13d6449bea21a9b8f831615696970f4af7b9c3f17cfc5f371fa3f172ec471facc03e2d6ae247ee76ee277ed267ed72ee277ed2276fb76ee2d5c44dc279f92b030ffcbd18a826430d335e7df825092c4998e5c6c141209ff6de297e3d319e6a3d6af9f74e83600ebe78cc14deacbd8e04adc3ef431109423ffe6ef3ea6a6753a433f58455a7ca87efde767ee03f0eba7a351d397b1f32a5a14d7f89d99ffb9fe14e4cf4f410099bfaaacfa3582d113ebebd36dfa610ab5edb377abb971e7ce27148ff9fd7d79c5b7352e764aa3d7d06719f8eb3ace0e1a83cf4f1a6cd150b9e904d634f6ca93aeef9a0d9c1b3a86175b7e8ca30adc7d17b07a562306af5fc6b07e6fe237df0a8d7d2d96ad1f5ce8b83bfc33830e5f5de176aa1bdf6e98af5f1fbc7024bdbaf8b3c2a312deedde03961b6dabb9ed9175a94c7db32b51e9121949a90c98b926df98dc9a0d21f6743fdef831f37212bfc1b59832359af56ef666b5c9dc782c4d3b7c4643fca77812e4917d5f89a97d61aa0f4d29682cad9cdd9fb77c5be0e2ee8a67c00460a759e5e6666c7c19b2a47f4cb1a49c77d62da45fcfaef8ceab402ddf2128945b0a2cc7dcb105c6c7bca97e2da8af5e9bb609ab4f7ae1f7c6a784ae99a47f5a5861e51e03e67ee68be37bc8927c4535361f0785c2061b6b25a74f25121d1d89d24a812c679ea1d4e824eec5593174869af83bc968755993491d3a9d8cae7c15ecfdaaa13573825718274e9cb0687d51795a9e50263c5e529566efcbc7b74e2c54e69090107c7c7c08080828e2b01ebfac5f02ceae7a8f466f2d40abaac437474ef1ce8be50170b7b1e276ba96dbe95adce47b286d2aa1b4ae8426ed568efcc62e8faa6063c5bd5cf90db75b291468659964ad8c75c60dac6cabe6d89e55ffbc43c768ef92fd341295530d9eaf5a264f7d592c8dfb699192924270703043870e2d96f243424218376e1c494949c5527e69529a9e9bff245817d8889dfdb7b0fcd52a0527160a4da7b90f56ae2880c883d3693526956b27e7947458c253c0f0d8c6b3da76d2d255281412b2fcf0ff4c59874221a1d1c19d786bce775d489c4d0db4b20c4880845607b22ca1d12988d768e9facb5c00f6cd7c83a0e527707152e250e72b0eaf69076496bb73f640666f3dcdcdeb09bcf9cdefcc7e2df3f2eccb4bdee5cdefff213d3595645d3926addec080175cf5f90c8f3b72fffbb76ead796dcb211a34c8bc14fbe4c9934892c4fa0f7a3377df596ea77af0e3decd0454c8bcff28fdc10986f518c6c9e87452d21cf960cd660636c8ae6bedfbbdf872ff152a04ad61cbb027e331adcf8ac21cf79c387182b0b0b0623b5632d4b8cb5c71a623b73afdbee4b84e4ba3018b19d1aa11ca3f4f12d4b81cf33b55e18dcde1f4fa68113de4cc1b16ab749a5f4069d93ea8e7caf8e3510ff3afcfb3bdb5b30dfbe35299b86c23b5cfe4bdcce9abaed5e8b3fe2a9f4f5880e388f6a852ee7174ef6f9caaff15ff9bdad068bd8f1ab72008e6498f3f44409709243bb7e36047f32ef1120a2fe5de5a3af6fd15859c46a2c283f9bf2c29e99084a75074bc8a07f1f628b04247e6fd57a040854c060012f6b5bb9396a22243f3f0473c4027cb6875804e8722f581bebcdeb3d7f1577c1acfd95991742739475d9b6a4fe2c8c7cf117fe53b2afa0c66f66bbf0350e5d5991c0dcabcf222fed25a3c5a4f64c06df3c67bb7df0e822471f2e4c91ceb373699cd5f739ee3f2fa3769d9f11bee1d1f0fc08f1d3ad178f11996362ac7836b6ba9d47c0c03efacd4e7dbd66806473f2fbdf7e008a59b9874e4a36eff851cd3ea6832e81b86b56c8cf2af13bcf5cbffb832ec6d16877cc08738d361d04c967dd7c7ec32dfddb99a5d6ddf22f4eb19a8df0b018ee4d8bee4c771bc3cf42b7e786f389ddf990584e5d8de736d18c15546f1ddba6d0c1fb80a6b2735b51bf8f0a65f0593f5f679c4b805419ce5308fb5b31f070f85159c50281265dc4770e8e088920e4378ca8dfbb126f1294e3838daa052aa48d128712a23a1d1429206ecad41137a11a56c49868d1f000020004944415405caac2b07326fa497d121c9320a29fbfed0779a56a077bf91bc1bd883be3ddae5a8ebcbd7329ffee5ec3984b4b8eca78e25fcb785debdbfe16aac062ba544f2bd0bc0a34db2bf7cad1600b5ba0573bf5f7d2073d231e3581495de7e991f1fa67354dccf916f61cfe71fa95ee1d926261d0fe5bebce885818bc918b838c7ba294b7632c5c8e73c77fedccb766e01ec39735bbf2ce5ba0aa07a8f4ff8afc727d92be60fc9b15d61558eb1c16b181b6c5efdfa7caa8a16c52d0882200842a6de5bdea1ac9c82ad12540a196ba5844ce6655456924cba6ccf35a919c8594fe6c9bc0c4ba70349076841979ea12fefb32311f43eb883cd3f7f4eadcf7772ef9fecffd4ed8d3c41ecf54e23187c3082810d2ba0cbb887d2daf48f8d1633380ed0c832bf1dfd876a36f93fadec897b858050aa8849872008822008423e626af7264d296367a5406525a1542a33cf5cc89075ff86233c7c5eb20c929c796995564b8646c64aa32525e9e12373e5344edfd3d1c8bf1bf57dbcf8c4a50d60e497440337d2b4d4a8e20cc0f125ef58dc86f22a25b7d37554b2ce9e304cd87a8d9f5eafc5d52de371a9937d5fefb4266e0c0d39caaed12d00b812761e4f1f7139955034c4a4a38488330c8220088250baa5fcb11b29230d8d52810a054a498924290105b2ac00fdbb5064244947e69325b568652d19e848d3ea48d1cac07bc8ba54c6776dcdbd7489f4c41486066f332b86dfbe1c42f77a7570ad5c8ee75f9d0afc66511bbe1bd2169f7a2f50cede4a7f6f47d7bf3ea0d9a717884ca9c8cabdd9ef367a77cf4efeed15c473df6bb02383aa2da6b24d4c3a842222261d822008822008f9701cfd2e4e0e8ea854d6a8ac6c502aad912425b22c91f755673a2449ce9c7468d3c9d0a49191918e3636f3be0849e9cc9ea327f3d401a62fd16ef8ee375c7b377bdb9ae972bee98cfdbbc7d77be891abbe9e5faca7673e71a81c1bf2e3ae7fcc8a51102c25261d82f00433f538dbe27ed4ed93fa28ddc2c45dd8b6e6ce57dafbacb4c757da14477fcd0b788117d6fdcd2bae360527b650691c8fa5210653ee0e1fceddfbf7917432b22ef3fd580a49422b675e61a59024740f0fc69592842c673edf4a9224644023eb48b2b1c1373abae41a2108a584987408c2134aa311bf3a099633f552af03070e3ce6688a5771bfc0aca8fbebc1f56f59aa9cc0b96298700885d3f5ca95920ea1c88933164249118f211084c7247c73775a8eff1b80fbe7c7e3e6e6c6c9a4cca79a2cf2f1e4ab9b8900a4c5fcc1c0f6cdf1f5f3a579fb81fc793f4d5f865aad66d3cc20da07b465e0aa9cff19a64685d2dbaf11be6ddb13f489f16b85afae9e48fbf6afd0a6b51fcdfc5ee3e773b139cadfffe5285eedd08ec6f55ee2d31d372c2e5f937289496fbf8a4f2b3ffc5bfbd177f209b3da65ac5e53dbd2134f33ba577bdab66d438b565df8f96cacc93876f6ef0a80bfbf3ffefefe001c9a3794c64d5ad0c6df97ce430fe6694f7e794cb5c5543ea0506d31642c5e53f90dc74dd317abe3372dfb6dc569f7b753c5eb0d64a04d9b3626fbcfdc382f8474a2d587d98f0f4e89de4055ef41c805f49d5aadce514eeee52c058d61c3cf88b9fd6aaa6e637d6ed85fa6c669f29dbdf468d510dfb6ed19346b9bd1761d9bfa23cda6b5d72f9b1bbb39e517c77834f73bada0b2b6cd1a4c87005f1af9f526342a35df360a82f0e413673a04e131a9e83b80c8c9eb607e53ae84fcc98b3dabb0e0540c4b5fb2e7ebbbf69c702f03c0925e41588fdac6e1ee9e5cd93484575fff9e8ba1d9cf6cdf53ff03764ff502409dfdd01196f61946f9f777f24be71a5cfd6d285b8cc4e111f021bbfb950320e1bf8dd4ef3a9dc0b30bf4dbb73f3796ed636b92706d39755e19cba44eeb2d2a7f559f1e5c68f73561cbfc00888f4c31ab5dc6ea35b56d55ef405ef8fc300bebbb92787d23753b7c4ce0b96f8cc6e1ecb105d46a424343f5650f0edeccaeab91d4b4b522f95e4a9ef6745c99374f416d3196afb06d31642cde82f2678d9bf4f8437836998676c61694c0f9afe7e2f5ce62729f0f30b61fcd89d3f3adaf88a93b88f8d98771b692383aed0b5e9cba06c9ccbe2b484163d8f033b2b4535db3fad59482c6481663fbf687de23a8f8e12e3674aec1d5adc3d96a24ffb2ffdd63d00217fdb2b963c29cf28b633c9afb9d565059db1a4c62d7949a5cddfa2e9dfa2ce5c2fee146fb5810842797987408c263625bae1bb592467335750e6bf7dde7cb2dc308fce82c0fbe0843ae3c1abb87cf685f78218e239d6b0250b3f3a7c48d6809641f947ddac533dff2175e88e348fb6a0054eff409b031df740fc2771114b49488780d4a85444af46520fb806d76a71a0038d5e84f7afc4716973fe75814fbd6b7d42f3b7bd899d52e63f59ada36f7540c1546bdceaa87cb0e8ab802e3c8edad866a82867dc8dbdd3bf37ae7d6f9a6c9ada0b6985298b698136f41f9b3c68db5b31f235c07f1c595383ef27462c68aab4c3ee695a71e63fd674e9c56765ecc6d9ecc84c3b70869a562dcf644360757071eadefb21434860d3f23e6f6ab29e68e1163fbf6db2bf1fc91f5d9e93013f835dffc87e3d3f9ce516571ece6966f49cce6d46dee775a4165cdee58fd61ecb3881be60b884987203c8dc4a443101e1b89f7ea3831f7d4dffcaeec4b70b561284ef5277c750cb506673fb250879c238f94eb376897477c39d380c0f7e9bfe52481f5d4e832a2a9e09ef3718876465e50652ec9c825f405b5cb54bdc6b6696599957bf651c53aef8bac8cc591dbe4ed27e8f6e75e766c5ac48b0bf77161dfac02f314d416530ad31673e22d28bfe1b879634633ba4ef983e19f9ce5b4cb30da94b5ce93de58ff991ba7ff17c319d3ed476e4ebb047ef3a8faf06563a6fa4e2949e8c8bcee57d6193fa350d018366cabb9f19aaadbdc31f2a89f9ddccc8dfd513cda7834ef3bcda27688fb0d04e1a925eee91084c7a8e1c8daecfb6814eeddba2129ec78d7f53453975ca657a7cafa3463bc5d98bc331c80f01d9329eb3ddaacb2477a39336df7750022764f319aee569a8eaaee4e00fcbb7a9cd9b19b5bfe241f374687fca95fceba2ca7b0ed32656283f28c5f715cbf7cedf8a502e3705529b99b9ef98419e474ce476ba9dfb223e3677d46dc850df9d693238f056dc99dafb06dd13311af59f91f727ff973d2fefc98ad1fadc1677aff7cd318eb3f73eb71f0184c4fed72868e0d65c4677efaf5a6faced7d99a55e1090044ec996a347e4bc6b0b9f11aaddbcc3162cab05ace4cff3df37e89eb7ba61b4de7eb6ccddf0fb2df5e6d6eece6965fe4e311f3bed30a2a2bfb7b652ace5e23cd8a4f1084278f38d321088f915bb321c49eeec71b3f665e5ee237b81653a646b3decd5e9f66f0fa650cebf7267ef3add0d8d762d9fac166951db4ee5bdeecd10ddfe08a78fa8f02d6e79b6ee5ecfebce5db021777573c0326003b8bb4fcbe6b36706ee8185e6cf9318e2a70f75dc0ea598d0add2e5306feba8eb383c6e0f393065b34546e3a81358dbd4cc631bfbf2faff8b6c6c54ec9817d5b98fa6657a2d2253292521930734dbef518e6090d0d35bb2db9f315b62d59645daad178cdc99f4569edc1acc63a861f4ee5d84af77cd318eb3f4bea193ea321fe533c09f228a35f67aaef82178ea457177f567854c2bbdd7bc0f27ccbb5640c9b1bafb1ba4df5b9b9de59b7907e3dbbe23baf02b57c87a050e67f47d4c097d4fc742196d62f552830767f7f7ffd983255be61baa21e8f60de775a416575f867061dbebac2ed5437bedd30df74670a82f0c492aa347b5f3ebe7562c129f3111212828f8f0f010101451c9660944e47dae9d3a4fcf517dabb77d0c5c5a28b8bc5a64143ca8e195bd2d1951a2929290407073374e8d062293f24248471e3c6919494542ce50bc2d3605d602376f6dfc2f257ab947428254aa7b90f56ae2880c883d3693526956b27e7e4499710be98e6c3cb7276c79bc552be601e716c233c890a73dc73e2c409c2c2c28aed58c950e32e73c5998e27859c9a4acca285c47c321b8536033b2f57940e2a148e8e68e313493877464c3a04412815d2e30f11d06502c9ceed38d8b172c1199e7229f7d6d2b1efaf28e43412151eccff6549bee99caa8f64407a037ebfdf8b000bded5616ef982200825494c3a9e00e9376ef09f5f4b6cca5a536e401bcab824a078be0592633974e742493e76999434b7920e53100401c87c42d6c1436105277c4694711fc1a18323cc4afbfede53c55abe2008424911938e522ef5ca152ef9b5a07cc332b8063442e1fb2692261d39fc24baa3eb4192d0a58155c5fcafcb16044110044110849226261da558f299339c6feb47a516aeb8367047727085e89be812ee21fff737202359db9391ae40e551b5a4c315044110044110847c89494729f5e0efbf39dbf1153cdeee80438b4668cb564097918e26ea3a56b72ea04a49001b7bb07320f9c603dc86372ee99005411004411004215f62d2510ac51e3ac499d7ba5079e102acdbb527436543728686d4d43434357538fd6f09aa9468243b47329295249ebf49f556ad4a3a6c41100441100441c89798749432513b7772f68d5ed4e95c19a76bab90361f81d40474d13770525871a3cf0fc80a1592ad23929d13b1872fe2d0a9034a1797920e5d109e086ab59aa8a8a83cff2e8cb4fbbbf1e9738e53bf8b27c709822008822962d2518adcfaf517ce0e7f87da9f4d40f55c4d9255f6c819a9e8126351385ca5ccb53fd04a2a64a50ac9de114dba82e8bfaee01dbaa2a4431704b36834325656d263cb579003070e3c527e1bd7f68c538ee5c79b43185cd9a188a21204411084a78fa2a40378d6e8d2d339dc29800d4e0efc56ae2cdbdccab1a3a29a3d552a727ad430bc366c42d53588f4e7fd49add290248f4624d4e9449247137476ce68b55a50aad062c3a56ff652f1e3a9d8d5ae5dd2cd12cca456abd9366b301d027c69e4d79bd0a854fdb6abab27d2befd2bb469ed4733bfd7f8f95cac7e5bf29dbdf468d510dfb6ed19346b1b6ab55abf2d3df134a37bb5a76ddb36b468d5859fcfc692db85904eb4fa30fb11a629d11ba8ea3d0819488bf98381ed9be3ebe74bf3f603f9f37e5a8e7873c79f1f53b1abd56a36cd0ca27d405b06aeba6256bc96e633557f6a5428bdfd1ae1dbb63d419f6ccb51479b366d72d4b7ffcb51bcdaa11d8debbdc4a73b6ee8b799eaff0ed39a1132fd9f7cdb2008822008422671a6e331d2693484bed6195b6d02af6e58809c9682363519393505dd8df358c55c42b96f2ad2d172e8942ab419122977efa0ed3c1e1d0a7465caa1d5ead061c585ef4329dbfd0d2a8d7eafa49b2558685b8349ec9a5293ab5bdfa5539fa55cd83f1c008f800fd9ddaf1c0009ff6da47ed7e9049e5d00c00fbd4750f1c35d6ce85c83ab5b87b3d5a0bc55bd0379e1f3c32cacef4ae2f58dd4edf03181e7bec951a7e75b5f11537710f1b30fe36c257174da17bc38750d12b0a45710d6a3b671b8bb2757360de1d5d7bfe762e8288bda642a76803df53f60f7542f009676aa5b60bc96e63355ffd23ec328fffe4e7ee95c83abbf0d658b89766c7f6e2cdbc7d624e1da72eabc3296499dd603a6fbdfa5ce5bdc39bc0c686d519f09822008c2b3444c3a1e1359a7e360afd751a4c6f2e2843791526341938ef2c16d7411a720390eecca80831a9dfb0ba4865f26edbf536464a4a093659094c8655cd168b4442e5a8943a316d4f8626e49374b2884d91dab0350bdc32ce286f90299938e07e1bb080a5a4a44bc06a5422225fa329079e0fced9578fe685fed61be99c0affaf2e69e8aa1c2a8d759f570d9411197a74e2b3b2fe6364f66c2e15b84b452316e7b229b8333e35878218e239d6b0250b3f3a7c48d68095836e930153bc0a75d3c2d8ad7d27ca6ea5f78218e23597dd7e91360a3d1fa6677aa0180538dfea4c77fa45f6faaff558e3ea4270c325aa6200882200862d2f178c832a1fdfb927efb3ffcc7f5427a10857cff16ba3b9733271b00d6f6c8ae35902bd627e5d8ef681ec492929a8cad5319d29190252b74766549fbe443eccab8e0bd54dcc7f1549065fd3f0704be4fff2d2709aca74697114d0577f32e9bd3ca322bf7eca38ab5d2643aff2f8633a6db8fdc9c7609fce651d52633bd0ed920958444f6bd134a494247e67598b22ec568d905c5ee62957d25a7b9f15a92afb07d979b9d22abed4a645953a8320441100441c84bdcd3f1181c1cf2368967ffa6f53bed20f22cda537bd0fd170649b1808cac50a175aa497a3224edf8119d9515094909a46a241c2ba9d1ea408b92c86d47906f46d260e3162465c1076c42e9346df7750022764fc5d96ba47efdad341d55dd9d00f877f5b81c7986d57266faef99f7185cdf333dc7b6890dca337ec571fdf2b5e397f2add7c163303db5cb193a3694119ff9e9d78ff17661f2ce7000c2774ca6acf768fd365f676b56852764c6bb67aad136998a3d3773e3b5249fa9fa477a391bf4f914b3eacacd54ff673cf81b1b27716995200882209822ce7414b343a3471015ba9d8efd1bc08550646dc6c32d1248123a54e89cbdd03e4822fdda69a4ca5e445dbf445a92960a9e1e583b96459624e276ee20f164247e7f1d43696757a26d121e4d877f66d0e1ab2bdc4e75e3db0df3f5eb57ceeecf5bbe2d707177c5336002b053bfed9d750be9d7b32bbef32a50cb77080a65f69d09037f5dc7d94163f0f949832d1a2a379dc09ac65ef9d63d7c4643fca77812e45146bf6ef0fa650cebf7267ef3add0d8d762d9fac1fa6dc10b47d2ab8b3f2b3c2ae1ddee3d6079bee59a8a3d374be235379fa9fa83d67dcb9b3dbae11b5c114fff51c0fa02ebcacd54ffc75ef8890aad06ea97fdfdfd090d0db5b80e41100441789a49559abd2f1fdf3ab15099434242f0f1f1212020a088c37a3afcf1e1fb44ac09a14bd70aa8ac159075d98a94f9b74eb246e75813cd8378326e5f854a35b97bfd1289711adc6ab8e3ee5905858333e76f397163e97a5e0e3b869d8747c935e8099292924270703043870e2d96f243424218376e1c49494916e52bec7b21749afb60e58a02883c389d566352b976728ec5e5ac0b6cc4cefe5b58fe6a158bf33ecb4cf5ffca8e7549f9fe28ef54118fcc1584a78138b6119e448539ee3971e204616161c576ac64a87197b9e24c4771f9dfec195c5af91d3dbaaa51a924900149062490e5cc7b346cdcc988ba85e6fe1d70afc9ddf00b24446b50d7aa884b253714f68e48655c88db1f4ac3858bc584e31996726f2d1dfbfe8a424e2351e1c1fc5f9658943f3dfe10015d2690ecdc8e831d2b1753944f2f63fd9f76ff77e665bccd2931e1100441100493c4a4a318dc3e7e9c7d53a6636bab62c94f3791b532e874483a9916adca53bfa12b3a557932a26fa379701fdcaa111b7e8198e80cca57af4099726aeccbb922d93922a96b909eba076b37b7926e9650040afbf6eb32ee2338747044a1ebb576f6e3e0a1b082130af932d6ff36ae019cda2b7e0d15044110848288494731a8d4b831e3a2a250aa5428adad51a85428acac089b378f07eb3e434b5934f7a3d0a42440f92a24dcbcc2cda80c5cab95a76cb90ab8b8ab51d83a8053055028494b4e45e5ec5cd2cd12044110044110844211938e62625fbe7ce63f341ae46d5bd06ef819e9cc45d2349011771f6d5a0ab26b451e44fec7f5680d2ed5d4942b5f81b21ee550da3b809d03d89641d6e9c4a44310044110044178a28947e616a75bb7d0766b85eee65aa485dd510eed437a5a3adab46464970a3cb813c1ed182d65ab96a7fcc3331c2a0727245b07b02e03b216642d6929a9a89c9c4aba35822008822008825028e24c4771b97d1beddbed90bf2d8b54c50da41834b117c9d0ea909dcaf1e0ce75eedcd751a68a0be5cbb9e1ea5e1e95a323924d19b0528142093a1d2874a426a5602d261d822008822008c2134a4c3a8a49c69411483374489592809b686edc20edea36d2e432c4dfbdc9bd38097b0f17d4e52ae0e2f170c261ed0056d6649e80d281ace3afa55b71a95747bc0c50100441100441786289494731d05eba449ae61c76e56d200964eb2be8921ca8f9c648fed9bd9675bbe2b0b1b6c2e17c2aae1ee994aff88096dd9ba354a9c87c6960e6d3ae8e2cddcebdc864ba1f3854d24d12044110044110844213938e6290b8f46b6c5aeb20195081a4b2c7baf6602ad576674c783fd0a512b5348cc4e80c68da94ad03fa53cf3f1557fb3299ef0f94240e2cdf454c948e1ea187b176742ce9260982200882200842a189494731880f0bc5a3b51d240136f648729787f7672420cb20674412bf79279ebfed4652a95039d821593d7c63b9047b97ef25260e7a1f3888b58378e998200882200882f06413938e229672e60c0a8f34c8b081342724fbaea0738274c0f601b27c96ff461fc16de25424950a008d2c232995c8c8ec5eba8fd8442bfaee3b80aa4c99926d8c20088220088220140131e928623717cda1423325b836422ad718743699130e85066dca312ecf08c3b1f948cab669abcfa393652409b62fdd4b7c9a2dfdf6ed47656f5f728d10044110044110842224261d4528f1fc79d292227078a92328ac21391239299594fbd7883a19cead5005de53bfa75cb39639f2c9b2ccb6e507d039a8e9fffb3e54767625d40241100441100441287a62d2518452a2ee90986acbff668421cb32b2a4439665cad4aa8d5bdbb76931ae0b9255de2ed721a175aac8805dbf63656b5b02910b82200882200842f111938e22a4f66b83daaf8dc5f97aadfa19f7468dc48443100441100441782a8949472950b579f3920e41100441100441108a8da2a4031004411004411004e1e926261d8220088220088220142b31e91084c7e4fc927ed47f6d718e758b5eab4fbf25e78bac0eb55a5d646515b7478df551f297867e2a2886a28cb134b4174cc7616c5b61632f2d6d1604411032894987203c26b507ada0cbfd854cfc3d12809b7b26b2e87e57560caa5dc29109a58d462373e0c081920ea3c83d8d6d12044110ccf3544f3a2449429224ec5c03c8901fae943368e762a7dff628e5e6f7a738dcfff737dee9ee8f473947ac942a5cdd3de9d877549e78b204060612181858a4311467fb9e19921553372e66c7bbfdb9107b81fec377b078e314ac1e766b5acc1f0c6cdf1c5f3f5f9ab71fc89ff7d3f45973ff6a6bea57dcfd5f8ee2d50eed685cef253edd7143bffeeaea89b46fff0a6d5afbd1ccef357e3e170bc0d9afdae137ed843e5ddafded54f17a0319484f3ccde85eed69dbb60d2d5a75e1e7b3b1f9d67968de501a3769411b7f5f3a0f3da85f6f6e7e53e934299798f4f6abf8b4f2c3bfb51f7d279f6067ffae00f8fbfbe3efef5f6019a951a1f4f66b846fdbf6047db2cd68dfe55717147edfa8d5ea7cf7477ef1abd56a36cd0ca27d405b06aeba429b36d94fc233d536637d9f25bfba4cb5c75061c68ca9b20ddb64ee3e01d8366b301d027c69e4d79bd0a854b3fac590b198c23777a7e5f8bf01b87f7e3c6e6e6e9c4cca0060918f275fdd4c34199720088260be67e2e955a9b17b792fec2e5fbf5481bb47c7b02f2eb5e04c26ac5dbb56ffefbe7dfbe6596731590352febbe2fe99afa9d564340938f0e6b88f79f9050f126e5e64cb9aef8145f9e6f9f9e79f0b1f8b50ac6ccbbfc2ba093ff08aff2b349bb08357ca673f267949af20ac476de370774fae6c1ac2abaf7fcfc5d051264acbdff6e7c6b27d6c4d12ae2da7ce2b6399d4693d001e011fb2bb5f390012fedb48fdaed3093cbb80e7de9e4a78936968676c41099cff7a2e5eef2c460256f50ee485cf0fb3b0be2b89d73752b7c3c7049efb264f9d838337b3eb6a24356dad48be97a25f6f6e7e53e956f5e9c185765f13b6cc0f80f8c8149c3db6805a4d6868a859652ced338cf2efefe497ce35b8fadb50b618e9bbfcea8247db37f9ed8f8e2bf3c60fb0a7fe07ec9eea05807aa279fd63acefb3e45797b9ed29cc9831b76c73f709c0b60693d835a52657b7be4ba73e4bb9b07f7881fd62c8584c157d071039791dcc6fca95903f79b16715169c8a61e94bf67c7dd79e13ee654c44250882205842aad2ec7df9f8d68905a7cc474848083e3e3e0404041471584523eb97f91e6a7b42dd3e22facc6466d52dc79ca83624476d0032df06fee90be5997c268e2dd1897476b5e5dedfef50c1e707eabc7b98b3dfb432ab0e599673acd7a45ee1c30141acd871940738f252a7012c5931074f5bab1cf942de69cbb8a5a1246668f32d7fea732eccba1247e02fffb1b657cdec0d061395dc31e45ed6a5dfe1b35143f97ee37e22633370f76ac29029df30a56f831ce9d74e7983090b37126be5ced81ff633bb7bb51cdb0de56e6f699392924270703043870e2d96f243424218376e1c494949966796d351bb7970eb5e142a83aef576afc891885b945729d0654451a95a4beedeba0464fe0a1e1515a54f9b7bd970fdf5bbf7b05348801637b7cadcbb771b80e8b0d5bc376b2911f11a940a8973e72f73ef6ee6a55e9ffb78a25b738c8f3c9de8ee599dd1c7aed0a6ac35b53d2a52e1396f7df951d1719c3d73324fbdb33bd5639f5b07deeede99d73bb7c64199d93053f90ddb602a9db77b45f68547e261adccd356c33e28a88cecbe8da6827bed7cfbcf585d85dd37a6f6477ef92eddbe8b8b95c2a2fe31d6f7a6faca547b0c1566cc98db57e6ee13b55acdf95b77f5e9dcabfb7227f27c81fd62bc2ec398645eae518d1fce5f6551d3ba0cdb328cc08f5ee0e0176134edabe6e21f83f3c4233cfd4afbb18d20e4a730c73d274e9c202c2cacd88e950c35ee32f7d938d331677e2bbc064c63e91977a69f8fa5dd8a39ec796b837efb90e503f8b849301f4cfd87ce8b5bf2fbf8ed4892c4cc994d0a5de78a2e6d98bff7262dc706d353dac0d8e0f9b4b95f9b1bbf07e548179cd88a6fbeed68b49caf231200f8eab5ea3937183933929f9f7b3767f26fe1bcbdfc300b7ad6273438806efd9ae0dcfc3ea3ab3be9d37d72fd79a64eeac9d00f56317f5010b3bbef0532cfe214c9191d2193640d9063c201a0c370222721919d402949e8c8bc1e52d6e5fd35db50e6012e801259d6e8d70f087c9ffe5b4e12584fad3fc8cbf2c68c66749df207c33f39cb699761b4299b19a3569659b9671f55721d84e73679fb09bafdb9971d9b16f1e2c27d5cd837cba2fca6d2997b559fb9759962acae47d937c6f6477eb2261cb9996a9bb1be37c5547b0c1566cc985b76a119fce061ee3e371e93c47b759c987bea6f7e57f625b8da3014a7fa13be3a865a83438a366e41108467dc537d4f47969a7d9651c546c1bbaddf45615395e57d6ae6d8ae6e3c971e6a7b2e2f1bc2fd945b8cfdeb2ece9e93e851deaed0754e3a94f96be6fa3963183d27f3f296db873ece936ed30f53786bf004a3e564fdfffa28ff6d8fdf99791df94f41feb83897a3fb8c63c8b29649a4ba29000020004944415455bf46e448b7f9bb8f1932e17b00d2e243f5eb0def0f298efb45844c63bc5d98bc331c80f01d9329eb3d5abfcdd7d99a55e19913d0883d530b55fead341d55dd332799ffae1e97639bfbcb9f93f6e7c76cfd680d3ed3fbebd74f6c509ef12b8eeb97af1dcffb6b38723ae7a3b5d46fd991f1b33e23eec206cbf217906e928f1ba343fed42f675df2e4aa5272375d67561923bd9c99b6fb3a0011bba7e41b83a9ba8a63dfe48edf14a36d33d1f7a6ea32d51e43851933e6966dee3e010cd24dc5d96ba47ebdb9e3cb544c0d47d666df47a370efd60d4961c7bbaea799bae432bd3a55361993200882609967e24c87c2da9de56f7ad2f6c70b780f594625ebdc732d055f2c6acb86c06d749bd58ba80c2dbd170f7ba43af5bfbb4990fd235bde395e6d7bd3bb60447527665f8963ecd60856bf5ec3608bd6b01693b2262c9f1f384a7b171bfd7a95538d1ce96ad92a81cc89962ce77fb997507c06af5fc6b07e6fe237df0a8d7d2d96adcfbeb42378e1487a75f167854725bcdbbd072cb7b8fc95b3fbf3966f0b5cdc5df10c9800ecd46f535a7b30abb18ee1875339b6d25dbf7ee0afeb383b680c3e3f69b04543e5a61358d3d82b47b9b22e95a96f76252a5d222329950133d75894bfa0747dd76ce0dcd031bcd8f2631c55e0eebb80d5b31a31bfbf2faff8b6c6c54e496868a8c93282d67dcb9b3dbae11b5c114fff51c0fa7cfbc8585dc5b16f72c76f8ab1b699ea7b5375996a8fa1c28c1973cb36779f0074f867061dbebac2ed5437bedd30bfc07ec9cd544c6ecd86107bba1f6ffc98f96394dfe05a4c991acd7a377b7d1a7f7fff02f79120088260da33714f872ccba4271c61e1f77fd1ec9dd1b472b2ce7bdf8326867ace95fecfde7d474751b5711cff6e49253d6c2821f42a201079019584d0045144418a288a8282d2442c808205152b2a2a8a8a0a2a554551e91db104a50aa2a202d2135248df6477df3f024b7a362105f4f739678fd9997bef3c77ee2cceb37367875f5333317b35e4d499df0934177f7da1b07b3a16dc548fc15f1ca4e38457e9e758c2f8195ba97be37cfe5e7a4b91f5f23abdeb35eab77d8064fcb8e3c1497469194ad2f13f58f6c9dbacd87ea2c0b6f2be5fdcbf01033ffd0b4bbb213c3daa076e69a7f871ed97ec6af92adf4f6d5d6c7d803a9e6e1ccec862dabbf3685ab51137dfd8a1d87d53992eea7b3a4444e4a275b19fdb881444f7745c44dcfd3af2e08385df146e34073377dc65b49bbe8b06b7bce352c25194818bbfe7c0c83b7963f6234cc49f9e773dc5076f0f2c713bc1adc6f1e78f613cf2e4abac98fd141f26a4e35bb516ed3bf773b98d9b174433236c0c6f2ffa9afb867e8cbb9f8566adda715b643597db9837a91f83667cc994bb6fa74ac8ad177dd22122222222178f7f75d251d45584bcebbefd7633dfff710683c1cc53cfb97e425dd8368c6ed59932670553e6943cb6bcaa86f765ce977d5d8e21ef7ba33998f133e6337e46e9ea03747a7c21c71f77316011111111911cfed5494749444474c2cdbb2a039f58ce004be96f20171111111191dc94749c75b13f774244444444e452f59ff8c95c1111111111a93c4a3a4444444444a45c29e910111111119172a5a4434444444444ca95920e111111111129574a3a4444444444a45c29e910111111119172a5a4434444444444ca95920e111111111129574a3acad0a79f7ec9a953a7722ddbbd7b3fab576fe6e79f775e70fb3ffcb08365cbd6b26edde65ccb1312129833e7e30b6e5f44444444a43c28e928437ffe79908f3e5ae87cbf78f1e7c4c7c773d9650d484bcbe0d557df62d7aedd256ef7c08183bcf9e607d86c99848737c3cdcd9db9733f71aefffcf3aff8e5977d65d2071111111191b266aeec00fe4d828303f1f3f3e7a79f7ea66ddb2b3873268d0103aec466b351ab5628edda85f3c9279f71e64c12111157bbd4e6ae5dbff0cb2fbf336cd8203c3dbd9c6deddebd87c4c4444e9d8a2130b02a164b6039f74e44444444a47474a5a30c198d0eaebbae1bebd77fcbc99327f1f4742323239da4a424e2e3e3c9c848e7965bfab067cf6ffcf9e75fc5b677fcf8717efc710737ddd483cccc2ce2e3e3494a4a2223231d0f0f770e1e3cc8dab59bb9e69a488c460da5888888885c9c74a65a86ac561b595959f4ead59d458b3e273e3e8eb4b434ac562b56ab95949414525252e9d3a7275f7cf10d0e87a3c8f6befe7a0dd75dd78db4b4745252529ceda4a7a771e2c471962f5f4b44c495646565919e9e5641bd14111111112919251d65a87efddaac5dbb99dab543090808e2f8f153fcf9e7416cb62cd2d3d3c9c8c820393919777733d5aa5563cf9e5f0a6debe8d1a3f8fafae0ee6e223939998c8c0cd2d3d3b1d9b2f8f3cf83fcf3cf096ad6ac49edda3558b36613dede9e15d853298db707f4222a2a8aa8a8282c168bf3ef5e03de2ef76d5b2c964aad5fd12eb5782b93abfbaaa872a5dddf39ebb9d286c6b578a5d94779eb94c57e3ed74665febb27221717ddd35186ba77efca4b2fbdc65f7fd52522e27f1c38f037ab576f62d0a01bc8cab239af6cd8ed76ead5abcdf6ed3bb8fcf29605b6b577efafd4a9538be4e4143233330130180cd8ed36bef9662d41418174ead481bffe3accc68d1b79e491f115d64f299d918b9733f2ecdf168b858d1b37566638ff5959590ecc66c3bfba3d57dbc8ca72b061c3860bda5659b958e2a848e531d617db7e2cab7ff7cafa732622154f573aca90c16060d0a07eac5dbb1183c1405454078e1f3fc1d6addbb0db6d58ad1967a747a5e3e666222121b1d0b6525252319b4d39a6676560b7dbf8f6db68fefefb30ddbb4762301858b66c255dbb4610161656813d95f290717a2b437b5c4944640457f618ca7771190596dbfcd208c2afb88ace51115c3f629373b935790f63fbf7a04b97ce5cd5b1370bf7c61758bfa8725969bf33f9ceeb68d73192a84e91dcf2d80e560cb901c0f90d655e7f7df2103d7a5c43e74e917488bc9185fb0ade6e416d17d7efa2be81b5582cac7f650cd7f5ec46788bf63cbbfc1f8002e3b5582c2c7d6a183dba77a14344133a4e8c76b69316fb19b59bde45dec98ec5c575aebda11f1fc855af34e393b3bdffb5ad4be4e33bcec711f70d618d07e328411b7963cabb0f7396ebdcb9b3735dea89b5f4ebd89a882e3db86bdad7f9f6bfabfb3bafc2c63ea79c711457de614be1d5bb23b8e9b185d8f2b453dcb815d487bc5c3da62fc6b1ceb91f5de96f61e357583d57ff9da951a34681cbf32aede74c442e3dbad251c6c2c2c2080ef6e7f7dfffa64e9d9ad4ad1bcaeeddfba85b37141f1f1f0c06036e6e666262e29c53a24e9c8861c78e3da4a5a5d2ba7573ead7af47b56a166263e3f0f3ab456666f65592c4c4337cfffd369a366d40ad5a35d8bfff4fce9c89a36bd7ae95dc6b290b73fa0fc37dccd76cb9a9210796decd757ddfe1b78d63f2951b3ee30b56fe7594fa9e66524f9dbf97e7e30183b8fcf92dcc6c1944f2e1cf69def35106ed9b95af7e51e53e1ed88ffdddde24fa834800128fa6e11fba0c8af88632b4fb4456dd1a0cc0993f3fa7e50d4f3068ef6bf9b75b40db25e97741be69349e6fc6d7e7ccdf1f72d935e399dceb53aefda8e07857b77c8455531b9395f63b2d9bdf45e2d35bf0371bf8f1f117683b753e79bf432d2eae73ede555daf139d79e3571330daf781cdb93cb3001bfbef9228def79034309da284ece729687ce2f7f77c028aa4f5cc967d7d7e3afafeee3ab0bd8df391536f6a5296fb31e67eac06b39dde515968ee99caf6e71e356501ff272f598be14c6bab8fe16367e85d573f5df99ddbb5dfb79f8d27ece44e4d26308ebf0b063fb570f155fb200b367cfa65dbb7674efdebd8cc3bab4a5a5a5f1da6b6fd1b56b24e9e969ecddfb070d1a84e1efefc7c993b19c3e9dc09e3d7be8d2a513369b91949414ead5ab89d16862fffebf003b6ddbb666f9f29554ad6a213838906ad5aa72e64c12bffd7690cb2f6f82a7a7170b177ece6db7f5a74d9b3695dde58b4e5a5a1a3366cc60c48811e5d2feecd9b379e0810748494929557d8bc5424c4c4cae654d6b56e7db43c7a8ea66c49e19438d3a5773f2d8eff9ea3eddab05eb427a72e74dd7d3f7fa4ef898b24f979b8556a75aa3a6ce7231b109ecfd6567beed1555ae69cdeaac3b7894507753b1f19e131bfd09f74f7b9f438959988c06f6fdfa07a74e1ecd57aeb0b68bea77deede67c6fb158387cf2145e4603602324a416a74e1d2fb4deefc74f1268cebeb8fbf5ade17c39fc2b667774a36da3ce7cf1db6e6a7b942cae9cede554daf1c9d9def3ed1a629fff13931afa7153c3ba8cfde9009d03dc4bd44661f296cbb9af9ad6acced643c708763362cf8ca55acd66a5dadf79b9725ce58da3b0f237360d2068d4529e1fd4a2d06d15356e85f52127578fe98b71ac5dfd8c1456a7b87a45c5559c92febbe7ea315dd6746e2397a2d29cf7ecd8b183e8e8e8723b57ca29bcf78bbad2511ebcbcbce8d9b30b3ffcb09d366d2ea355aba664666661b7dbd9b7ef0f1213e3090c0c24292985d0d06a04067a111f9f7d89ba7efd9a180c2676efde87878717274f9e2236360e8b2508777777dab4b90c93c9c40f3ffc44b3660d9470fc8bd8734df03160c8f7dd7bb6c7bed9419fefd6b27ce9ebb49db98efdeba601607338f868f53ac2f29ca8e55554394329a64cdf31e861862cdbc9a01616e7896a410a6bbba87e9b0c06ec64cf0375d8f37f3b9e7d520460c2e1c82a32ce9c272e512fdcc7b83eef71e4f1df21f2a57c09477171e56d2fa7d28e4fcef6063fd9811ba66ce5be67f6b22770249d03dc4bdc46514a7b12e7cafe3ef8d97d0c7d3dfb61a557bef539d39b0595f8b82aaa7ccfa8663cb76215a9039ae36dcc5fb0b87173a50fae1ed397c25897e433e24a3d57ff9d7155693f672272e9d1a7b99cb46edd1a373713361b646565cf3acecccca255abcb080f6f43972e11d4ab570bbbdd465c5c3c1919196464a473fa741c595956ead50b253cfc721a356a488b16d9490b80dd6ec366b31313738a810307546617a58c8d6b1ac8632b0e027070f96304341d9bbf90c3caafb1365a5e7d2d13a64d2761ff67ce550fb5aaca84b9db9defffde9eff2a4971e526b70b61ececef9cefcf4d6b09723371d26a2fb0bd6319766ad7f40360f7270f14dabfc2da2eaadf11feee7c7cf00c0087564f2db4edbc8a8a17c027743837db3e64c4f88d8c9a1e59601997c623af32181f809a5d9f27e3bb47f96ad27cda3d31a4546d5c79e595c5c79bc7c806fe3cb1267bfefee1d54fb85c2fe7feaedb6f161b376e64e3c68d4c6f1604143ef68529aa7cbf69cb78b4feb7440c7981645bfe9f1d2fd5b8e5e1d2317d118df5852aeef3925359c75516e3252297065de92847d5aa59309bcdd8ede7bf25f2f5ad82bfbf2f999999a4a65a7138ec04040472ecd8490c06a851a31a566b3a999959b8bbbb53a38605bbdd8edd6ec7603000068c4613d5ab57c3d7d7b7f23a27656ef8a71f30f2d6db887cd94c9677033ef87478be320e7b3a536fbb8118ab81cc9474ee786abe73ddd0258bd87bd738dacdcbc2932c6afdef41e687e79f0b5d54b95be67fc6be11e3687bf5a3f8ba41cd88d7f8645a1b5e1e12c135119d08f432e59bfbfdd1d343b83de22a026b06d1b0fb83c08a02fb5758db45f57bc6ccd1f4ef1dc5dcd01a34ed763ff0a14bfbb2a878cfb9efc9d6444d69c8b0d02a05ae77653cf22a8bf10130b987322ddcce7d5bd2f9e9a39a256e232bed578ec4352a36debcee5934935b6fbe818897aad120e26e8ca6652ed52b6e7f1736f68529aefc8d8f2fc5fc4c7f22073fcbc6f993f1339dff76bc34e396972bc7f4c532d665c195cf4b79c55516e325229706ddd3518e962dfb865ab542494d4de2dc73001d0e873381f0f6f6e6e4c9d36cdfbe832a553c090e0e26363681a64d1b53ad5a30a9a9a9381c0e8c46e3d98423fb17b2bcbcaaf0e38fdbb8efbe7b2ab17717b78bfd9e0ea97c8b06b561c590657c78ddbfef97df4eef19cd3d7bc6f3d9e00625aa67cf8a03731046e0e8a627e8382e9dbf773e573e418a5ca4746e239722ddd3f11f959191c10f3ffc849b9b1b767b1646e3f9b9af0e87030f0f775253adac5ebd1e3737137dfaf4a2458b16984c2662636359bd7a0dbffdf63be1e1adf1f6f6202bcbe64c3ab2dbb0131a5a8bafbf5e41e7ce9154a952f037b522929f357133dd7b3f48aa7f37365d5babb2c32917c12ddfe0b3821f0154a4b4530bb8f69625181d19241b437979f19cb20f4e4444fe939474942187c3c13fff1ce3e79f7772d9658db1d9aca4a5a5e1e1e191ab9c8f8f0f3b767c4b9b362de9dab56baef555ab5665f0e05b3870e0005bb7fe48870e6d494e4eceb79dc68debe2eeeec5ead51ba8572f8cd6ad5b55481f452e75eefe916cda1c5d7cc1ffa02a3547b179d3a8ca0e434444fe8574237919dab2e57b52525269ddfa32ecf64cec76079e9e5ef8fbfbe3e7e787a7a7678e973beddbb7cf97909cd3b06143aa54f1cc55c7cfcf0f7f7f7fbcbcbcb0d9ec58ad698487b7c4d3b30a4b97e6fd457d11111111918b83928e3294969682c51280dd6ec7c3c393a0a020aa55abce8913a7494848a27af51af8f9f99e4d22bc724d992a8897970f1e1e1ef8f9f952bd7a0de2e3933871e234d5aa55272828080f0f4fb2b2b2b05802b0d9322ba897222222222225a3e95565c86834e3e1e14170701026931bfbf6fdcea64d1bf1f7f7c1cfcf8f1d3b76d1b56b147e7e9eb46fff3f7efae967aeb9a6e01bd5b66fdf418b162df0f2f224393995cf3f5f80c1e0a066cd1aecd9b38bb66dff47b3668dc8ccccc46c36396f541711111111b9d828e9284366b3095f5f3f7efa6907ebd76fc0c7c78b7efdfad0a041f62fc8242424f0c517cbb8f1c61ba95b378ca3474f70f4e85142434373b593909088c160a656ad6a2425a5b260c122faf6bd8166cd9a61341a494e4e66c3868d6cdb164dfbf61db8e28a56b8b9b957469745444444448aa5e955652831f10c2fbef80adbb7ffc4cd37dfc87df7ddeb4c38000202021838b03fab56adc36030d2b1637bbefbeec77cedfcfcf34e5ab56a8ec96466f1e2cfb9eeba1e346fde1ca3317bb87c7c7ce8ddfb7aeeb8e3364e9d3ac65b6fbdc7c993272bac9f527a168b85cbfb7e986f99ab75cb5361ed5fc8764b5bb7bcfb7aa1ca32be0b6daba8fa39d7592c16a2a2a29caf312b8f5cd0764be2428efbd2f879c173f48ce8485454145777ecc1730b7e2e553b151d7771b1b8b2ec4258937ea0664808d7cede5fa2edb852afb0bf45e4bf43573aca509b362d69d9b259ae44232f2f2f2f1a35aacb8e1dbfd0a64d0b3a77eeccdab5ebe8d6ad2b00dbb7efa455abcb311a8d6cdbb603a3d146787878816d55a952856bafbd963367cef0f7df7f974b9fa4ec35dc3385f70ff5e3ae3a17cfc31db3b2ca677ede860d1bcaa55d299de21efc9695e5c06c2efa5eb3d2aaa8e3fee89a8719383395956b36d0d0c78dcce403dcdfbd278f54ddc4f3dd438b6f208fcafabc96e75814e6c0fb53091b3c92bdafbc0023de2ff77a22f2dfa22b1d65a84e9d3a45261ce78487b761dfbe3d64646452b56a2066b327494949679f3c6ea06ad50032323259b56a25fdfaf52db63d3f3f3f5ab5d24fe65e2a5e7ba337cf0f9959e03a6bf21ec6f6ef41972e9db9aa636f16ee8d0760c5901b009cdf521ffce226ae9eb00d80b85f27101212c2ce94ec1f1378bd5d435e3d92fd33cb19a7b732b4c79544444670658fa17c1797e1dc96c56261e953c3e8d1bd0b433f3ee05ceeb0a5f0eadd11dcf4d8426c408d1a35f2c5e9eaf63b77ee9c6b7beb5f19c3753dbb11dea23dcf2effc7b92e3d66230322db10d1a507c39ef93ad7b60aeb83ab31e4f4d7270fd1a3c73574ee144987c81b59b82ffe82e3cb69f34b2308bfe22a3a474570fd884dcee5858d6b5e4595cb4afb9dc9775e47bb8e9144758ae496c776e43b2ef22a68ecf2ca7b1c1477ccac7d79143dbb77a36dabab7969f55156be3c9aeb7b7527bc457b9e5f75b4d0ed1475dc97e518bf316109f7cd7f96863e6e00b8f934e4d9f9f7b278c21bb9fa51d8589724eec2c66befabdd887c7cc7f9fec57d4358e3c1388aa8732eae823e93aeb8d0630f1c3c3beb57a64c9d4c7ff37ade3ebb6f8b3bc60aab5714578e4b11f9f751d251493a758a60d3a66f0168dffe0a366ddac2d6addfd3bc7953c0c0ead56b69ddfa720203032b3750297361d7cca45be2bb3cbde374be751f0f18c4e55317b07efd0656cfbf9347fa3f0ac0b51f2d03b2bfa9deb87123d523eee0e8aa45001c98fd1d6d6f0ee3b55da771d8cef0e6496f46d4cc7e60e49cfec3701ff9115b366fe1a3916edcd9f79d5cdb5bddf21156ad59cfc7431b0160b31ee7b19baf66ffe54fb1f4e9419880ddbb77e78bd3d5ede7f54da3f17cb3722d1bbfba9759e3c63b97bf3f7024551ffe9c2deb57f1688bdc3fff5c581f4a134368f789ac5ab59a0d9b36b3fa83db79a4ff13171c5f4ec3677cc1a75b37b361e316164f6be75c5ed8b8e65554b98f07f6637f9b4788fe76331b376de6ed7b9be63b2ef2ca3b7639a757ed4d3dff8b77398f83e28e99af1b8c66e59ab56c5876372fddd98dd54dc6f3f5f2356cfae65e5e1f3d9ec21475dc97e5182f8e496578eddc5725fcc286931ab324d7b2c2c6ba247117365e8dee9ccac14f1ec776b6dcaf6fbe48e37b266328a2ce39793f93aebad0632fe9f04cb67adcc6f5419edcfbc8e5cc79323bd92bee182bac5e510afa374544fefd34bdaa92d4aa558bbd7bf771e4c8096ad5aa4eedda7531180c7879b973e4c8717efb6d1f63c78ea9ec30a53c18cc3cf9c130fe37f47126ee7c23d7aa17779da6da98be7c7cf6bd8f31a1c0263c83fbd020652c7fa53fc7827571bcb26c248326ed25e985681cb5c6e265cc9e9631737f02df5e5f1f80fad73f4bc2a8ab81f3c7d5b3bd1be66a7764d74882462de5ed412d8aec82abdbcfebe95ef500f0ab37046be224e7f299fb13f8b6471d00eaf67a06f83cf7ba02fa509a18920eae64d8b0f739949885c968202df60fe0b50b8a2fa7db5b5b1836722277de743d7dafefe45ceeeab81655eeb99f6258f7e9d5cef7fea15e05b65194c2a657e53c0e8a3d666e680a806fedc1d8ac0ff174affacef739f7593e451cf76539c685cb3d85b0b0b12e49dc858d97bb7f24a382eee28503094c6ae8c79373ffe2b19f1a1759e79cbc9f49575de8b1f7fdd4795c3e71310075fa3ec3a947ef22312b1aff62a67895b69e88fcf728e9a844d75cd39d4f3e59c86db7dd425090dfd9a506e6cf5fc0c08137e3eeae5fa4fab7aa1a3e85e1fe4d18b73af7cdbc3687838f56af23ccdd544c0b06eebfcc8f17776d638de91666d4198971d7100e7e729a06c3673b4bd9739d68193090fb4420d09cfb6267cfa8663cb76215a9039ae35de4099d6bdbcfebfc49a2098723ab983e16d78792c770c7a08719b26c27835a58b067c652ad66b30b8e2fa7c7bed9419fefd6b27ce9ebb49db98efdeba601ae8f6b51e58a79accf05c9791c1477cc388f0b837bbef7c5edb3c28efbb21ce301166fde3b9cc403f5fc9ccb92fe9983b76540ae722519ebd27c5e073fd9811ba66ce5be67f6b22770249d03dc8bad03f93f93e758dc4dfc63b539ebd9acff60723f7f43f6851c7bf6cc381e597b02ebaefe84bf94bdcccd7e8c49d127997555f532af2722ff4d9a5e55890c06035151116cd8b0053f3f3ffcfcfc58b1620dcd9a35a24e9d3a951d9e94b3b1f31e66d9e871b9963dd4aa2a13e66e77beff7bfbefcebf83dc4c9cb4da9def5b8f6ec6ba4963a8d9a70f06a317f706ed61ea9c3fe8dfab96b3ccb8a6813cb6e2200007973f4640d3b145c6d46fda321eadff2d11435e20d956f4cde5ae6cdf55a31bfbf3f8aac3001c5a3525d7baa2fa50d2188e65d8a95d33fb6474f7270f94497c4e0e2bbfc6da6879f5b54c98369d84fd9f39571535ae3915556e72bb10c6cefecef93ef1681a90ffb8b850253d664aaaa0e3be2cc778d44bfd993578127f245901c84c3ec0e4c1b3e8ffd2a8328fbba8f1aad9f57932be7b94af26cda7dd13435caa5394f12d8298b4f0fcb4a4dd0b2711d4e2ec317c81c7de89ef1e26b5ee64f6eed8cef6edd9af2d0b7bb36ee252a0f063acb87a22223929e9a864b56ad52233339d94940c9293d3d8bbf7177af6ec59d9614905f0ad3b8ca75afe916bd9d0258ba8b96622ed223a111971358f7ebcd7b9eee521115c13d1c97933674887bb89df73882e77644f4b891cde801f336a3224c4db5967f8a71f90f1d66d44768ae4b6b733f8e0d3e1c5c675e3e34b79f2b29f881cfc2c678a483c5cd9beab862d7a8b13cff521a24b0f9eda7e5dae7545f5a1a4317cf4f41046475c45d7eedd79ebd4ad6512df390e7b3a536feb4954e7ce74ea7407773c35dfb9aea871cda9a872b7ccff8cc6dba6d3f6ea483a474572dfdbd93f4f9af7b8b850a539664aa2a0e3be2cc7b8d6352fb0607428a37b9ebd7fa5c7286a8e59c80bd7943c192e2eeea2c6cbe41ecab4703b13b6a4f27cf79a2ed529ca1d8be611f8f583b4ef184964c7f63cf875201f2dba1db8f0636fc9e4cdb47fa24fae65d5da3f8be9cf67f829d95ae831565c3d11919c0c611d1e766cffeaa152559e3d7b36eddab5a37bf7829faa2dae71381ccc9bb78013278e3370603fead6ad5bd9215df2d2d2d29831630623468c2897f667cf9ecd030f3c404a4a4ab9b42f22229543e73672292acd79cf8e1d3b888e8e2eb773a59cc27bbfa87b3a2e060683816bafedc6f1e3c7957088888888c8bf8e928e8b44484808212121951d86888888884899d33d1d222222222252ae9474888888888848b952d2212222222222e54a49878888888888942b251d2297008bc592ebefa8a828e76bccca2345d42cfb382eeffb61a1b195b59f173c47cf888e4445457175c71e3cb7e0e752b553d17117178b2bcb2ec4b6f9d3b9b663072223a388b8ea6a864d7cad4cdbcfabace2b726fd40cd9010ae9dbdbf44edbb52afb0bf4544a462946bd2613018f2bdce1934681083060d2acfcd9748def8f2be0738f4f5f5f8854d70be8fdbfd25f7dc144568b02f66931b41351b72ed2d632a2ce6b250d41895978b6dec2f465959453f0d7ce3c68dced7eb3df33ff4acb8fa17a2e19e29bc7f28a9dcda3fe7e89a871938f3086facd890ddd7956ff2cfcc813cb2e668a9daaba8b8f32acfb128c891550f31f8cd63bcfaf566366fdec8966fd733b8c9c90a8d21a792f4ffc0fb53091b3c92bdafbc50a26d94b69e8888549c0ab9d2111c1cec7c9db370e142162e5c587005475645845562aba646d36cfc9d00c4fdf2260daee8cb9caf77d06df8a3bc3fef7d9e1a3708dbbe45951c65015cd89f058d51792972ecffe5324e6f65688f2b89888ce0ca1e43f92e2ec3b9ce62b1b0f4090b30ae0000200049444154a961f4e8de85a11f1fc855af468d1ac5b69db77e71db5afbf2287a76ef46db5657f3d2eaa3ac7c7934d7f7ea4e788bf63cbfaaf013fbd7dee8cdf3436696a87f07bfb889ab276c0320eed709848484b033251380d7db35e4d523c9f9da7a63c212ee9bff2c0d7ddc0070f369c8b3f3ef65f1843772f563fd2b63b8ae6737c25bb4e7d9e5ff942a6e6bf21ec6f6ef41972e9db9aa636f16ee8d0760efabdd887c7cc7f9fec57d4358e3c1388aa8732eaec2c6b2389b5f1a41f81557d1392a82eb476c2a36c6bc5e7f700963163c4b9300f7ec05460fbadef9ecf93e14735ce494f7ea4041fb7ac5901b009c57def2f6bf4344133a4e8c76b69316fb19b59bde45fe54c4c1b3b37e65cad4c9f437afe7edb3c74441edbb52af28ae7c9e4444a46c5548d2111b1beb7c9d53d89585774674c5c7ddc3b9dc6e3dc13323fa50c7e28bd9ec49edcbae66da825d00ec9c7605068381dbb7c700769a5671c73320128023eb6ec06030d0f1dddf0038f8d9edd4ae51158b25982ade7e346d7f1df30bf99f7641ec99b13cfa4b1c0f0c6900c0ab373d4642969d01f37730f7f989dc7eeb10463ff234ab771e7329f69c7d5e38f5566a057851a56a031e5b7ac8b97efbdbf7d3bcb605b3d184774008adafeee15c97957e80070776c2e2eb89a7af854e031fe4407a56beb6f3eecfc2e41da3f95dc330180cbc7c38fb9be1e4a36f603018088d9cebd2fe2c2af6bc63ef6a5f0adb4f979239fd87e13ef223b66cdec24723ddb8b3ef3bb9d6af6ef908abd6ace7e3a18d722ddfbd7b77aef739a757ed4dcd2cb07e71dbfabac16856ae59cb866577f3d29ddd58dd643c5f2f5fc3a66feee5f5d1e30bed43d83533e996f82e4fef38ed72ffaa47dcc1d155d909f981d9dfd1f6e6305edb751a87ed0c6f9ef46644cd2af9da5a1c93caf0dabeb996f9850d27356649ae65df341acf372bd7b2f1ab7b9935ae74717f3c6010974f5dc0faf51b583dff4e1ee9ff28008dee9ccac14f1ec776b6dcaf6fbe48e37b266328a2ce39858d657186cff8824fb76e66c3c62d2c9ed6aed818f35a129bc6d0509f42db2feeb8284a41fbfada8f9601e7afbe9d73aeff3facff9ad38b1f20f1ec158f1f1f7f81b6531f25ef35d5a4c333d9ea711bd7077972ef239733e7c96d45b65f5cbda2e4fd3c898848f9ab90a4a35bb76ece577166247764d65bcf3bdf2f1c70258fbdb38cae2fad203ef1246fde92c9e3b75ec1cc8367a87fc78d00fcf8fa6fa4c52ce4f7341b19895b589f90c19e97b24feeefec9d3df5c4af413f566c3f444ccc69620fae236ec72a46747fc0e53e9cde339914bf5e0cb47801f0e6a13300bc7a63dddc050de79fb75854ec393d73b8095327df4ceae9bf78f9ae61cee5d78d7b8343d62ebcf7d147bcfeccc35c55ef7cdb737b77e6e5c59b6972f7749ebba7099b17bf4ce7de738bdd9f85c93b46d7be713b00b31fcdfe1ff8ce27df04e09637af078adf9f45c59e97ab7d296c3f5d4a66ee4fe0d9ebeb0350fffa6749f8fdf55ceb9fedddd0a576724eaf6aeeed5660fd62b7754353007c6b0fc6668de5e95ef59defad895b0adfb8c1cc931f0c63ced0c7c93b73a6b06d7a06f7a141ca62fe4acf62c1ba385e79e83676cedc4bd2d13771d41a8b97b124d3fa726ff4e95ef500f0ab37046be2d652c5fde2aed37c3ca62f5151515c7ffb4c7c8cdf01e0ee1fc9a8a07dbc702001b0f3e4dcbf786c78e322eb9ce3ea58e6757b6b0bc3464e64de971bb1077b161b634915775c14c5e57dcdf9fe9bbd1af3e295a93cb8e518f6cc533cf04d32aff6ab9baffcf753e771f9c4e100d4e9fb0ca7563dec4c548a52da7a222252b12ae489e45959ae4f975afaee149a799f0f6bc28aec4bf8f38645316f18801d87c3c1c74b0e3166c20354737f9263ab3ee644ef037887dc4edb8c05ccdc114b66740c6ede977167f5ec6f503d820359347d2c3b0f1c21d56ac386839493f3810f5c8a2b7aea6aea0e58e07cef38fbffb4a24e958a8a7dec432d9de5be78fb51eabb5b19f1c8c764246e742eef64f1e2d3984dcc5f0c8d1b36a1db98f3b14ede7c1c804f9f1b4788e116c6cfa8c1f1cd8f02b94fc6f3eecfc2e4bc0a0510d8ec29ba05ce60d3d2fb49b3fdcc84857fe1e11fc1732db2a75f15b73f8b8a3d2f57fb52d87eba94d8739d301b30e4398202cd17f63d40cefac56dcbfbdc89bec13ddf7b473153f2aa864f61b87f13c6adce7d137be1db3470ff657ebcb86b1b6b4cb730a3ce488cbb8670f093d334183ebbc06d0cb078f3dee1241ea8e7e75c96f4cf1cbc2d0372953b9fb0984a1db7cde1e0a3d5eb087337e5ab33f8c90edc30652bf73db3973d8123e97c76da525175a0f0b1b4b89bf8c76a73d6b359ffc1e47e7e1ad363dfeca0cf776b59bef475dace5cc7fe75d35cdade39fdab7a31ef5832a3c37c0b5c5fd471613218b093fd6d94c39e96af6e49f675cefe47bd701fe3fabcc791c77f87c897a8ed91bb0ff6cc381e597b02ebaefe84bf94bdcccd7e8c49d127997555f542b751da7a222252f12ae44a47ce6f658b93f704f9dcffe29edff0233b77ee64e7ceddecd9b3878f06d6c760acc2c47afea49cfc802f9fff851a9d8732be7555a29f98c3f2b834825b3eeaec60ff363d99f6fafbb4bef91e264e9c4855b30987ddea5a071c594cda788cc10f37772e1a5537fb4468fc5779a7f9d89c7f15157b4e0d3c4d188cd957501c8ef3f53fdaf733efbf743f978556e1a7052f734bb7f353949cffcb3690e38bdffcc3e94ac2019c8d2ffb756e0b2f8ebf8ccc943d8cfc7c0cd149569a8d7e05f3d94e15b73f8b8a3d2f57fb52d87eba948c6b1ac8632b0e027070f96304341d7bc96e6becbc8759367a9ccbdb6c3dba19eb268da1669f3e188c5edc1bb487a973fea07faffc37c2038c7aa93fb3064fe28fa4ece32a33f9009307cfa2ff4ba3ca3cee875a5565c2dcedcef77f6fffddf977cdaecf93f1dda37c35693eed9e18e2529da28c6f11c4a485e7a7f7ec5e3889a01667af123aacfc1a6ba3e5d5d73261da7412f67f56e2ed8d7efe2666defa187f9c39fb797464b2e1c3f353b18a1aa3087f773e3e7b25f6d0eaa92ef50720c8cdc449abbdd0f53ea1c3b9d9f62123c66f64d4f4c87ceb4f7cf730a97527b377c776b66fcf7e6d59d89b75139716d97e71f54444e4e271d1ff64eeab37d401e0f9075fe3bbedbbd8b6750d6f3c399aa11ffe01c035a31ae3b05b7970db29c2c735a1f503cd39b1e509005a3c72a5b39d5f92b3e7bd272725b26fd3bbfc91eefad59733875f643f4d78a4cef96f5ceffff409fccc46160e0ce7ae492ff0f1fc4f78ebe527b8363cd4e5d88bd3fbded7386d0ea17d44173a34f4c39619e35cf772af3000fa4f7a9d99936e0620acd7cb2ef729af733777e7bcc1fbb2b133703318f878f0bb180c265e78b085735d71fbb3a8d8f32aebbe5ccc867ffa01196fdd4664a7486e7b3b830f3e1d7ec96ecbb7ee309e6a99fb582e6a9b211dee267ecf21badc919d74470e6fc08f19351912e25d60fbb5ae798105a34319ddf3ecfd2b3d465173cc425eb8a6e024e542e21eba641135d74ca45d44272223aee6d18ff73ad799dc4399166e67c296549eef5ed3a53a45b963d13c02bf7e90f61d2389ecd89e07bf0ee4a345d9d3191df674a6ded693a8ce9de9d4e90eee786a7e89b717d6eb153eba3b8431d746121919456444173ef9edfc8dd3458dd18c99a399d53b8aae3dafe3c55fae71a93f002f0f89e09a884e85dce89dedbe275bb3bfca608685e6bf7f67c9e4cdb47fa24fae65d5da3f8be9cf67f829d95a68fbc5d5734551318b8848d931847578d8b1fdab874a5579f6ecd9b46bd78eeeddbb17dcf8d99b851d8efcf36bf3ae2bacac3deb34af3d3c86b717ade4cfe309b8fb5968d6aa1db73df90ee3a36a907c6c26bea1d9df5afe70268356d66ff0aada178065a7d3e81d943d277acf7bf7d3e79177f827d58b9ef73c4fcabc316c48482f74fb39dfff38b60503ff7c8e83df5c9f2bb6d8ed9ff3c893afb262cb764e24a4e35bb516ed3b5fc7ea456fba147b71fbe0c62effe387ed7b8949ca2428ac1943a77ec28b77654fcbb2679ee0999177f2c6e20d24e24fe701a3f9e0ed47a9ee662c76df17340e39e5acf3e2e5557978cf69829a3dcde97de7bf2d2d6e7f16157bded84ada1757fa969696c68c19331831624491fd2fadd9b367f3c0030f909292522eed8bfcdb2c1ad486154396f1e17561951d8a48918a3bb711b91895e6bc67c78e1d44474797dbb9524ee1bd5f2cdfa4e3dfa2afc59be0558778375c0f94ba5428e910b938581337d3bdf783a4fa7762d3972f9cbf7748e422f55f39b7917f974b21e9a8901bc92f759fc7a45676082222972477ff48366d8e2ebea08888fcab5df4f7748888888888c8a54d49878888888888942b251d222222222252ae9474888888888848b952d2212222222222e54a49878888888888942b251d222222222252ae9474888888888848b952d2212222222222e54a49878888888888942b73650720101f1f4f727272ae65d5ab57c7cdcdad92221211111111293b4a3a2a517a7a3a070e1c60d6ac596cdebc19a331fbc2534646062fbcf0022d5ab4a0418306951ca588888888c885d1f4aa4ab474e952860e1d4a8b162d888e8e66f7eeddecdebd9b75ebd6b178f162eebfff7efefcf3cfca0e5344444444e482e84a4725d9ba752bcb962d63d9b265d4ac5933d7ba5ab56af1c9279fb07cf97266cc98c1c48913090b0baba44845444444442e8cae74549271e3c6317dfaf47c09474e5dba74a15ab56aac58b1a202231311111111295b4a3a2ac1a64d9b68debc3975ebd62db29ca7a7271d3a74e0d0a143c4c4c4544c702222222222654c494725983f7f3e37df7c3356ab95f5ebd7337dfa7476eedc09407272324b962c61faf4e99c3871822bafbc92bffffe9bc3870f5772d42222222222a5a37b3a2ad0a4499300888e8ee69e7beee1e8d1a34c9a3489e8e868b66cd9c2f2e5cb898e8e66f2e4c91c387080d4d454a64d9b86afaf6f25472e22222222527a4a3a2ac873cf3dc79e3d7b00888b8b03c0cdcd0d7f7f7f0082838301f0f6f6c6dbdb3bd7b273f52d160b1d3b7664f0e0c11519ba88888888c80551d25101e6cc99c3cf3fffccf4e9d301f8f9e79fa951a306168b85e79e7b8ea14387d2ae5d3b005ab56ac5cc9933397af4283d7bf674b611181848dbb66dd9b66d1bd5ab57a74b972e95d21711111111919252d25101a2a3a3090a0aa265cb9600d4af5f1f0f0f0fcc6633e1e1e18487873bcb7a7979d1a953a75cf5fbf6ed4bbd7af5a85fbf3e2b56ace08d37dea076edda346cd8b042fb2122222222521aba91bc027df9e5970054a95205b3d9f57c2f323292060d1a60369ba959b326870f1f263131b1bcc214111111112953bad251019e78e209060c1840747434010101f9ae6414c7cbcb0b80b7de7a8bb4b4b4f2085144444444a4dc28e9a800356ad4e0b3cf3e63e7ce9d3cf5d453bcf2ca2b5c7ef9e5256ae3934f3e71fefad5134f3c51e2fa22222222229545494705090909213838983367cef0d5575f11121242f5ead55daabb72e54aa64c99c23ffffc03643f34d0cdcdad3cc315111111112933baa7a3025d71c515dc7df7ddfcf8e38fd8ed7697eb65666692919181afaf2fbebebe4a3844444444e492a2a4e312e0e6e686afaf2f274e9ca8ec5044444444444a4c49c725a061c386dc73cf3d5c7ffdf5951d8a88888888488929e9b804787a7a121010808f8f0f070e1ca8ec7044444444444a4449c725a056ad5a74ead4894e9d3af1f4d34f3b6f281711111111b91428e9a8407171711c387080ba75ebe6ba19fccc99339c3a752a5ff9d4d45476efdecde9d3a769d0a001bd7bf7c6cfcf8fd75f7f9db8b8b88a0c5d44444444a4d4947454a0bffffe9bf5ebd7d3ab572ffcfcfc9ccb7ffbed37d6af5f4f6c6c6caef2bb77efe695575e61d7ae5d646666d2b2654bfaf7efcfc9932779f3cd372b3a7c11111111915251d251813efdf453dab46943bd7af5f0f0f0702efff6db6ff9f9e79f3972e448aef27bf7ee65cf9e3dc4c4c4909191818787078d1a35a263c78ebcfdf6db151dbe8888888848a9e8e18015e4f5d75f67fffefd0c1c3890d0d050e7f2a4a424b66ddb86afaf2f1919191c3c78d0b92ee7bd1bc78e1dc3dddd9de4e4e48a0c5b44444444e48229e9a82073e7cee5a69b6ea25ab56af8f8f80070e0c0017ef8e107befffe7bbcbdbdf9dffffec79e3d7b9c75962c59424c4c0cd1d1d124252539976fd9b285fbeebbafc2fb2022222222521a4a3a2a90d168243e3e9ecd9b3703b06fdf3eb66cd942f7eedde9d2a50bcf3efb6caef253a64c0160f9f2e5ac59b3867efdfaf1f7df7f53a3460deebdf7de0a8f5f44444444a434947454a0afbefa0a93c9e47cd6c67befbdc795575ec9942953080b0bc3dfdf3f57f96bafbd1680962d5b72f8f061c68d1bc795575ec9e8d1a3090a0aaaf0f845444444444a4349470579fffdf7d9b3670f93264d722e5bb87021d5ab57272c2c0c389f64e4d5bc79739a376f8ebfbf7faef222222222229702251d15e4f2cb2fa771e3c6b46edddab9ac79f3e6256ae3aaabae2aebb04444444444ca9d928e0ae4e9e959e24443fe7de2f7ad60daf36fb3e6fb5dc42466e06ba945f855dd58f4cef40a8bc162b100101313e352f9bbefbe1b8077df7db7dc622988abf11524e99fd7a91ffe14008d6eff8aef5eee50eab6722a6e5f9474df8a8888fc1728e910a940f1bfcee17f5d27934415fadf3b9e88cb6a9074ec00ab3e9b07545cd2e112471618b2ff89288f64e39c77de79c7f9f73df7dc936f5969fdf4d43c00dc8d060e7df628d697d6e16eb8e066cb755f888888fc5be9e180221568f61dd349ccb2d367f606de983a8e81370f60f8d8c92cd9f88bb34c56c6df3c3efc069ad40d25b46e136e18fe387f676439d75b2c965c57070a7bbff4b9915cdea016b59bb4e5d96ffec9b5beb8baf326f4a54ecdd042cbd9ada77865c210da34a94bf5eaa1b4beba172f7fbed7b97ef7878fd2b17513aa875423ac4153a27a0d28749fdc74d34dce57de65aeee93bc1cb66426ad3c8abbf765ccb9be36d694dd3cbd3f0e80cffab6c262b130eb48f6336f528ebf87c562a165ef852e6d2befbe488fddc480c81684d66ec2b067bece174bdef2222222ff454a3a442ad0fb47b29fb7f2ccb5797e0cc070fea2e3a25b6f64d697dfd370c814a6dede90efbf9cc58db72e2af1b65e39da9007efbf81b4b843cc1a77bf7379ceab08efbcf34e815715de4a69cf0b2f4e2db4eda5c37bf2ecbc95443cb988037ffdcaf37db3787e6457defd27bb7fb73c3a877fac11bc3a6b16cf4d1e43bb3aa612c79f5349f749ecce29fc999e49adeb9ee6aaa9b700f0e563d93f55ddf5b9ec0468eeb33b00f8e5c5f701e8fbc235a5dad6070347b0e1d793b41efa00ffcb782bdffaa0a020fdda9c8888fce729e910a9400e47f67f8b9ae5f3f4f72701f860ca3ddc3de503004e7eff4c89b735efa5f10c19350300eb99adcee5455d513867ee2b131878dba842db9ebaee18008befef43c3fa8db9e3c59d381c36967c790480ab823dc948fc8ecfbe5cc19e4349440e7fbdc4f1e754d27db2fab1d500741b529544633f9a78b971f287499cb0da09683c914e011efcf3cda3a4db3299baf410ee7e1d98d234a854db9ab93fe16cf9bbb9e7b10ff2adffedb7dff8edb7df4ada651111917f15251d2215e8ae305f001e5b7524cf1a9bf32fe7350103e038f7e6fc47d564c84e59d2ed60b31e2d745b753d4c188c9e00381cb642cb15a4b157d1b77b9d4b9aa67eb18a0d1b36b061c326366fdeccac1beb00306beb3a5e7b72048d6b78b3f3f3598ce8d7bf44dbcfabb87d925356fa5f4cd9190bc03b3744121efe3f7e4bcbc4668d65d296e380892746362133f5571efc6612db93ad341ef6346643c9b7959301c0903f9decd7af1ffdfaf52bb6be8888c8bf99920e910a34e28387f1351b597a7717c63efd3a4b3efb940f66bdc0c02e2d9d659eea561380bb9e7e8f779fbe13809add9e72aebfcacf1d8027167ccd874fdd55aa386ab9672715333e5ecc57cb7f2a71fd677ad40260e6e3efb06df75e76466f62ce8b1319b3f02f006e7de81de24d16aee810c115f57cb1659e2e559ce714b74f723aba6a22495976eadefc3473e7ce65eedcb9bcf766f6f4b2ad539700d0f8ee69b8190c2c19f111068389c747352bd5b600c6360dc82effcc7bbcf74cfef1d8bc79339b376f2e517f454444fe6d9474b8c06030e47bb96ad0a0410c1a34285f5be7c4ef5d44eff64da9e261c6ddcb8f7a97b5e5c11c37fdbae2b3fbaf23c8db8d8e37f5273a29b34475a5620535bf879f56cd6150b766ac9ffb12a3ee1dcdb4990bb1d7efed2c73e37b2b9938b80b7fce7d92a7e6fd4597c11359f9de8dcef5afbd7a2f7582bcf8e8d187f9d6785ba9e278f3feeb09f1f560faf8518c9e30a7c4f57bbfb39a6923fb12706c350f8fb98f879f7a8d1db13ef4b932fb8669cf93db99f9f423dc7bef583e3d1accc8174b7e4f4a4ec5ed939ce63df5330003270fa657af5ef4ead58b3e0326d3d6d79d84032fb02dd98abbdf554c6e1a883dcb4e40a34788f2772fd5b600ee5cf436514d43f8f9bd17d8641b7241fd141111f9b732847578d8b1fdab874a5579f6ecd9b46bd78eeeddbb97715817977349427070b073596c6cec05b5e5383bb97f40481596c4a43274da1b74abedc9fe6d1bf92b7c2a9fdcd9c8e5367dcd26926d7632ed0ee71491ffbab4b43466cc98c1881123caa5fdd9b367f3c0030f909292522eed8b8848e5f8af9cdbc8bf4b69ce7b76ecd841747474b99d2be514defb455de92889d8d858e7eb9c839fdd4eed1a55b15882a9e2ed47d3f6d7317f6fbc737d715746be894b07e0e6feb770ebedc398f6fa47b9120e57da4fb6d90170339edf8edd7a826746f4a18ec517b3d993da975dcdb405bb2e7c2788888888889490928e12e8d6ad9bf3758e5f837eacd87e889898d3c41e5c47dc8e558ce8fe80cb6d4e691f0240ef6655a9d9e40aee183f9d5f734c912aaefd050b1614f8f7c20157f2d83bcbe8fad20ae2134ff2e62d993c7eeb15cc3c78a6547d1711111111292d3d91bc04b2b2f23f8ccc23389045d3c7b2f3c01152ad366c384839391fc8ffd399057978e36e4267becad2551bd8b2299a79af6ee7ab9531c4fd3ac3a5f6070d1ac42db7dce2fcfb9c092bb2ef0b99372c8a79c300ec381c0e3e5e7288b10fb54444444444a4a228e928818d1b37e65bd6bf4d4f569c4e63ca9c4f89acedcfa8ef3613976975b9cd546355864c788621132023fe473c833a90f0fbdbc08c0b6affdc44abe737fc488f400fe77237bf7a2ec72622222222521694745ca05f92b3a742252725b26fd362fe48cf7f35a42835eab563e8d0feb46d528b84fd5f0250a5da800b6effd51bea30f0d3bf78fec1d7f01dd503b7b453fcb8f64b76b57c95efa7b62e518c22222222221742f7745ca06fde1845bd202f5e9ff8106bce7427cadfa3f84a39dc1915cafa8f5e61c4d0213cf8e20a9a5f7d237337be76c1eddfbc209a19e36f21f0c8d7dc377408a31e798e6da77c191059ad44f189888888885c285de970c1b99fb72d48cbe1aff2d7f057cf2f786d789175f3be9f39ef8b22b75d5cfb85c5673407337ec67cc6cf28b279111111119172a72b1d222222222252ae9474888888888848b9d2f42a910af4c30f3fb06b971ed228978e56ad5ad1a14387ca0e4344442e714a3a442ac8b984a35dbb76951d8a88cba2a3a30194788888c80551d2215241ce251cddbb77afec50445cd6b1634766cc98a1a44344442e88eee910111111119172a5a4434444444444ca95920e111111111129574a3a4444444444a45c29e910111111119172a55fafaa406969699c3c19c31f7f9c2025d54166a6178967b2b0d90cd81d06d2d2acd8ed36b067e1ee9646b56aee54abe6439b368da852a50a66b3864b444444442e3d3a8bad0076bb9d53a7e24848482126269dcc2c1fdc3ccc78f97811186cc4603080c14866661656ab0dab358ba433492425a7939a96414acaef346e5c1d8bc59f8000bfcaee8e88888888488928e9286776bb9df4f40c4e9e8a273636958404135e3efe787b79e2e3e3819fbf0766b301b3c988ddee202ddd466a5a16c78e7a72ec681ca74f9fe1d8b123b8bb1b30181cf8fa56c164325576b744444444445ca6a4a39ca5a565f0d34fbf929ce283d11c4c58fd406a857ae2e36da48aa7018301e70bc0e170c3e180164d7c888dafc68953e944471fe1dbeffe66efbe58aee99e468306f5f0f070afdc8e8988888888b8484947394a4949233e3e998444033e7e55f00bf0a1564d0ffc7c0cb899cf271a05713343a09f1137930799adabb3db98416a72023ffef81781814154ad1a809b9b5bc5754644444444a494f4eb55e5283ddd4a4a4a26195637bcaa781210e0455080194f0f236e66439e2b1cd92fc85e66348297a791007f3375ebf851a37a55dc3d7c38782891f8f824d2d2d22aaf63222222222225a02b1de5c86a35926135e3e35f158bc587aa41eeb8b965271776876b6d984d0682030c346a62c1683270f8e049fe3e781cb3d9819f9f6e2a17111111918b9f928e72949e914546868d2a3e5eb899b32f2a6566828bf90670f6ea8703bc3c4df8fa79e01fe04fdce944e283bdcb25661111111191b2a6a4a31cd96c76b26c0ecc6e660c46030e07d86ca5483a0093c984bbbb1b1e9e9ea467c49091612d97984544444444ca9a928e7274ee3e0d93c980dd6e202b0b328da54b3aec0e301a0d787abae17038b0d9ece512b388888888485953d2519e1c0e1c761be969e9a467b86132999c094751bf5c95a7096c36b066da494fcf24e94c32d52c66dcddf5cb5522222222726950d2518e4c2607066c2425a61018e085a7bb992c63f6bd1d254a3aec909e96496a4a3aa94967a852c7136f6fcf728c5c44444444a4ec28e928476e6e6032db8839994848881fdede1e186c6020c74fe51652d77076ddb9295ac949e99c4938c39933a7090cac4f40806fc5744244444444e40229e9284741413e6466669110ff3bc78f7963b33b080d0d04ceff646ecee7739c93fbf91d0e32ad59fcb6ef30a74e1da756ad2cead6ad8ec5125c813d1111111111293d3d1cb01c7978b8e1e3e341b5100f529292898b4dc496958501074603d92f2398f2bc8c469ceb1d361b71a7934848388dc39e4e830635f0f7f7c5c3c3a3b2bb2722222222e212251de5c86c3653a58a1761613e24272713732a81acac2c0c46072613984c603681d99ce795639dc36127e6d41992cfc4613266d0b8712d7c7dab6036eb2295888888885c1a947494336f6f4f3a74684d7090898cf438f6fd72045b66266e668a7dd9b23249883fc3b61f7f2524c444ab56d569d0a03e9e9e9e185cbd135d44444444a49229e928673fcc10890000200049444154068301b3d94c8d1abe04f87b70fcd869d2d232b0db6db9a651e57d998c90949446dce933645a13b158fca95ebd2a6e6efaa95c11111111b9b428e9a80046a391ead5fc080af224262681f4b40c6c59b6f3f76fe47b3930191d2427a7131f9f0ca452b5aa1f164b10269349573944444444e492a2a4a38284d5ae41edda21184822e6540267125370772b785a55f6ed1a0e8e1d3dcdb123313468e0436868558282022bbb1b222222222225a6bb912b88d96cc6cbcb9daa553d4849492325391dc3d9695479d91d909e61252d2505ab3583d0d0aaf8f878ebe67111111111b924e92cb682188d463c3dcd04057992919e457a7a2626e3b90774e49e2e657438c8ccccc26ab562b767111cec8f87873b46a32e4c89888888c8a547494705727777a7468daa1c3c9485d59a859b19c8f120c073ec36b05ab3b0d9333199ec040707e2eeae1bc845444444e4d2a4a4a302b9b999080cacc2ae5d47494bcb04873d3be1389b759ccb3dec763ba74ea5723a361eb3398b2a55aa6032992a2d6e11111111910ba1a4a30299cd2602027c309932494e4ae78f3facd86c59d86c76ec763b76bb0d0087c3417c7c2a1e1e560202aae0e9e9a1a9552222222272c952d251813c3cdca9512384ead50d1c3e9cc0c18347888f8f272d2d8dd4d434d2d2d270381cd8ed76d2d353e9dcb915b56a85e84a87888888885cd294745430a3d188d99c415898376ddb36c0cdcd83f4742b696919242525939a9a4e62e21956aefc1a8321159b2d13b3d9ac677388888888c8254b494725c8cab262369b080cf4c1cf2f00ab358bb4b40c1213bd494848c26eb7e1706462b3d9b0db6d4a3844444444e492a6a4a382391c0e3232acb8b9b961349af0f4f4c66cb66134ba91916107d2b15a1d6465d9cfdeef61abec9045444444442e88928e0a643018301a8dd8ed368e1d3bc5891327f1f4f4c26acd2223c34a6c6c3ca9a919a4a4a402363c3c3cf0f6f6c6e170e86a87888888885cb29474543083c140ddba75f1f0f0e4f4e9d3fcf3cf3f242727919c9cc2d1a3c709080824202090f0f056346c589f909090ca0e5944444444e48228e9a8048d1a35c2dbdb1b9b2d8b9d3b7770ead429e2e2e23870e000ad5ab5222cac1a11115713161646484888ae7288888888c8254d49472508090921242484366dda3070e0c0ca0e4744444444a45ce98973222222222252ae9474888888888848b952d2212222222222e54a49878888888888942b251d4530180cf97e39aaa06565d97e4e83060d62d0a0418596cfbbbeace31311111111290bfaf5aa8bd8c2850b2f68bd88888888c8c540573a2ed0f6b7efa7796d0b66a309ef80105a5fddc3b9eee067b753bb46552c9660aa78fbd1b4fd75ccdf1b9faf8dcf1e1bf07ff6ee3b4eaaea60e3f8ef4e9fad2ccb2e65a9a252142c2862140bb296c492041530d1682cc4e48dc616935863892d126b221a8d46a318a3c62812c560c306028a8a346902cbf63af5b6f78f650790b6e00e3ba3cff7e3c8cc2de79eb3337b769f3df7dc4b496e905efb1ecb8cca586af98e462dbebafeabcfdb5eff6178373c1e1f2fd5c501a89a73018661b0cfcf67ed7ac34544444444da49a1e36bfadec5f7b12a3986bf3efe38f7defc6bbe3360e3e051c1c0714c9fb78aeaea5a6a56fe8fbaf9af30a9fcd22dcaf863cb287ef7b383a9f86c063f3ae12fbb5c97a79e7a6ab3e76dafcf7ff427b8aecd95d7ce0560c665d3300c831b6e18b1cbc71211111111692f858e5db0e988c2912561e2f56ff2e43f5f60fef226c6fef26fa975c1e2229ebee5224efeee719c74c66fb17189543eb94579cfddfe2b2ebee55f00d47d76db2ed76bd3f91d9bcef72839f00ec695e4b0f46fe753175bc725ef5752b8e7ef18d72dbccbc71211111111692f858eed18186e1db598d36202906c9e0d80373430b5cde30be7f2c81f7fc5d0b25c3e7cea4e268edd787ad569071ccf8df73ec2fea75ec06f7ef31bbaf9bcb84e728be3a47fdab787dbef1d8319fd9c536e3c8d6ad3e6d8fb7e96f6a38a888888888042c776dd3cb60c80938e3d93eb6fb89eb38e3b1980dee537a7b639e9c2bba9f59572c8e8318cdab300dbac4eadfb74435869696e64e19b0fb1346e6df538e37e730ff7fcf63400baeef3ebaf55e7bec1d6a074d35f1fe75fff7e3fb5bcffb8471992e367d62defe20befc90363cabed6714444444444da4ba1633b4e7de64daefac90904964ce3c6eb6f64da920027fce42adef8e7b8d436a18ad9dcf6dbffe3c73f3e877fac2ee1923f4f4fad9b76df2f18d035ccbdbfb982194de51c5518dcea712e09becd8d7ff980ee43c7f2c4f40bbf569dfffedb71f4280871cdf96771f6a4fb52cb3dbe621ebb78280003273e48914f97d51511111191dd4397ccdd0e6fb01f373dfa32376d679b7fcf9cb3cd75c3cebb8be5e7ddb571c1dde76db6de75ddd4f3536fd972ff4dd7b7e735c091d74da5e2ba2dcb9a35eb2dde5bda8461f8b8e1d651dbacb388888888484753e8f896183dfa48fc39dd187ffdcb9c5ea209e422222222b2fb28747c4b6c6d5444444444446477d09c0e1111111111492b850e1111111111492b850e1111111111492b6f61efc3ae9f74c661bbb4f3dcb973292b2b63c5d4d399f4eac1f47aef44fdab7f33e2dfbe87fe94f7de7b8f830e3aa883bf65367ef60f3df4504cd3dce9ef97810307ee7863910c6159565abf9744328dfa6ac946bbd257af5fbf9eb56bd7ee96fe7dca53ef62f419f56b77de8b57ec5a0153a63072e4488cd9bfe1b6d8431d5c3d915df79fab863079f264264d9a9496f2a74c99c2a5975e4a2412d9a97d468e1c497979795aea24920eb1582caddf4b2299467db564a35de9abe7cf9fcfecd9b3774bff7ee0497774cce9550a1c9249ae0c9fdfd95510111111914d7448e8d02f799249148245444444328b463ae41b47215844444424b374c8cd01af0c9fafe0b1131cc726d2d048736d1db1c66aec5814c3b1717d7efcc100c1825c8a4a7b12ee520a189d5dddac735bec21fed3d9951011111191940e091d0a1cede3d816eb977e4aae6172e8f05e8cfaee2086ee399a1eddf20905bdc41216d5753196aca8e3ed394b99f5d15b98be5c4a061e8861e8eac6edd53ad231abb3ab21222222221b68a4633769aaa9245eb182cbcf3c94938f194c51610800d372302d0bc330280a0628ed9acfb0bd4bf9e1b183698a384c7f6b0977fc753ae15e7b13eed2b3935b911d34d221222222925934d2b11b542d9e4df7bc308fde399ebdfa15134d24696a31b16c1bdbb2715c87a0df8fe971886082dbba9fd763f0c3b1831939ac2fbfba712a156b1ae8d27b48e736260b68a44344444424b3e8ea556956bdfc638a8301eebff6147a74cba3ba2e425d5d0b6b2baaa8acaa636d653d8dcd716cc72561da98499b64d22291b088c44caa6a9bc9cf31b8fbdaf11413a369dde2ce6e52c6530816111111c92c1ae948a368ed1a92f551aebaea6472c37ed6aeafa7baa686682c86edd86078701c0fe15088dc509060308065dbb8ae8be3ba98a60d403c6e12f0fbf8eda4ef72e1758f13eed21d7f4e974e6e5de6d248878888884866d148471a552cf98c7163f6273fcfc79c05cb98fbf1a7ac58bd96eaba28f5cd2ef54d06d58d0ec1502e966db362f53aa2b104f1844955753d4dcd112ccb25693a34b524e85614e084230ee1cb4fdeeeeca66534856011111191cca2918e34a95fb390b2e25e84822e0b16ada4b6661d5e5f108f2f07c3e3c5712d2c3b4159692165a58558a68de3b8d4d637525dd3404e3844cfeea5d8b68365d998968b633b0cead795fc400191ea15e4960ce8ec6666248d748888888864168d74a449a46a3d2545797cb4e84b967eb19ae6168bc65880fa669b9afa084d2d7106f52f65f4417b9097132037374cffbe3de9515acca03dfbd1af4f191806a6ed60592e9669134fd8388ec5b0bdf6a66ae5c2ce6e62c6520816111111c92cba23791a588908ddf20aa86d68e4e537e6b26c45058d311fb5f5516aeb5ba8aa69263f27c8a8fdfbe1f77b710d178f07705dbc5e0f7ebfaf756e87e3b64e2a4f5ad80e44e3169168923e3d0a71e3496c33d6d94dcd480ac1222222229945231d6910ad5b47732449df9e5de9dd2dc4478baa59bd3e426d438cdafa28f54d513e5bba9ee55fd691971320271420271cc0e7f3e0f518d0fa1f2ee0382e15953544a2713e5bb41a80825c3f5df2ba106faaecd476662a856011111191cca2391d69108f34b0679f1e8c1852c6c87dcba8aaade3cbf555ac5e5f8dc717020caa6aa3dcf5e85b5cfad3d1f4ee914f3412a7a45b11aeeb629806ae0bb6ede0f5780904825454363267fe67e41574c73502742d2ca4b6a19adce2fe9ddddc8ca3391d222222229945231d69602713f42c2dc6b46c0c8fc1e03dfb70d23107d13527c1ca95cba9a98fd11c49b0685915bfbcfe394ebdf061feeffa7f128dc5f1fb7c808b8b8be3b8244d8b6020ccdc4fd790b0e0dd798b5957dd485d63144ba7576d9542b08888884866d19c8e34303c06b6656118e0ba904898b8aec1a4b34e63ccc801acf86211953511ea9b62545447585591e093a54dccfb74153e9f07db71b14c87a469e33806cfbf3a9f07fefe3c5fac5cc3b1471c88cfeb61c5ba9ad673b0640b0ac1222222229945231d69e00b8689c6a2188617d775715d1780ba864696ae5847d2f1d31289d3d412a7399220164f505ddbccc2a595b88e8199b4312d1bafc7c3aa75f53c33ed5df20a8b292ceec3f3af7dc41b7316934c26f0f9839ddcd2cca4102c222222925934d291063985a5d43536a546225c0cf2f27299f1c607bcf1de5202e1ae189b8c52b880edb854d54589272c92a68369397cb6ac92c79eff90bafa0602561523f7edcda9c71ec021c306921b7209e675ed94f6653a856011111191cca2918e34081576675d6d2549d3c5eff352dfd0c8df9f7e8937e7579353dc1f5c7bb3ed5d20180af0ea3b5fb06c65155e8f87aada080b16ade3e345ab08f8bd4422cde487030c1d58c69081bdf1102554d0a353da97e9148245444444328b463ad2c0e3f513756c2a6a5a303c3e5e7bf35d9e7a6e26eb6a12f87dfe8ddb19065eaf8780cf4b6e38c017abeb79f5edc5ac59dfc8c3cf7cc0df9e7b9fba9a6a860c1a4451f73da96f8e134f587cb278153985b9f842f99dd8cacca5102c22222292593ae492b95786cf57f0f88ae27efbf0fe470b28ca1fc9ea1a9b82a2021c6cc047c0efc3eff3e2f779f07a3d78369c6b55901b64eab4053cf1e27caaeb22b8ae4338b70b8585f934464a79e5bd65cc5e58c3f22f16d07fc4a8ce6d6006bb2df610ffe9ec4a88888888488aeed39126e12ebda85afe318b5755d3b7771fe2c92409cbc0f0040805bca9e0e1f37af0780c0cc0712169d960ba9414e5104fda244d9b65ab2ac90d07a96f8eb362cd32ca7afac9ebbe5767373163e93e1d222222229945231d69d47bd8517c34773a3d4a06e10be6d3bd340c80ebba780c03df86d0e1f5b49ee5e6b82e966d635a0e966961bbe0315a2799d735c68925a030544daf7d7f886174c89971df481ae910111111c92c1ae94823af3f4cb74187b0eae37708e6f4c1ebf1d0b5304c30e0c3eb691de1683bb5caddf07fc771b11d17db76b06c8778c2a4ba2186e57809384be877e0119a40be031ae910111111c92cba7a559a858bcae8356c143e770d5e6f10c3e3271cf2d3a5204c49d75c7a94e453d6bd80dedd0be8555a408f6ef9742bcaa5202f4428e0c7c58f6d3978929fd37fffef505836acb39b94f1148245444444328b463a76839ce2bef84279d42f798ba05144af92c1f428ee82eb9af87d000e86c7c0755c12a68d276691347d244d93baeae5c462b5f439e87be416f7efe49664078d748888888864168d74ec2681dcae94ee7f324de1ae7cf8e9bbcc9efb269595eb88451324139088bb2412108f995456ace6934fdf62f117efe374e9469f51131538768242b08888884866d148c76e64181e0aca86e1f6da8796961a3eac5c83b3f8137efec343c8cfcfe51fcffc9765cd214205a5e40c389c5ef9a5787c81ceae76d6d148878888884866d1484727300c0fc1fc528afa1e48b8d7010cdeb307878ce88f695bf41c7e22c5030f235cd45b81631729048b88888864168d74a499ebd8604669bb3e1500869764dd4a0eec1bc05796a077ef5e141717f2bd630e62e1ea8f595fef52e3292310cc03c368ddd775c1f06004f300a3935a931d34d2212222229259749f8e348bd77fc9a4d161f6dab31789840580d7e763c9a21c0e3c604f7af5ea41341aa3a6a6861f9e7c343fc4e5f5d7dfa3bab6927df7ed86df1f005c727382fc77e687bcb2ba845061cfce6d5486d37d3a44444444328b463ad2ccb12df273a1a8304032d93a42e1f7fb589be361cd9ab54422cdd8b603806118d8b64d24d24261be8fa2421fc1a01fd775c9c90952107630638d0a1d3ba0910e11111191cca2918e34f306c33cfeecff08f96c1cb73574d88e435e38c431a3f7271269c17136860e70a9aea9e7cdf7e631fdf5b9f87cfed41dcceb9aa218c5633ab135d941231d222222229945231d69162ce8491547639b31dae662181e2f56a49a25cf7d846325c1d8743ebf8be5faa05b3991703eee8640022e4689977041e9ee6e42d6d148878888884866d148479a198667eba74375ed0b8cd8edf5f936d048878888884866e9904be62a704826d1259c45444444328beed321df380ac1222222229945231df28da3102c222222925934d221df380ac1222222229925ebae5e35e3a6030148c69a39e50f4bb15cc030b8fdaafd3820d49aa1caaf9eb7cbe57ef9e1327efaefa6cd96ed4c79bbb24f4768ef71cfbb6c3fc6177979faee8ff96bb5ddbad03078e09afdd9c30fbfbae9237ef0fdfe00dcfcf48a7456396d74f52a11111191cc92b5231d81703e1796f90128eadd3b1538beaeb203fab367c0e890b2d2ced8f97a4e7b3502c051c7e7a596e597f46260c0a0a5a6828509979b9f5e91b5810334d2212222229269b2764ec7db1187a37e580cc0f77e504422d2b0d9fa89bf1cceab371ec0a8706b13bb94f565c64d07f2d793f3b6286b5335ae972bcb73b7bacef0fa39e39481fce377fbf3ca0d07f0e4c583f8f1f0706a7ddb6843dbf3b6d7038f1ecc8c9b0ee4ca5ead034b8f5c77002f5fbd370025030732e3a603b9eba010005e5f9049e3f7e65fd71ec0cbd70e67f2f8327af98c2dcafdde297bf1e2ef0fd86a3dcbf6e9c5b41b0fe45f3fef4777dfe6c1a46ad197441de836b00f791bdefde1271401f0f1f4ba2deabea376ef4cdb76179dee272222229259b276a4e3afd35bc82fe9c5f1dd8b39abc4c7a7d3d76eb6fee567eb300c83f3c6e60030e284425c171e7b2dbadd726f7a374edf9103e8ebdf7214e1e8098338e7e042e64f5fc60f6e5ac03d0b0cce3a6d303f28f202f0877f6e1c1df8c33f57a45e57cc6f0460f0a810c1dcaef4f619f84379ec1f32187078eb2fefaf2c4a0270ec997b73eab03cd67cb896bfce89336c5877fe7866d72dea322ed0c23dff59bbc5f29e437a31657c0f5a565773c19455545aee66eb6d33c1036b4dbcbe0093cafc181e1fbf18e0c7b12deefb22b9d5afc9f6dabd336ddb5d34d2212222229259b276a4a3e2935554db2e179fd717c74e72fb2789cdd637ae5bc3db1187b203fb92eff773611f1f91baf5bc1d75b65162ab25afafa0011fbf3b2a678b7593f66e3d9dabfc077bf1fcd5c3f9fdd1391886c131fb0600787d417d6adbd717d4a75ec71a2ba9b75d8af7ea4a51bf6212915a16c45d7ed0cbc729bd7d58669cffb6b4d6eba7fd5b470c6e78a58ae75f6d0d2dc5fd7b6d5197ebffbd9e191f566eb1fcc1893d48d65473dec35f52676fbd8def4f6b0d0a234f28a0a84f6f4a7c06b5abbea4761bdb6fafdd3bd3b6dd45231d2222222299256bef48eeda26777c94e08e83427cf9e1aaadfe82fdd04bcd8c1e5fc80d47ed41a1d7e0cd17ab7758ae6dc6b9794e82db0f1bb0cd6d1e7a64311fc6368e20d889c436b705705d87a9f5363f2b2ee63b4758d42dafe0d9fc022e1ed38dae610f756bd6d3565a7b7f3d5f6dba5b5dbe3ce130b8b888237b56f0d25a6babdb34ac5bcb1ab398b2debd39e9a4d672de9cd6bcc3636eaddd3bd3b6dd45772417111111c92c593bd201f0e9f4d53cf8dfb54c9edeb2d5f5eb3f5bc56ad365df2373b1cd04772d37db55eec257571235025b2cfff386d384261c5fca3ebdc20cea9bcf2963fa70c501c1d436551b4e67fad1415d3962c8c6b92173df4f60180693cafc2c7d2fc117efc428ead71380956f6dacff034b5aeb784d79293f38b635f8542f59d3ae7a03fce6be15ac71bcfcdff983195beaddea36ae6373dfa22486c7cb8f7bf8b092511eaeda7a40694fbbdbdbb6dd45231d2222222299256be774005889169e9955c9a789adff2ddd752c6e7f370ec0ba05ab69ef593e5632cacd1fc5b758fed6d38b79e0dd7a9a0b0bb9e887fdf9e5713d18946bf3e6ca8dbfb0dff65603750987b3bfdf9f2bbe5f925a5ef559eba9561e03fe556551bfba2675f1a9e7576cdcff8da98b796c6e13bd479671dec121e6ccade0a2a91b4fdbda91586323173fb09a46c3cf65170ee2b0a2ad078fcf5fad493daf58b0066b3bc3113b6a777bdbb6bb684e878888884866c9bafb746cef3e145f5db76fbf3c8676f3e2ba2e8f6db8546c7bf79dfbfc42ca9fdf7c1bd7b178f6e5153cfbf2b6cb59307305e3676eb93cd65c45f9d5559b2c69d86a5b5cdbe489e797f1c4f35bacda6a3db7b6bca5b296f1d7d56ebb9240b4be92f2abb79c13b2b563eca8dded6ddbeea2fb74888888886496ac1ee9d8913f9dbf37e7ecede18d995ff06664f74e6696cea3910e11111191cc9275231d3ba333ffda2e9d47231d2222222299e51b3dd221df4e991a8245444444beadb2faea55225ba3102c22222292593a74a443ffeadf4cf857215844444424b3187d46fdda9df7e215bbb4f394295318397224e5e5e51d5c2d91af27168b3179f264264d9a9496f2a74c99c2a5975e4a24b2fdaba27d751f7dbf48b649f7f79248a6515f2dd96857faeaf9f3e7337bf6ecddd2bf1f78d21d1d33d2212222222222b22d0a1d222222222292560a1d222222222292560a1d222222222292560a1d222222222292560a1d22222222229256beceae806c9d6559ac5bb78e4422b1dded0281003d7bf6241008eca69a8988888888ec1c858e0cf5ce3bef909b9b4b2814c275ddad6e6318068d8d8dcc9b378fef7def7b0a1e222222229291747a5506725d97c6c646cacaca0804028442a1ad3e028100656565d4d6d6f2c5175f7476b54544444444b64a231d1dccb66da2d128b66def7219aeeb62db36b5b5b5949696120a8552cb011cc7c1b22c92c964ea58cdcdcd1d527f11111111918ea6d0d181d6ae5dcbe79f7f4e6e6e2e86616cf3b4a8ad69ddd4ddf0dca5b4b494783ccee79f7f4ed7ae5dc9c9c9c1711c5cd7c5b22c4cd3c4e3f190979787c7a3012b11111111c95c0a1d1d68eedcb98c193386bcbcbc1d6cb9e330e2ba2eae0bf5f5f5cc9f3f9f5ebd7ae1f178705d17c33008068398a68965590a1d2222222292d1143a3a90cfe7232f2f8f373f58ccac4faa28282ac01ff0e2f579f17a3df87c1ebcded6876180e3b8d89683653bd8968d6539ad0fd322d218e1a4d1031934a02bc5c5c5f4e9d32735a9bced615916555555388ed3d94d1711111111d926858e0ed436e2f0e1a25aa6cc8cd077603ee15c0f39397ec2e100a1708050c88f3fe0c563185896432261118f27894593c46226b1488268cca16a6594a1fde20ceaef904c26a9acacc4eff76f163a6cdbc6e3f1e0f57a3bb9e52222222222dba6d0d1810cc3002018f25350d47a8a95ebb83876eb88866dda240d03c776300ca3754278d2c6366d1cdbc5b59dd6b91d2e1474c9c1e381783c8e6ddbc4e3f1d49c8e36a6692a708888888848c653e8e8406da1c36378b02c9b64d2c6ebf1e0314ca0f5742abf69e3f5793036bcb62c07d3b448c42d12090b3369619a1696e5104f24686868201008d0bf7f7f82c120406aa4c3344dd6af5fbf5313d645444444447637858e0ed436eae0382e4df55142e1201e0360c3e9509683e9f3e0f1b69e86d57a8a948369da98499b44c224913049266c1a1ba298490bdbf6619a26353535f87cbed46847dbe9556d13cb4544444444329542471a780c0fb5d5cd787c3e8a4bf25a47346c07bfaf7594c3e3310023153a6cab357824931689b8495d6d84869a161cc7c1b61d3c1e0f8140804020900a1badebecd43d3c444444444432954247074a9d5ee5699d245eb1ae8144c2a46b711ee19c007ebfb7357418066cb88f8763b7868864d2261a49505bd3426343149fbb6124c4b1f1fbfd141717130c065337066cbb5ceed7b909a188888888c8eea0d0d181da4287e1f1e0f379f1047c249336f5751162319350c887cfefc5ebd9183a6ccb2199b489c79244a349e231b3b59c0da750391b4635a2d128c9643215344cd3241e8fe3f57a35a74344444444329a4247076a0b1d3e9f9760d88f3fe82710f41108b4860dc363800b8e4b6ba8705c9c0d81c1ebf3120af9f1780c3c5e033761b5860ec7a5a5a58579f3e66dbce29565d1dcdc8cdfef67c080019dd86211111111911d53e8e8409b868e50d88f3f1820146a0d1dfe800f9fcf8bd767b49e5ec5869b03daad370434931689b649e686818d816b806d5be4e5e5d1a3478fd47d40128904f1781cd775f1fbfd9dd65e1111111191f650e848038fd74330e42710f2130af90906fd04825efc7e1f3eafa775c483b6d0d17ae5aae486c0d1bacec57201036cdbc6e7f3d1a54b170cc3c0b22c0cc3c0e3f1609aa6ee462e22222222194fa1231d0c039fbf35640482fed600923acdca931ab1701c07cb74f0782df0787000db6ebd778763bab86c081d9e8d97ca4d2412a949e4966529748888888848c653e8e840ad13c01dba15061939a808ff570287dfefc5b7e1ea552e1b42c78653ab5a2f971b6cbd5747dcc48e5be4e77ab16d07afcf4d5d2237994ca69eb7850e4d2417111111914ca6d0d1815cb7f57e1c870eedc6017b166d08040e8ee3e2b8ad57a1729dd600e1380eb663e3d876ebbd3a1c17c706dbf662dbe0d81e7062d88e032e545755b364e91262b118bd7af5221c0ea726968b888888886432858e0e6459164b962ca1478f1ef80d17c7b05b438363b55eb2ca6e7bedd09a305a9f1b8e8dc776701d1bafe362b80e3636aed1bae9dce57349d62719bae750f2f3f399376f1e814080be7dfbd2ad5bb7ce6eb688888888c876297474a051a346f1c61b6ff0c61b6f609a26d07a0a95dfefe7a0830e22373717dbb6537714dff4b176ed5a56ae5c89cfe7c3300c060c18c0c1071f4c757535ebead66134188473c20402014cd324994c128fc7b12cab935b2d22222222b27d0a1d1d28373797e31a2a66f400002000494441548f3f9ea6a6264cd364e5ca952c5fbe9c010306909f9f4f5e5e1e7ebf7f8b39189148842e5dbad0bf7f7f962f5f4e595919894482ae5dbb120c06393d703a6b2bd6f2d9c2cf701d97be7dfb52585848281452e810111111918ca7d0d1c1bc5e2f454545545757631806a79d761a5eaf97482442757535aeeb120a85300c03dbb6696868201a8dd2a3470f860e1dca88112378efbdf7f07abd2412092ccb22af208f01a101141717934c26f17abd98a6492291d0247211111111c9780a1d69525757475151119665118fc7711c87fcfc7ce2f1388d8d8d9b5d792a2f2f0f8068348acfe7a3a8a88855ab56a52e8b6b9a26a669e2f3b55e3a37994ca62e9bebbaae8287888888886434858e34e9d3a70ffff9cf7f686868a0acac0cafd70b80cfe7c3e7f3a58242db8dfe009a9a9a58b76e1dafbcf20a7becb107aebbf152b95f7d5896856ddb000a1d2222222292d1143ad224272787a38f3e9afffef7bfbcf3ce3b74efde9dd2d25272727208040278bdded47d3762b118151515ac59b386a6a626860f1f8edfef67d5aa55783c9ecd269f6ffabced92b9b5b5b5f87c7a2b454444442433e937d534eadebd3b13264c60c58a152c5ab488cf3fff9c969616128904d07a652b8fc783dfefa7b0b090a14387b2f7de7bd3af5f3faaaaaa98366d1a5555555b946b1846eab9e338949494d0b367cfddd62e11111111919da1d09166c16090c183073368d020128904b1586cb34bddfa7c3e82c120e170986030983ad5aa4f9f3efce8473fa2a9a969bb3700340c83bcbc3c0a0b0b774b7b4444444444769642c76e621806a150885028d4ee7df2f3f3c9cfcf4f63ad4444444444d2cfd3d9151011111111916f36850e1111111111492b850e1111111111492b850e1111111111492b850e111111111149ab6f6ce8300c03c33008772dc76cbb61b76b32b6289c5af775cadddaa3a3d57ff634271d3298dca08f40b88001430fe2f2695f76f8714444444444d2e91b7fc9dc78fd6bfc6a7625f71fd29dca0f2ee67f0df1af55de534f3d957a3e71e2c42d96ed34d70263eb6fc3a4a37fca4bd551cebef13ec6f60db168ce1b2cafdac5fa6fe738bb2c1d658a888888c837ce3776a4a3cdb8921c9e3ef721001e3cf769724ac66db6fe0fc3bbe1f1f878a9aef597f9aa3917601806fbfc7cd656cb9b306142eaf1d5656dacf8322e1f7f2425f92142f9251c39fe7296c5add4fab6919107271d435e20b8cdba4fdb50a7534f9bc88fce3a971bef7d9c7f9cb3576abd935ccfcd934ea15f493e3e5f88be430fe3c6a73edeee719e3ca60f866170e7ea66005ad6de876118941df1d82e972922222222b23ddff8d071eb9d8753b7f03a1ef9f411aeffbc9ec3efbc75b3f5e73ffa135cd7e6ca6be70230e3b2691886c10d378cd8e5633e76d2d1dcf9cfb71874fe2ddc7ac120defae79d1c7dd2635b6c37b9e570fefc97dbb659ce3587940270d2906ef41a34829f5c720b9f379ba9f5534f3f94ab1ffc0fc7fc713af58d95dc3fd1e4ba1f8de09e954ddb3cce09f79d05c094abe600f0d1efef0760e2fd27ee72992222222222dbf38d0f1d7b8cff1b7d821e2e3cf2423cc1be3c3a7e8fcdd6971c7807e34a7258fab7f3a98bade392f72b29dcf3778ceb16dee563feeead0a00fe75ebc55c74ebbf00a878ebaa2db67bfea16b38ebbccbb759ceafdf58c0dffff83bbe3f7614e6ca8ff9fb5dbfe3b09157a6d65f36bd757ec7dfcf3d8aa2c2627ef0fb0f715d9b279e59b5cde3140db981b14521563eff2b62b6c9655397132c1ccdadfb16ef72992222222222dbf38d3f21df13e8c5a33fde93317f5dc4e0f3ff46cfc057739687dbef1dc3b3135ee2941b4fa3dab439fdbe9f7dad637adb9e1840db24f6ade4bb2139dbfff2473ddd38f3b29b39f33248d47f40a8eb281a963c004c4e150f70dbeb1f705cd1c6539dfc0503b6731c2f775c329403ae9dc7cf9efb25b39b93ec7fd59ff0191babbcf3658a888888886cdbb7e237c7c3ee7c883b06bdcfa80b0edbeafafee31e65484e4f66ddf22ebef09e3c30a6ec6b1defceeff6e18c7fafe4b4dfdecb38f71900fa7cf7ce9d2ea7e780919c7df6691c34a8370d8b5e0020b7fbe9a9f5779ddc8ff1ff5ace6d97df4dfe2f8ec31fabe283d75ee0e36177f1deb5fb6fb3dca1174dc67fddd13c71c643188697db2fdff76b972922222222b22ddf8ad01128389ccb2f3f7c9beb3dbe621ebb7828236ff99881131fa4c8f7f52e7f3bfe9fefb1ec67e770df942bf90d851cffd31bf8db03e377ba9c738e2ae37f8fff8987d654617b73d9e7b0ef73c32377a7d69ffad46c26f7f9250f3cfd123f3ffb090205250cd96f243f3ea2fb76cb0d141ec9cdfb76e5d79fd4d275c84d9477d938a2b1ab658a888888886ccb373674b8aedbee75b366bdc57b4b9b300c1f37dc3aea6b1fc3e3efc1350f4fe79a8777be6e9bbae7efffdeee7a8faf984b263fc9259377fe38572ca8e18a0e2e5344444444646bbeb1a163678c1e7d24fe9c6e8cbffe654e2fd9f509e42222222222b225850ef4d77b111111119174fac65f325744444444443a9742878888888888a49542878888888888a49542878888888888a49542878888888888a49542878888888888a49542878888888888a49542878888888888a4956e0ed8c992c924c96412dbb601300c039fcf472814c2e351261411111191eca7d0b11bb5b4b4b078f1626a6a6af0783ce4e4e450585888c7e3c1755d1cc7c1b66d2ccba2bebe9e96961600ba75ebc63efbec43d7ae5d3bb90522222222223b4fa1633758b264092b57ae64c080010c1b360c8fc7434d4d0d6bd6ac61ddba75b4b4b4904824701c079fcf474e4e0ea5a5a50c1c3810bfdf4f6d6d2d3366cc20168b71c821873064c890ce6e928888888848bb2974a4512c16e39d77de61c48811ecbdf7de2c5ab488679f7d9655ab56d1d8d8483299a4a5a585a6a626229108f1783cf5304d139fcfc71e7becc1c8912319356a145eaf97b7df7e9bf9f3e773fae9a7e3f3e9ed1311111191cca7df5ad3241a8df2ce3bef505e5ece975f7ec98b2fbe0840381ca6478f1eb8aecbba75eb686c6ca4b1b13135da914824304d93643249229160d9b265bcf8e28b94959571eeb9e7f29def7c87458b16f1b7bffd8d73cf3d57f33e4444444424e32974a4c9ac59b338f6d86359b16205b367cfe688238ea0b1b191b7df7e9b0f3ffc90e5cb9753595949535313f1789c643289e338b8ae9b7a388e836118388ec3b265cbf8ed6f7fcbaf7ffd6b8e3ffe78e6cc99c3fffef73fcacbcb3bbba92222222222dba5d091066bd7aea557af5e388ec36bafbdc61e7bec415353134f3ef9246fbdf516ab57afa6b9b93975c52aafd78bdfef075aaf5eb5e9a4f2b67f011cc7e1a1871ee2d8638fa54f9f3ecc9d3b97a38e3a2ab5af88888888482652e848832fbffc12afd74b2c1663e5ca95dc72cb2d5896456d6d2d894482dcdc5c4a4a4ae8d6ad1b5dba74a1a0a08070388ccfe7c3ebf5e2ba6e6abe476d6d2d6bd7ae65fdfaf544221162b1188ee3505a5acaa2458b8846a31416167676934544444444b649a1230dbc5e2f9595950c1b368c638f3d96fbefbf9fc6c6c6d4faa6a626a2d12895959584c36142a1107ebf1fafd78b6118d8b64d229120168b118bc588c7e3b8ae0bc089279ec8befbeecbc2850bf17abd9ad32122222222194fa1230d860d1bc682050b686969e1c8238fe499679ee157bffa150b172e4c6d6359169665118944da55a6cfe7e3c73ffe31d75f7f3de17098850b17b2f7de7b130804d2d50c11111111910ea13f93a741281462d4a851bcf4d24b343737535e5eceac59b39832650a63c68c212f2faf5de5783c1efaf6edcb4f7ffa53a64d9bc6dd77df4d8f1e3d78edb5d788c7e38c1e3d9a603098e6d688888888887c3d1ae948937df6d987a6a626a64d9bc6c9279f4c4e4e0e175c7001175c70016bd6ac61debc792c5ebc98b56bd7d2d8d8482291c0e3f1a4e67bf4eddb97a143873274e8508a8a8aa8aeaec6344de6cf9fcf679f7dc619679c41cf9e3d3bbb9922222222223ba4d09146871e7a28914884d75e7b8db163c7525959497e7e3ebd7bf7a677efde3bdcdfb66dbefcf24bde79e71d6cdba6b4b494d75f7f9def7ffffb0c183040f33944444444242b2874a4d9d8b16379e1851778f7dd77f9ce77be43454505aeeb929393434e4e0ea150088fc783e338249349229108f5f5f5ac5fbf9e356bd6b06edd3aba74e9c2a1871eca8b2fbec898316318326488ee462e222222225943bfb9ee06a79c720a53a74ee5e38f3f66f8f0e1ac58b182fafa7a6cdbc6b22c4cd34cdd20301e8fa7ee4e1e8d46292d2de5c8238fe4dffffe37fbedb71f23468cd03c0e11111111c92a3a3f6737993061028b172fe68b2fbea06fdfbef87cbed48dff4cd3c4b2acd44d000381008661505c5c4c7979393367cea47bf7ee1c71c411e4e6e676724b4444444444768e42c76e74d65967f1c1071fb07efd7afaf5eb87611840eb5dc8db1e00a669120e8739f6d863f9e0830fb02c8be38e3b4e37011411111191aca4d0b11b793c1ece3cf34c66ce9c494b4b0b03060cc0719cd48dffa075f2b8cfe7a3bcbc9c254b96b07cf9724e3cf144ba75ebd689351711111111d9750a1dbb59281462e2c489bcf4d24b000c183020756a956559001c79e491545757f3f6db6f73ca29a7505656961a051111111111c9360a1d9da0b0b090534f3d95679f7d169fcf47bf7efd80d6bb940f1f3e1ccbb278e1851738f1c413193870a02e8d2b22222222594dbfcd7692d2d252c68e1dcbcc9933292a2ae2e0830fe6e0830f66c890217cf4d1471c70c001ecb3cf3eba34ae88888888643d858e4ed436993c1289e0f7fbc9cfcf075a2796979696ead2b822222222f28da0d0d1896cdbc6300c4cd324168b118944304d1360b3c9e52222222222d94ce7ee6480b69b03dab64d32994cddaf4344444444e49b40a1a393b9ae8b699a1886910a1d8ee37476b544444444443a8c424727735d3715341cc7219148287488888888c8378a424706304d13dbb6b16d9b4422a1f91c22222222f28da2d09101da6e0c68db36a6696aa44344444444be51143a3a91c7e3c1344d9a9a9a080683388e43341a4d5dc14a44444444e49b4097cced44e17018afd74b7575350d0d0d442211bef8e20b962f5f4e51515167574f44444444a44368a4a3939d72ca293cfae8a3ac5dbb16c33088c5621c78e081f4ead5abb3ab2622222222d221143a3a59515111175e78214b972ea5b1b191a2a222faf4e993ba3bb98888888848b653e8c800a1508861c3867576354444444444d242733a444444444424ad143a444444444424ad143a444444444424ad143a444444444424ad3a3574188681611884bb9663ba1b16ba26638bc2a975bba2feb3a739e990c1e4067d04c2050c187a10974ffbb2e32a9e466ded360c035f20877e430fe5c67f2d4bfbf176d6840913983061c24e95bbad637d9df75a44444444325f465cbd2a5eff1abf9a5dc9fd8774a7f2838bf95f43fc6b9537e9e89ff2527594b36fbc8fb17d432c9af306cbab76b14cd702a383bf4ced28f3a9a79e22b2ee6dcebbeccfdc78d6f7b8e6d4c51d5b87af69ead4a99d5d0511111111c91219717ad5b8921c9e3ef721001e3cf769724ac66db6fe0fc3bbe1f1f878a9ae353854cdb900c330d8e7e7b3b65adeb40ddb9d7ada447e74d6b9dc78efe3fce39cbd52eb9de47a6e9e740afd4af2f1f942f41d7a18373ef5716a7ddb5fde1f9c740c798120004f1ed307c330b8737533002d6befc3300cca8e786c97cbdc9eb163c7525e5e0e8027d03db57ce5b367d1b767374a4a8ac9cd2960f021dfe3c9cfeab738ced46b7f44ef2e6172bb0de4eae757a5d6c7aa5ee3f861bd08e676e3f4ab9eddec981fdd3802c330386b5e35e030383740a8cb1100acf9dfc91886c1e10f2ddeec38ed29b76dfbafd6f1ab5eb8f91cfa6ca5ce2222222292dd322274dc7ae7e1d42dbc8e473e7d84eb3fafe7f03b6fdd6cfdf98ffe04d7b5b9f2dab900ccb86c1a866170c30d23b65ade3587940270d2906ef41a34829f5c720b9f379ba9f5534f3f94ab1ffc0fc7fc713af58d95dc3fd1e4ba1f8de09e954d9b9533b9e570fefc97db0038e1beb3009872d51c003efafdfd004cbcffc45d2e737b4a4a4ae837fc0778bcb95cfeecc651858281e3983e6f15d5d5b5d4acfc1f75f35f6152f9a55bec7ff3ea415cfbbb5389d62ee7ce9f9e9b5afe9713cee0954f2b38f867577368fc4f9bedb3c74fbe0fc007f72e26563d9525319b44e3dbcc6c48f0c91f5b03d43927f5de6a7db7572eb48edc6cfa7cd3d76dae5e3a806bb6526711111111c96e469f51bf76e7bd78c52eed3c65ca14468e1c99fa8bfc4e1f7cc35fbbedc45a0614f6637d8e0727da93d58dcbe915f402e0ba2ee0706a693eff89f4637dcd6b0c2eec8bd9ff37d42fb969abe53a6635ffb8e72e9e7fe575de7e733635499ba2c19750f7f964007a067dac4fda78bddeb63db06d97836f5fc0ec2b86a5eab530623224a7ed34289bf2ae79bc99dc8bc6c6b91c5594c7c79e4368a97f0b9fb1ab656efb6b3263c60cea164f65fcff3d4c4ee94422954f0210f9f22d6ebbe3313e5ab68668d266fe5baf536ffb70ecc466fb2f8b59ec1148e2f1e660185e1cc702a07bd04755d2a6226953ea56e10df64c7d9d5d2742cf702191e2f35870df3286fdbc0f07259ea2cb735f609eba1733e20388473ec3b3c9715adf9fed97fbd5b66dbaac3d75de15b1588cc993273369d2a45d2e637ba64c99c2a5975e4a2412d9a97dbecef78b486748f7f79248a6515f2dd96857faeaf9f3e7337bf6ecddd2bf1f78d21d9931a7c313e8c5a33fde93317f5dc4e0f3ff46cfc05707603cdc7eef189e9df012a7dc781ad5a6cde9f7fd6c9be5453ddd38f3b29b39f33248d47f40a8eb281a963c00b4868eb6137b6e7bfd038e2bda78aa93bf60c066e56c1e0ebcdc71c9500eb8761e3f7bee97cc6e4eb2ff557fc2b7a1b05d2b73dbc68e1d0b630e63fcff3d4cace6b9d4f2d30e389ee9b531ae79f85f1cd1b7905fbcfb167566728bfd0786bc401800d7b5b7586f007c75a2b72797df0c28e4d2a57fe385db8ae879f4355cb27e06175eff301575317a1c72d50e87c6b6566e7beda8ce22222222929d322274001c76e743dc31e87d465d70d856d7f71ff72843727a32eb9677f185f7e4813165db2cabe780919c7df6691c34a8370d8b5e0020b7fbe9a9f5779ddc8ff1ff5ace6d97df4dfe2f8ec31fabe283d75ee0e36177f1deb5fb6fb3dca1174dc67fddd13c71c643188697db2fdff76b97b92d53a74e2556dd3a6725d4f584d4f24f5b5a4f136b696e64e19bff64697ce74603aedcb72b97cdabe6b4dfddcb38b69c7b71ec2ff6c6bde87d2e9f53c5b8bb07b17ff53eac3fe57a00f6bdf2d05d2e17a06fd0c7ea84c54d7f7d9cc1ddf6e2d4ef8fdaa9ba8b8888884876ca88391d008182c3b9fcf2cb39bc20b0d5f51e5f318f5d3c148081131fa4c8b7edbfa69f735419331fff1393ce3e93cbef98ce3e877d9fc7deb83bb5fed4a76633f9928914ad79899f9f7d26bfb8f256e654e573fa11ddb7592640a0f0486edeb72b8ee55034f8f79477d938a2b1ab656ecbc4891339efd287197840397f7ee5afa9e5d3eefb0503ba86b9f7375730a3a99ca30a773c297d53174eff07e5fbf4e0fdfbaee735fbfc2dd6f71d371100db75b9749fae74ffcecf52a7435d7464cf5d2e17e0efbf1d478f8210d79c7f16674fba6fa7ea2d22222222d9ab53473abe7a6efff6d6cd9af516ef2d6dc2307cdc70ebf6ff427ecfdfffbdddf51e5f31974c7e924b26ef7cbdae5850c3d666c07c9d327766bb61e7ddc5f2f3eedab8e0eef3b6bbff575f874bcb79f5d38a8d0b269fb9d9fabc5e17e1ba176db2e4075badd3ce960b70e47553a9b86e8bc53bacb38888888864b78c39bd6a47468f3e127f4e37c65fff32a797843bbb3a2222222222d24e59133af4d76f1111111191ec9431733a4444444444e49b49a1434444444444d24aa1434444444444d24aa1434444444444d24aa1434444444444d24aa1434444444444d24aa1434444444444d22a6beed32192edf6db6f3f66cf9ecde1871fded9551169b7c99327b3df7efb75763544761bf5d5928db2a1af56e8c810b66dd3d2d2826ddb0483217272c21886d1d9d5920e346ad428a0b56310c916fbedb75feab32bf26da0be5ab25136f4d50a1d9dcc711ce6cc99c7faca1aa29138c9a4452412a14b5101e5630fa7a4a4a4b3ab281d68d4a85119df2988887cdba9af16e9780a1d9de8d34f3f67fefccf304d97783c4e4545155555b5acaba8a0aaaa9ec9931fe6b2cbce65e2841f7476554544444444769942472759be7c05efbc3b8f86ba662a2baba9a9ada7baba8686c666eaea1a696a6aa6a1a199cb2fbf8551871cc08001fd3bb9c62222222222bb4657afea046bd756f0c61befb364f10a162ff982952bbf64ddbaf55456d5525d5d4b6d6d1df5f50d2412092a2a6a78f8e1a9388ed3d9d51611111111d9251ae9d88d2ccbe2934f16f2e65b7358b3a682bada069a9a9ba96f68a4b9258a699a040201f2f3f3f0fbfd2493492ccb61d1a2e5d4d737505cdcb5b39b2022222222b2d3143a76934422c1b469aff1f9a295343434d0d21ca5a9b999682c86cfefa3b8b810d77149262de28938f158927832896dd9ccff6811175d741df7dcf37b050f11111111c93a0a1dbb81ebbacc9bb780a5cbbe24168b62db361e8f414e6e0e5e9f0fcb34b16c1bd3b4f0b92e7ec78feb80d7e7c5711c128904efbdff110f3ef80f2eb9e47c42a15067374976d1471f7dc4a2458b3abb1a22ed3678f060f6df7fffceae86c86ea5be5ab24d36f4d50a1dbbc1aa55ab99ffd1229289241ec38bd7ebc5ebf31208f8f1780cec800fc77652c1c3ef4f60064d2ccbc6344d00924993679f7b85c30f3f98d1a37519bf6cd4f643ecfcf3cfefecaa88b4db430f3d0490f13fcc443a8afa6ac946d9d0572b74ec064b962ca7b1b1997822896d59188681dfef271c72b11d3fb665635a166e3c816559d8b685695a44a37112890491480ccbb2a8ad6d60d63bb3153ab2d4a2458b38efbcf34826939d5d1591763bedb4d378e6996732fa07994847525f2dd9281bfa6a858e34731c87458b96914c9a78bd06065eeaea5b686a6cc1b44c4cd3229148924c2689466244a23162b1388ee36cf27081d6d3b4de993507c771f07874e1b16ce4ba2eaeeb76763544da4d9f57f936525f2dd9261b3eaf0a1d69565f5f4f5373945e3d4b193dfa20c065eddaf52c58b098ffcd7c8f783c4e2c16271e4f128dc5482692d876ebe571bffa01725d97751535343535d1a54b974e688d7c5dfa4126d9469f57f936525f2dd9261b3eaf0a1d6956515141696909c71d379a64328ecfe7a7b8b880d34e3b0170f9cf8b33314d0bd3343193adf338b6a7b1b185c6c646858e2c960d1d83481b7d5ee5db4a9f7dc926d9f07955e848b3c6c626bef7dd63008ba6a62602810015151574edda95817bf6c5ebf560db369665a74638b6c7711c5a2291f4575cd2427f3d936ca3cfab7c1ba9af966c930d9f57858e348bc71304837e229138c3870fc7b66df2f2f2a8aeae66bfe14338fdb413b8f7be27304db35d771d775db0cced8f8648e6caa61f64c5c5c5ecbbefbe783c1e5cdb24d47d08675cf85bce1ab347bbf7afadadedb0edbeaafafd4738fb923fd314c8c54d98ec77d623dcfff3c1693b5e47ecff758fdd19b2e5f32ad291d457effa765fa5be7af7c886cfab42479a2593260d0d4d74e992c78a152b28282820180c02e0ba0e23460ca56bd74256ad6a69577986015eaf2691672bd775db152e33c5ebafbf9e7a5eb5f07f5c34710c4bfe348b1bc6f46ad7feed6debae7c4dce3fe36a7efcdfcf18bf67213871167e1e4febf13a6aff6c7aff213b7e90897434f5d55f6fbb4da9afde3db2a1af56e848b364d264e1c2a51c74d03e4c9f3e9dbdf6da8bdebd7b138bc558b162259555755456d6b4fbc3e2f178c8cdcd4973ad259db2a16368b3695d4b868ce12fcf4ce28053efe6f71fdf0a40b2e513ae38e70a3ead4b124fe6f1cb071e63c23e455becbfadedfe7bd629001c75d45140eb0fce1d95d9e6b3a8c5c09250eb318c204386067778bcf6d60bc08a2de1ba9f5fca6bcb9ac9f1baf41c7d3767adba7ea7ea1baf7e93b3c65d4285bf9441637eb9c5d7341b645b7d453a4a367df6d557abafce86fa2a74a491ebba249326cbbe58cd7efb0de2c0030f241a8d128944686a6aa2bea185e79e7b8d783cdeee3203011f8140208db59674caa6217bd8b2132be87f01b1ea11b8ee2d003c317e22c36e798bbb8615d1b2fa79867df72ac67f7aff16fb6f6bbbe31efb3774efcecc993353dbefa8cc36f79c732827ef3f8a238e3982d1479dc04f269493e3313aa45e004f4c3895cf8fb98ff71f190d40e3ba1885bd76aebe8f4cf819ddae98c6d3270e60f90b3fe33f5bf99a66ba6cabaf4847505fadbe3a9bde7fc88efa2a74a4513299a4b925466d6d1d9f7df61985850574e9d285a6a64656adaae01f4f4e67fdfaaa7697e7ba905f904722914863ad259db2fd0759eb6b4f6af91f3faaa5fbc5e3f8c786f5799efacdf6d9d9eddab36d9bb137fc8b8f7f329f99b3dee3bf8f5fcac32f5fc19cc7cfeab07addf66135339e3e34f5baa06728f5bcbdf5bd7751036f1edb17d775e977c28dc0f359f5fe43f69d6220d211d4576f7fbbf66cdb467df5ee910d7db542471a353434d0a5309fe6a616962e5dcd7efbed4d555515894492f7deff94eaeaba0d1ddb8ecb721c9782821c0e1ab117ab56ad628f3dda37414c324bb6ff206b5c3e859c6ea7a6965bb83cfaf22bf40e78b7bacfce6ed79e6d3755b4c7fe8cdb637fbe3ffe7bf4dd732cae7b6687d5cb60dbefd7ced4b7ad8cadfd10cc06d9565f918ea0be5a7d7536bdff901df5d58ce434696a6ae695575e27916866e4c8212c5df6259f7eba84f7defb84a94fcf60e1c2a538ceb62f93ebba1b3f40e1b09f7efd8a1871606fa2917afef297a7f9e49385bbb339d28136edd832f9f1d5ba562e9cc92fc63fc48f26ff3cb5ecb2e1ddb8e2eff352af57cc5bb2d5fdb7b75d57bf97f549bb5ddb6efa78eecd85381b9e372e9b893f77ff0eadd795234bb8f8a17753af1bd74677babe17ee55c8ef5f5d85ebbaac7ae5baac7affbffa5910f9b6e9ecefbb9df9fedcf4b5fa6af5d5994a231d69108fc79931e34de67cb8885e3d0b282d2d60e890de98964d65552debd7d7108dc64926cd4d4247ebf98dad57a7320806bd14e487282808e2f19a24e3cd5454b8d43738d4d4b470cfbd8f32e5815bf178941bb389eb66d71551c68e1d8b6118b88e45a8746f4ebffd657e7c44f7541bcefcc7e32c9c7439df79dc228445d941bfe2b1fd06a6f66fcf76b79e7118df3d6a0c45611fafbefaea0ea59c5ed0000018f549444154cb6c33fbd1abf9e3d5b584030671b7981b1efd7387d6ebb447a7b2f0ff2e63d491d790ef37e879d89d3c7add7e3b55df9f3c710fe74c18c751777567cf237e013c9755ef3f64c75fcf443a9afa6af5d5d9f4fe4376f4d5469f51bf76e7bd78c52eed3c65ca14468e1c4979797907572bbb7df2c9429ef8c70b54acab261a8b515a924f69693e818007c3308846e3343545a8ab6b22168b138f270017c3008fc7c1305cc0de30e93c4a32e902619a5b5c6cdbc1f8fff6ee3c3aaafafefff8f3ce4c76482024a1090404340484262e40942d842054c5da1f8b112a625d222ec50577eb56292a2556c516a43f9422160ef56b5b514401c55ac568a9f66b11912d20b224109240b659eef78f909140b699cc6426c9eb714ecec99dcfbd9f8dcb9df73b773e730d03c330b8ffbe1b9931632a56abb5891e753c151515e4e5e5919b9beb97fa172f5ecc5d77ddc5090f1ed4b872e54aa64d9b467979b95ffa24e20f151515ac5bb78e9c9c9c407745a455e85a2d6d9137d7ea7ffffbdfe4e7e7fb2d563ad5f913e7eb4e873f14151de578d9091c4e270e8783eddbbf63fbb72e62633bd12d368a88082b86e1a473671be1e1615455d52c3ab7575763b7dba9b23ba8ae7651556d60b747e1705870384d6c360809a969c334e18b2fbe61e2c463c4c5750bec80a5d9daca2dd0d6d2ab57af3adb7bf7ee0d504fa4213a5fa523ea28d7ea53afc1bafeb66d6de17c55d2e1072121360cc3c06eb7e3b03b70389d545656535c7c829d3b212ccc4668a895109b05c302a6cbc4e972e17080d369c361b7e2729998d47cdc2a241442a849340cc320223c9cd8d818060eec4d646444a0872b1e6a0b1786d652505050675b73137cf46f221d554738f74fbd067784f1b6676de1df4f49871f74ebd6854e9dc2d9ffbd03a7cb85cb6562b359b1d96c800926d8ed60b7bb308c9307990626560c4edecdf8a1c07d2275ea1449747434e161060306f4e1d24bb3898850d2d1967494bf9e49fba1f3553a225daba5ad690be7ab920e3fe8d9b3077dfbf660fff74554545410161ae24e220ca0ce69619ab56bc8dd9b35eb3b2c8486d8080b0b233c3c8ca8a870a2a2c2888f8f66cc98e10c1a3488e8e8e8d61b94f884dec8a4add1f92a1d91aed5d2d6b485f35549871f74ead489912387f1dfffeec066b551547404a7d38961b1d49b7498275fb1d96a928cce9d3b111a1a8ac35e85d56a9290d095debd93183cf85cfaf6ed436c6cac168fb7616de1c220524be7ab74543af7a52d690be7ab920e3f300c83fefdfb73cd3557b27efd3f888b8ba6bcbcfae457e43aa93d2f2c16039bcd86cd662534d44658980dc302e16156ba74e9c439e7f4a54f9f3e24252511151575f2e359d256a5a6a6b26ad52ab2b2b202dd159166dbb87123a9a9a981ee8648abd1b55adaa2b670ad5614eb27168b85f4f474121212f8f4d3cfd9bbf73b0a0b8bb1db9d609898ae9aa4232ccc464c74345d6363484cec4e7c7c37929292888989212222029bad6651bab47de9e9e940cd8541a4ad484d4d759fbb221d81aed5d216b5856bb5920e3fb2d96cf4ead58be4e4642a2b2b292d2da5b2b2d2fdc099909010222222888888202c2c4c1f99ea00d2d3d383fea22022d2d1e95a2de27b4a3a5a816118eee4e2d4cfdce90e868888888874044a3a5a99120d11111111e9682c81ee808888888888b46f4a3a4444444444c4af94748888888888885f29e9101111111111bf0acaa4c3308c9a6f7c8a1d87bdf6cb9e4c3bd95d23dc652da9b7b1d7727272c8c9c9f1a80e4fca5baaf8bfab98382c95a8301ba111d1f419782173dedae7b7f6a0e9391111111111694c507f7b5565f17aeec83fc48bc3ba73e8d3d96c3856e9f73657ae5ce9f7365a2277cc2f585358cecc5f2f24bb5738db3efb805d87bd9c17d30146d3a740b0cf898888888804b7a0bcd3516b527c24abae5f02c04bd7af22327e529df2dffc380e8bc5c69aa33541f7e1cf6ec2300ccebde5a346eb2d2a2a72ff9ceef43b151587d7336170126151714c7de8f533f66faadc557d90b9b93fa5777c676cb6707a0d1cceaffffce519edad7c643a3dbb441015d78f87df2868b0ef6f9d1cebe42957337dc6f5fcfa85e5acb8ee1c8fdb7b29772c9d42c300786d6c328661b0606f1900c7f72fc4300c7a8c5a56ef9cb8aa0f30f7a689f4ead6195b6824fdd24635bbfd2d8beee0dc5ef1d82c5622bb24903e7c7c83631511111191f621a8938ea7168ce0e8d64759fad5521efbba98110b9eaa537ee32bd7629a4eee7be45f00bc77f75b1886c1134f5cd068bdf1f1f1ee9fa6fce127d358f7d50186dcfc3017553eeb71f9caa917f1f04b7f67ec6fd7525c728817afb6f3e8f40b787e4f699dfde6eeedcf230f4ea6fcc82e16fce2fa06fbf3ab6109004c1c104752ff0bb8f6ce797c5d66f7b8bdbce323f8fd1f9e06e0270b6700b0f8a1cf00f8e2f11701b8fac5cbebedc3ca2917f3f0923518c366f2ff972ee6baacc466b77fd9ec85145467f1c7e5cb7961eebd5cdc27a86fb689888888880f18c919f79a5bdebcc7ab83172f5eccd0a14319376e9c6f3b75f2afeaceaafdf489e9cdc1480baef244f696ec2229cc0a70f2c9de2e262774e6ef277a73b0683da931bdb09f753fc5db9f6cb4def7de7bcffd5a6ddf6b9f145ebb4fed76f7301b87ab9d1ca87692601ec61a96e8517962988d83d54eac56ebc9165d389d26439ef90ff9f70c76b7b7a3c241dfd06a2cd6480cc38acbe5a8770c2e7b212b9eff1d6fac7b9f7f6ccaa7a8da49d7d43b39fa759e47ed6d3d616740646dc0ef645c6c2736559f4349c9bfc8ecda892f2dc3385efc2136e3cc39a96de3eb723ba911759386a6dacfe9d999bf1446913561342967f7276bea6dfcbf9389942f555454909797476e6eaecfeb06d8bc79335f7ef92543870ef54bfd22222222fe949f9f4f5a5a1a1919197e6febfc89f3837b4d87253489577e7e36597fdc46ea8d2f93187afa8d190bcfbc90c5eb396bf8e9afa75068773275e1cd4dd69b9d9ded715f0c80c6169037505efbcad3ef7fcaf8ae61eed743a2fbd4d9af5fb8158800c0349d0db6536e89e39abbe772cddd5055fc29e1b1191cdbbe08c8f3a8bd1f120e002bf3ef1cc8798f6ce1e6ffb99dfcb26ad21f7a169b17ebe19b6a7ff9d67f71e9b2ff61cbd7dbd9fce7052c79e94daacafeed79430156fb1f343f3f3fc03d11111111f15c6b251cb5823ae90018be6009f3fb6f26e3a6e1f5969f35e915064426f2d1bc8fb1459ccda2ac1e3e6dffbe41b1dcbda590290fbec024ce5cb3d154f9efaee8cd557fd9c5d3739ea3f3ade309a938cca7ebffc697837fc7278fa47bdc9fc43e439939730a17f6efc9b16d7f0320aafbd416b737f09779843c3a8657a72dc130ac3c33675083fb2e9890ccf4bfef61c2a4bb787cfa50bedff2260f2c58d5acf627ce7a8ef1232e60d8c89ef0d55a3ecf2ff4780e8245464646abfe67151111110994b8b8b87ad7433757d0271da1d1239833674483e5165b3796cd1ec8d0795fd2efea97e8eacd9fe71b316bed0adec99ac1070b1f2366d6f3c03f3c2a9ffce77cf2926f67d1aa35dc32f35542a3e3199036949f8feaee557faecbecc186e5cfb2e4bbc338ad519c3bfc4a9e58fa5c8bdb0b8d19cddc41b1dcfbbf47881df024e3ba8435b86fceea8fd975db4d2c7e7d29bf78f72592070ce18166b61f7e209fa71f7899c2323bb1c903b8f3f72bbc9a0711111111691d7171714c9e3c99458b16795d4750aee9f0c4471f7dc827cfcde4bed7f7b1f2502953e32302d617091efe5ed321222222d211d4261c80d74947d0afe9688e912347131219c7558fbdad844344444444c4477c9170d46af34947ed372a8988888888886f9c9e70b4744d47503fa74344444444445a577d0947edb6b79474888888888808e09f840394748888888888088d271c2d5dd3a1a44344444444a4836b2ae1888b8b6b51fd4a3a44444444443ab0e6241c5ad32122222222225e698d84035af895b9696969e4e7e7336244c34f0c170984bcbc3cd2d2d202dd0d11111191a0e549c211d0e7746464640035019e4830494b4b739f9f222222225297a709474b9fd3612467dc6b6e79f39e96f75c4444444444e434e74f9caf351d2222222222e25f4a3a4444444444c4af94748888888888885f29e9101111111111bf52d22122222222227ed5a2afcc05f8e28b2fd8b66d9b2ffa1214525353494f4f6f749ff636667f69ce5c8a8888b417478f1ea5a4a424d0dd68969898186263631bdd67e7ce9decdbb7af957a1418c9c9c9f4ebd7afd17d14f7f926a66b51d251fb8f70e38d37b6a813c164c99225000d4e6c7b1cb3bf343597222222ed456dc2b17dfb760e1c3810e8ee342a3131919494148006138fda84233b3bbb35bbd6ead6af5f0fd060e2a1b8af862f62ba16251ddbb66de3861b6ea0bababa25d504952953a6b07af5ea0627b53d8ed95f9a9a4b111191f6e2d484e3b6db6e0b74771ab570e142005252521a4c3af6eddbc7d8b16371381cadd9b556376ad4283efcf0c306930ec57d357c11d3b5f8e355a669629a664bab091acd194b7b1bb3bf688e4444a4233970e000b7de7a2b55555581ee4aa3a64f9fce8a152bdc773ba4718afb7c13d329e9388d920edfd11c89884847d316628460ef5f6b52dcd73c41917440fb3a799b3b96f634667fd11c89884847d31602544f629d601f4b6be9e8f3101449477b3b2195f1fa8ee64844443a1ad33471b95c81ee46a3f4feec19c57dbe39675afc9c8eda7f084f7f6263639bf55a738ff5e58f3fc73c6ad428323333193d7238e327dfc0b20d3b9b7dfcdf1eb88af32e1a49f6e5f7b6687ca7ce5fa0e7524444a43df1f6fdf2f3d7e6317ec470468f1ecdc5c32f61de6b9fd7298f8b8b73ff5e71f89f5c31f06c1e5eb5d5abb65a2329325d156cffe61b0a8a7db300fb9b6fbef1493da7f367dc679a26f9afcee5928b86307cc4282e1e96c175f73cebd7b8ab39b15fa0623a9fdce9f0f6e4adefb8e6d6e5afff30cd3df9bc6dfffdf7df77ff7e78eb067e797516db9ffd8827b2929a3cf6b63f6ee03ffb0f126d355a3cfe538f0fe45c8a8888b427de0468fbdfbb97ab9e2f67edbb1b39bb5308f6e33bb8e3929f706fb70f787a5c8f3a759fd8bf9149636731eab76b79f0f27e5ebdd77a728cb7efe555c5870889e9467571195d9212282e6ff9b760c5c7c773f8f0e116d7e3296fe3beefd6dd43cec24ad6bcf521fdbb8482ab8a0dcb1e0fd89db096b4eb8b98ce274f24f7365b6aecb5aab2fff0cbc9e3c9ca1ac3c52326f2e7af8ed6bb5f7c7c3c6f3e7103e3c78de0bc9153f8e07045ab6472be1873fc802cfeb03a973fddf15c93e3be764236279c2eae183b86ab7fb505d334d9f9ea1cc68fbf8431a3479131f24a56fef787398a8f8fafdbd629dbb5fd587bcd150064666692999989699a7c383f97f32eb898319923b83c7753c0b362111191b6a43640f5e467e19cbf70f3f227e91b69c5e572618deccb93cb73593d67a17b1f80929d6b9898792b97bcf01ef75fdac7e3766a7f3c8975bc5574b49a84e4bec453cc216bb8fbf5eddbb753567480bd7bf7b06bcf77943bcd6695d5aa3eb68f3d872b7ee8a3b38c6f77faffb928dec440cfcf59cdedafcd252526a4e6352394ac9973dde54dc5711bf26ee7b2f1d99c376818bf797b9fbbcc5efe0d0fcebc8ca1234691397a24573fbcc5a3d83950315d40d7748c1933a6defa005ebdea6a06cffb90df0deecaf1bd6f30f8d287b8eaab17cfd80f60cd8fef67edc37dd9f5e62d5c9eb394adeb6779d59fd3eb6d6c1f6fc77cfa71d167dd4445e10598e63ca0e171bffcf6bb74efde9d8d1b37baeb49cabe8fb5d3ba0150baf30dd2ae7c9ca9fffb6c836d9dba6d9a26e397fd154eabf3fa67ffcada1dfbe81b6ea3fc6402e72d251d2222d2d1781323ac2e2ce7b3e44e758eebdcf37aca0b87609a4fba5f9b9095cb152f7fcaecd18941fdfeecb21fa5c212c3c0e8504aba8551b0a7920109863b897024a4704ea4054bd96eb67e5f45ffe408aa5d4d970184c474c7b9f310d17dfb527adc4e45e1112213fa101f174d6191e74f83f767dcf797a20ab6244535786c5371dc5be7cce6cd3bfa52ba7b198326dcc1fd135603f06ace64be1ebb90cd4b470250f27d4dbce649ececa9369f746cd8b0a1cef68f7ef423775dbffde208dd674f62c5c9b24e96e23382e65a4f4ce88d699af41eff38c76665629a377bd51f68dead275f261d35db16afc65dbafb1deebae1650a4a9cd8ac061545df629a794db4d5f8efd7a4c773e3ac07b8f6cacbf8d965a35a749205fb423a1111117ff0e6bdb326b638b38e53eb9a31be0f2f2d5ac62dc3ef25ca6a78dd3f4fde9fbd194b796109e1f167134a05aea86ed877ed24e4acb3314b6bd677f4ed1681b3b48812331a47f95ea2bb9c4be191f226cb6a84101fe160776528dd5ce51c3aeee2acb3bb623f7ecc6fc9544be3be860e6d2a8e7b62c25998a649e7b3a6535df2a0bb0f4f7f5ec87bab2e726f472786639aa64731a4a77c11d30534e9a8efb8dad71c98bcf2f63a7a865aebddfff4df7fe847cb6e01b5f69d8e925d8b898c9becd5b8af9b7e3fd3dff89cabce8dc7652fa247afc1ee72ab61e0344d2cd42ce66aac9e537f7ff06f9f71c5271b58fbd7850c7b61035fbdfbb857e3ac6fac222222ed9d3731c2a4b84896ee2d63f6599dddaf95ed5b5a273e00b861e1bb54e56631f61736362ebd93088b7789875fdf9f4d27874fd8a17a179f15b9709926064e0aaac2e9c20f8bcacb2a9db50760b14601e5cd2a03884ae8ca9e9d87494a2881c8eec44558282e74e20d7fc67d93e22258bebf8c5b923bd75bde581c07106e9cfac76987bbcc68a04f9ec4909ef2c53913b46b3aeefe711cf7fc698b7b7bf796edf5ee07f0f8bb0598a649c1bac78839679657fd39bd1fad31e6435b3772eb554b989e778bc7e3364d93efab5c242776c6344dfef3da9c3ae5c3a34359b1bb04d334d9f3de6367cc59edefb121560e563b6bb65d556c2d7470ee45e3b9e3b12739b6ed8d56994b111191f6c2343d5fd3913bef672c9af110db4bab70b95c54977ecbc33316f1b37937d559d3e132adccfafd3aa6b29aec9b5ea0c2117c6b3a1c15877185243064c8855c78e1850c193284f481b114ef3e4a74684dd8b9fb682500f6e3455842636ba2e8931a2bab65b1c5d0d975803d07ca89edd91daa4ba967f9874f791303ddf29b9ff2c28c47f8b6a4fa649c55cdfbcb7ed5ac38eef4364fddbe6f683cb3977cecde2ed95fee710c1988982e68bfbdea9a15cbd99a3b878b973b08c7418f0bef60595abf7a8f1df7af27b9ecf91d1cac4ce0f9954ff97d757e4bc69c9d9d8d6118982e07e109294c7de66d7e3eaabb57e35efad8346ec81c4d97c42ef4cbbe1358e72e7f266f16d37e96cdf2a44452b26e03fe54ef37563d356d38976666d135c2c6bab5aff3f8b59328b21bd84f54f2f3479705fc9b0e444444da126f02b4a4b1735956389f3b278ea33a348ceaea507e72f39fb8676c529dba4cd304238cdb97bc4bf5ccb18cbfd5c6bb2fe612e2e10d0f4ffae7e9584a0bcb89fc515f0ce7710e179d38594934ae8a02aa220701105bb6877d474aa972da48ecdb0f97e384bb9dc6ca4eed4f4cb730f615c7303036821347cafc1a73781bf7255df20c4b8b9e62f6c431945bc3c1e52065f814469dacabb1380ece8c936bb7a7bcb292adb7dd4dc6e85fd139c42071f8025e7934cda318d253be985f2339e35e73cb9bf77875f0ca952b99366d1ae5e5e54defec27c9c9c9ecdbb7cf67f5555454b06edd3a727272ea2d0f8631b7154dcda58888487bb17bf76e366ddac4cc9933833e46282f2f67cd9a358c1e3d9a3e7dfad4bbcf071f7c406666260e87e75f751b15974068d9118aab4efdc8938584eef17cfccf7f3262c4088e9da8242ad486c570517ab4982a97c98e1d3b1a2c839ab5bf070f1e04a0ecfb3d9c883b97b41e560e15967adcc75a4ea7934f3ef984cccccc7acb15f7d568694c77fec4f98159d3d1ab57af46cbf7eeddeb711f7ca5b9773a7c3d66f07cdcc14e773a4444a4a3f1f4afe20d05fda7dabd7b774bba74067fbe3fefd8b10376ec68a0f48779a92c3b4665037b355476f0e0414c5739df7d5788cb12494af748aaca8eb6b4cb4d0a865837d082e2e355e079470a0a0a7c565f414141ab271d9eec57aba9317b5367b06b6fe3111111698aa701eaae5dbb9a55a72f7912eb78da76bf7efd484c4c6cb2edfaeaedd7af5fd3fd332248ee7d0eddba456371555158e1a035a28d40c6bac12028928ef6b660d85f773a3a22cd91888874346d2146f077ff0e1c68fc617d8d9537752c80e9aaa2a8b0d0e37ed55b97e2be6651d2e1073af97c47732422221d51b0bfff057bff828de2be20493aa07d9dbcfefc1ab98e46732422221d49626222cb972f67c2840981ee4aa3de79e79d463f022567eae8314dc0938ed4d45456ad5a455656568b3b122c366edc486a6a6a83e5ed71ccfed2d45c8a8888b417313131a4a4a40035417d304b4c4c2425258598989806f7494e4e66d3a64d646464b462cf5adfe6cd9b494e4e6eb05c715f0d5fc4742d4a3ad2d3d3dd1d692f525353dde3aa4f7b1cb3bf343597222222ed456c6c2c00292929eee42398c5c4c4b8fb5c9fda45dd9b376f6ead2e05447272b27bacf551dc57c317315d8b9ed3212222222222d298f327cec712e84e888888888848fba6a4434444444444fc4a49878888888888f895920e1111111111f12b251d2222222222e2574a3a4444444444c4af94748888888888885f29e9101111111111bf52d22122222222227ea5a4434444444444fcca0630e6968f03dd0f111111111169a774a7434444444444fc4a49878888888888f89561969bf4cabacf0c74474444444444a4fdd9fbc9d3c6ff015f8a7f0eb7a982dd0000000049454e44ae426082</data>
+ </image>
+ <image name="image15">
+ <data format="XPM.GZ" length="21774">789ced9bc76e25399686f7f51489e6ae3060873718cc42defb941dcc82565ebaf2a631ef3ee4fff3c66466c964035d48b454f700aafc4406791c0fc9d0adbffffe656f7de5cbef7fffede656dd1e9b2fe6485d7ff9ddde9d9f3ffdf7fffcd73f7efb5b5e945feaea4b9d575f8abffdc76f7fd30b5fcc1791e113d94d818bacca6c647f97b8ce73b4f7e0326bf23ab2d1e02a4a64fb086e3293e379b70f6ef3acf4e8cfe7bb3caff0bc9d07f7992f7bf00c58e5758d76cd761305e3917d118644ffe5c8799ed519ec317be0a06f56a23fdbcbc2351d5882aba021daf50e390ada4b701d34d060056ef2966c9ec03a0ab8019b5c670afd67c955a5e04f0bffe4367705ededc955d3c11e7d007651c0db601f05febf8a5ce44557607c037d0a7cd07e9ab82e609f3f0797852a31be29c075d1966c87fe45134684bde618dcc71e68bf4edc150df4994b1c04fd8f12eb82f6b7e44669e8e7cfc0a195fd9d1818fdfd636253403f6bc026fc86f1a13ea6d235f32507db20f4d7eec0c82fb10e7675a7114fbb446e5bcde7315f994741ff3d72ad35f3b706176596c62357b5d7f08746fe967514f43f04b7d18398cf92eb42413f754c6e0a0dfbc54ce2ced29f9cbf8f82fef760d50485c00f603df072e2862c6e121b4bff7ab0c97cc6f860fd963630f4572be4a6d7b04fad825d8817eda53daecd2ce3f90cf651102fe8536565c1f8a93b72d007f9a7b2c4c620dfd509380fedf08f3a489cf2c3b17fde351afe506be0229807fd65456e2b8bf56091af5559f99af3e7e436339c1ff1aeaa601fd9905dcf7879f8abaa6bdb637ef5481ef79735b9ade94fb99eb877ac77a95d6506fa88af645797f4ef65e2a6843de26160b48b89c42ddb951e98cf637d564d5b1aac47e113d78c873823bb8aeb57ac24aec916ebab6a3b6d38ff33d9e525ec957de282f9260f06a63fd2f3ae64bbd84e5ca5fe1be0ae5596f9724e76591a7f6160e82bb713a7f9954b3c9e0ff5b5eadb86facae9c4d6311e5303633d0bfab70f487f6c0dccf5361a98fa89c43ee9b33330fa0be64b3fe84b7d54ab2df25dae251ecfcf7c5256733d8893c486f3c9bd81911f7231b14dedbb89d3fc0afb4fa56dcff1649758f179313930e7bb48ac53fb7ce234bf500373fe5bb0e97247ff32df8d6d2bac4fa113778965e2b13efb89c7fa2c0f8c764b7d6d5972ff575c2fb6cd14e22b980fd63615ebed66e234bf7c1a98f581f3b9c6f379c9fae282fef0bf9c4c1c4a3cc6bb27dbaa42be88c78119af3c719de67f1a98fd4f13376485fa5d799b575c7fa3c4451a6f6e60b42b95b84ced8b89c7fa607facb3b6e2fe236712070dc1e7e4ae765ccf05d9663c0f899dc4637db01fd779582f6c5f251b97fa670373fddf25f66c97f303633eb93430d7fb01793cbf44bd0c8789c6a13e498e5f98ae623ef4896d9aaf1c98f5ae4b9cf4513303b37d8a1ce6637ed29e32f887f5e6821cfc83f8499f5839d6ff2bb2d1b447d1df55dbf4f4ef1979dcdfce927b45ffc9af64d354888f9a4edcd31fca0fcc7a457dead09ff56294d89005ce7f7513e667be6e26b61aeb7d03ebb16e3be778bee3fc5d148cbf486e5d0f7bcd09b92b0cc7b389d3f3d225f66475480ec719ae47e65767f264df54e2a242bd308c671f7774b43f915bdb737d36899de2f3f467af4d0d7d14fdd90fe3637fa855dbf58c1ff3597559d2ff3e7169984f8789bb146f43ee33c7f309f34fe9ae667eb58955cdf5779dd8d4d47f2eb1abe13fcff8e82a2fe89f3df2583fc578e8aeec987f22b1e1fea326c9613eae6ffadb7619cf83ea3471919e9f485cf17c20e99f50af34fdb94c5661c703337f5dd097eb01e79dda77e1c48a764deec7f59bf67955b5ccdf3671d3d07f380f3459988febed99dc87131ec63f4eec5bea83fad5e49de679545e92fbba273f9055deb23e5c252e38bfb089c30914fe46be3645a5b99fea597214f4bf25775d87f1fcf398799e95a7899565fddf22f7aaa5fed81f9a32f887f9bd40eefb86fee67865d08ff516f5bf09eb9dac109fa60efee2faa27df8a07d93dc551debed7462dbd3dfd7897d5a0ff36455365c0fd8df9b36e413f36583ac72b68bd4ae0ac64bd03f5d9ffc2751bf9a90ff3df38bf6ebce267faf91fbb1fdd81f1ad399942f8caf5125e3e7389e2fc39681fedbe4ce37d41ff5a7cdba713e207e6dd197ac57ce924dcbf3a7c3fa6cab22cff0bc5b22d79ee703c3f63e0ada912f6d383ff578fe10ebabcba2a01e235e5ddee70afef6d83fa2f7e83f7739e69ee7db8d8179ff853f63b4182f87fdab6bca70c5403bd66fd746c1f353649df617cbf6703b607f8dfadba928186f34e69ef71ff8afd351d00e7f85ec308af7d90bb2ae2de743bdeb5c14f4c7faee7c70209f47fc42b433d65b8378f779d86e785f853ef17aa8309e29c926e3fa70982f6c5695e27d749a1ce2c5fb34f6ffb09a6be6af45bde89b4e733d1c4a7214e88ff5d987f29cf3fe784eee3bde67dd2e39145cbe2f427deef1417fd8d7abc6f27ca0399e8a8276c4bfd751a0cfe19815fa7bace7de44c1f3d89f7a1b05ed384f846aa6799eb3f4878f025e1f731a0ffb97ca6ac5fbb946beaa3c0a18f1514514e8773166be3fd0c5c0bc3f421f15ee9b3cbf9a5bb2aad3fb01e8a32a55b1bf457d09d5a6e5f9dce7e428e8bf32e6f43cea4b28762de36d71df443a22fff5da98537fc457e1037d4ec79ceed78764ab795e36d8bf42a366be5ad47f65db96fba7477e28d7e4ac17ba2787e313f389f67a95ea9ff5634eed9b03b31df9a3c3fed3319fefc851d08ef3840ebb15f74b07fb75a972e6a3fd4ad665ca37e8afeb28e0cd31b3ddc13fba69d3fb25bd45d6e9fd82aec7ccfe1ef55bb76dcff74daa23eb96e743b34fb696fef37cbe0bfa31fedbe428989ff68684e679c76e0dccf8c15f703fe263b1beb56e5c7a1fb6430ef59bef5f27c8f18376acbf70b96f73e86f39bfd1c6b09eb1ddaab4def425390af45d19b3e1fb39facfb505e3eda88fd319d783b6898380cfc79ce63b1d98ef8b385f883ed9e3bc6332d5f23c6bafc851d01ffb9fc94d7adfa4e05f135f07329e2dd936bcff79e86fca2e4ff5f3991c05e3ef246e581f3dfc67aa78c0c47cf7e428b0e77160da87f562ea28e0a78191bf1af717d398f4bec26c8ed9b29e60ff336d14b423bfc2f6dca5f88b315be61ff61fd3775dcef5bb408e82fe9363e6f896f6f7aee47dcca19e84cda74ffa1e938d4ae363ff375ae7a9fedf90a3a07f3366cbfca67e4679c6cb4b72fc603edccf8c0d16707d568983a09dfe71aae0fdce6d93c3fcf48f221bc7f9f4c9c0ec3f4d76e93eec190fdfb539f7ffbdc43ddf9fbb9bc4e97db12dc851f03ce6b359a7f9f7077b41ee1bbecfd213e4209c0ff5ce86f30ef3dd3d91a3203ecb03d31fa84f36acd69cfc48d655cff583f386ada2805707e6fc889fada380ab8159bfb17fd8a62f38bef1e470dd65be50ff260a9e9703f37d29f62bdbea86f9af685f673bc7fa7b3c30df6fc2bfe13893717cdb246ef93ed6ae91a38071deb2aa4ff543d3bfcaa6f3bb3d1933ef534e935db8e0c2dfd88f519e583f6ec69cfae3be634375e379579f916dba9f69fa071ff467bb8b82f98fc6ecf8f728d427ebb5637cec34d9589e5f7c418e82f14ec9e1f8c67a8afae5b228d0777d60fefd646d60ae0fc4dbe5b6a6be66831c84fbfb44e29ee31be4932b6c9beaab234741fbd2c0fcfb0cf697500d4ad647b33a30f2d9603f7321dbf8f72723c941a81ffcebeab01db03e1e24f6cc7f3b2247813f5606e6f3d81f5dd31519d7cf25d9a6fddf57e428c8bf7660ae77ead7ba22edb73b895bb69bb981e99fb38159ff511f4374aa547f8ac4b585bd7a3971477f683d30fdbb9058a7f170be717dd7645c4f47e42898ff6a609e2fb19f84e351c7fcd3a3c48afa5a99388d6f501f03f58c976b12abe4df8581797f738975d2371f98efa3aa8159cfd707a67e8ca7ed72c6c75c939df55c3fccc7f0211becf73e8b82f9319ecf4341607e8cc841a82fecf765e733eef7c8df70b90c02467df16d14ccd70dccfb21f2d777aaca19af961c84ef67e01f1cef592fb1dffb78c0e07cc80f1f36d034ff22390ac6c779d3db713cbd27ab86f3d96b7214b4d35ed765fcfbb59f4d5ca7e76712f7fc7b9adf20f7796a5f1b98f5643f7197d6c75e624f7fba4d72b89ed0df693c5592fd6ae2e41fef12f739cf43d3894d62c6cfe99afba5d789d37dce9bc48ee7273f450ee594fe3f254701737c7c226fdcfebf482195d4d2483bfcc64af76d8f8f22d172e9bf914379248fe5893c9567dffdfec3092c3fff462ee4a51cc92b792d6fbefbfd8713587e3bc89dbc970ff2513ec967392127bf69f97002cba720d37246ceca39392f17e4a25c92cb7245aecab5d4fae10496af07d9909b724b7e95db7247eeca3db92f0f64267359c812ed1f4e6079256bd9c85676b217a1b80b21947c125a6e0b23ac70c2871e1f4ea2e5e2501c8963712217c469b0fa4c9c8b8b60f5a518c93d7122aec475e8f1e10496df885b712717c5bd7840d49578144fe2594c849f93624a4c871e1f4e60f98c98958f622e447b5e2cc4fa2616c552c8f765b1225683f56ba1c7871358be2e36c46688f356b0f8abd80eb6ce856c5f113bb28bff16bba1c7871358be27f6c581c8441ea23d21168408768f82e52ad85d885254a1c78713585e8b46b4a213bd924ae0cf0326be94099617caab4375147a7c38c10df2589da85375a6ced545c8f81dd9ab4b91a991ba52d7ea46ddaabbd0e3c3092cbf570fea513da96735a126d5949a56336a56cda979b5a016d5925a0e3d3e9cc0f29520ab6a4dadab0db5a9b6d457b5ad76d4aeda53fbea20b4ac7c4481e5d96714589e7f4681e5c56714585e7e46e17bdfcf287f59fef9e41bcbeb20bf5c9f7fa9bc69d1779657aaf9e5dafe6b2d7fc3a2efb2bd79a55f1bbf94a7a58edfa6d13f3b6ffca203fe58e6f5e12fb3fd358b7eb49c7efa4386e8237dac4ff46990337dae8fdeb5f9425fea91be52b5bed637fa56df052fdceb875f64fd2b39ff82e5df65c8d84efda89ff473b07d424fbe63f7949e0e32a367f59c9ed70b4916f5925efe4596bf90f37af4426dff2e43f48a5e4dff5ad3ebc1f20dbda9476f5abe1572e4abde0ed6eee85dbda7f7f5016cbfd0d92fb1fc859c0f1ae6efd5765de852c7ffd6bad1adee82e5bd916fcd63849e366a1c6ba3d37f4dfcc2c8d0c79b4373648ecdc99f6af1abb55d5fa5fff772dcef85ac30a7e6cc9c9b0b736946e6ca5c9b1b73fbde8ce62ed87e6f1ecca379d2dbe639583d117ef3cd2a3153663afc9c31b3af8e31f7ee2ceff678adb6eb9199370befd576b36896ccb25931ab66cdac9b0db369b6ccd777b5dac65a4f6276f491d9fdae7dcfec7f43072633b9294c09bd164c656ad398166d9de9ad7ca9878ddf63d2d658fb86262fd676eb42edcddfabedd6db437b6436ecb13d51bd3db567f6dc5ed8cbb72db7237b65afed8db6f6d6de857fdfffd0fe601fed937db613a0493b157e4edb19da654326d8393b6f17c27f17edd2cb3d022fdb95f073f5ddc8ff90f3fa411bbbf65e6d0f23afdb0dbb69b7ec57bb6d77ecaeddb3fbf6c0866a65f337a23e618b905577b6b495adedda1f7cd3d8d676b68fff76d20988a25d0e6786f8c5c3f8e51777f86a8f2377ec4edce9bb96ff60913b330b2f58fe4286b87377e12eddc85db96b77e36edd9dbb770feef1ed19cd827b32f3eed94dbc5667dca49b62ecdcf437115948ad336ed6cdb9f9377a2cb845b7e4dedf2b7fb0c88ec29efb6e6d1fb40c79e556dd9a5b771b4136dd96fbeab6dfb15dc455ee765e186dd786fdc1ed39ac7677e0b0dfb9fc3bbb0a57bacad5aff588df4d0b3f3bd7bfaac12b16e991adbcfce7ceed5ee0cbf2c65befbcf787fecdf39c2dfdb19efe718d639c137feacffcb9bf005dfa91bff2d7fee65bcbc3ef6ffd1d63fd520f7fef1ffca37ff2cf6f58fe8a457664ee7feadcfeadce137ed24ff9693fe367fd9c9f7fb3ef825ef68b7af1bd31ff4479d522bff433e7f61f9e59f62b7ed5aff975bfe137dfeaa933bfe5bffa77d6c49f2e2fdd4446fae8fddafe82ed3b7ed7eff97d7fe0df3c8ffa3caca7c2977fae65c3cd00f2a2e53f58a447bef25b3f53db5fb0a9f68d6fe3f71bdfee77280f853bfb732dffd6f6577afcf1dcfe7dccff8ddfc9bc62f7a77827f37379fe8ae53f95e7ff66f2cfbc93f934f297e59f4ffeb2fcf3c95f967f3ef9cbf2cf279fd8f2fffdcfdffe0f74789dae</data>
+ </image>
+ <image name="image16">
+ <data format="XPM.GZ" length="146794">789cecbd4797e3b8d6ae39bfbfe2acabd9b77af1cad00e7a201fdefb5e3d20013a194a9497facf378877036152612bab32a28e6a9f93194fd2017837362c19ffe77ffe737776fc9ffff93fff6b3af36729fb0f4bfcc97ffe87cf87c3f5fff3fffedfffdffffadfd572e53f55a7f69f6ad534ff53fddfffd7fffadf46f01ff69f5259fe57f030d65c917cac599e3fec6aae159cb5349b05d71f1457ac8297367105f7cfba9ae5fd3253b3bcdf68ad59de6f72a159de6f58d36c17bc181057e97ea966a48f6996f71b5e68c6fda69ae5fd861bcd8ebcfe4eb32b79a2d92b78a5caab86f25a0c35e379779ae5f3e603cdf279d99166f9bc91af593e6f38d32c9f973f5eef173c2b690e242f884dca5f5d339e77a6593e6f78ab593e6f126ac6f3ce35cbe7cd0f34cbe78db96626f33fd1cce5fd0c620bf7cf33cdf2fed34bcdf27e59ae59de6ff8785cde6f6a6b0ee5f9c79a2379fc9ad8a6e7799ae5fdc64cb3bc7e956996d7cf153bb87e1c6a96e95d9c6b96f79bde6996e95b6e34cbfb65aa7c9d8af4ff9c6996fe325f6a96fe3bad6896febb686b96fe3455fab9d063126b46f92d35430f43b3cc6faeeeef223dc38e66999e8c6b96cf9fcd35a33eaf354b7f9a8d893d3c3f7715e3fcd18d6679feaaa459fadfbca65996f722d58cf2b635cbfc4ef7897de46f32d12ccb3f4b34cbf21fabfae0e3f913ae19cfef6b46fd196946f929fd03f2e78666f8df8366f85f5531f41c469aa57ef99d66593ef95c33f277a159a667a5f2c3e8794dc5387f32d62ccf9f9e6a467a94ff705c3fe96846f9287fe1e40f9e66e90fcba666e90fe307cdf2f94be58fbc2af33b3f240e51de8b8d66a9ef68a519e9d1c7abf2f9d33dcdf27eb35433fcbfa55996df62ad19fea8d21f213f932bcd68cf4e34cbfc4c1dcd48efe3f5d23ff20bcdb27c877b9aa57f646dcd284f7d1ce99fe8e394feb96679ff29f967a54ce57dad595ebfe09a6579e71bc5b8dfe45c33fcbbac59de7f42fe58a920bfc323cda85f579a115f0dc555d447a619fed523aee27ecb4433dabb4746bca8684679058a91fe59a459fac394e243a586fb2d169a515f9a9aa1f7b966d4d75bcd323f23555e353c6fc934a3fda4f6b662e2fa7c4f7155e66fa58fe3fae14433fc4595b75993feb638d12cf51c53bcaa58387fa4d26f43cf6c4f33fccb540cfdf2ae66f8d7bd62dc7f76a619f15a95bf03ff1dba9ae5f523e55f0ed2bba4fa5871a9fede6b467971cdd25fb243c5b87e6668c6f3a9bdae50bc5eec6b86feb666a447e9ede1fa9cfa17151ff161162b467af2ba66b4372aff3eae5fa8fb51fc9c537dae301c5f52bcab70a467c6344b7f99398ac9ff3b9ae15f3dcd88c7aabc780dedb7a519e9a1f6ad42f162a9fc9fe2c3c2d20c7f982aa6eb29be8b9e3bcaafa718f16f9429c6f973aa6fd50ace1f9715c3ff3275bf0a9d4ff5a54af533bf524cfe7da9187a0fe79aa137f96b55d53fcdc8dfd4d58cfcdc69467f7bad59fac34ce5af86e74dcb9af13cea1f56a9be4ed5f32c7afebd626a3f569af1bcb666d4ff9962dc7f4af1a46ad3fd0e15e37e4b4733dab37bcda8bf55c5487f5ed68cfb937f571dba7fac18f71fde6b86de378ae97a8a3f5517d7cfd5f3a8fe2e1e34a3bde82bc6f513ea2f57a93ece53c5a4574d33fa17ca9fa87e4e687c53a5fed1cc524ccfcf34cbf2581a9a65fdcaef354bbd27cabfa8fe4ea87e5403baff4031dd5fa53f207fbcd18cf6fd4a33e209c5bb2aa3fb858a71bf4ce94df121a7f850a5f83055e9a5fecde24233fa3f2dcd323fc38662d29f6b467fa0ae19cfa3f6a51ad2f394bf51ff67a4ae0f71fe98da832ac593a1aa0f2a9e1c69867efa38ae1f513cac513c99a68ae9fa5c33c67ba662946f76a219f7237fa851bc99a8e315ba9faf19fe38538ceb332acf1ac59fc95231b5477b9ad19eb414a37c279166dc8fe2498de2516e29a6fbf53423de3614d3f5e46f35d51fb8514cf1c4d68cf4ac14233da34033fa5b146f6b149ff223c574bf8966e8f5a098aea7fe428de251aecea778341b6a467a12c5949ea566f81bc59b9a8a37e79a71bd4a3ff50fb29a66a447953fc59be98d66f8cb9d62ba3ed40cff55e957f1e64833aedf574cf1ff4a33fc4df90fc59b694733f454fee653fd1b6986bed41ed5289e4ca79ad11e9c2ac6f5e34833aea77855a3f831b9d78cebd5fd183dbfaa19e547fd951ac593c9a9665c9f29a6eb3b9af17ca537c587c94a33c68faa7e87a4ffad663c9fdaa39a1a9f649a71bdf2bf88f45b6986ff90ff9b141fa6b78ae979579a713ec56b93eaff5433e5ef5433cea7f6d9a4fa3eed2a267f38d18cfc50fb64527d9ece1453fb106ac6fda97e98547f27678a29fd8666f8abca9faa9f2dc594fe4033ce27fd4daa8f9391623adfd10c7f267f32a9fe65ea7caa7f13a619e753ffcb54edfb8362f2d74033fc85fac326d5af5ce587ea57ded38cf35579527dca5579537d9aac35e37cf21f93ea4fbe524ce5bfaf19e7d378cca4fa92abf2a2fa929535432f6a9f4caa0fe3b966dc8fda5393fc3dbbd60c3d943f903fe76bcd384e7a5be4bfd923a3bc69fc6991bf8eef34c3ffa8bdb654fb43fd3b8bfc2fab6ac671aa1f16f9dbd8d78cf4905e16f95346f5d9227f19527b66297fa0fc5ba4f790ea9345fae454fe1695e75ce58fca6f42e565a9f252e9a7f29951fb6c53790c490f9bf23f237fb3297f136a2f6cd59fa6fea7adda1faa3f36f9db94f26fabf4527b6c2b7fa1f4db94fe91ba9ed29b91be8e4a1fe9e5283da8be39949e11d52f478d97a93d7054fb46feeb507a96a49f43cf9f917e0e95df90cacfa1f4e4e40f8e8a97941e97d237a3f270953f28a6f42da83eb8949e8cf47449df05e5c7a5f29b51ffd055f591da2b97ca6f44f1c355ed8f3a5ff53fa93d7129fd73c594fe21f983a7ea03f9bfa7fc9fe28fa7e231b50f1ee56f447a7ae4df19f9af47f9cd29fe79a44746f5db537a50ffc553fe4df1caa3fccfe17f15b55ed44935cbf1de3823a6f59c754533d66f226207eb458b0631c7fcd306fd95aa5a6f69049a657f2c3d25a6f58e4d49b39c1fe887c416cdef59c42ed2bb803f563dbf86f52170adc8813cff8a98d673e613620bf383f5a96679bf5e83d8c67cd974a45996c712fdbfa2bb2cef1fa23d360b93f7bb2276301f3240fcb7547a56217180f2edd614637cd775891971ae59964777a3598e973ab89fadeedf59115b985f1c5588bdaa3c1edbc40ce9aba7c41cf34553e8637b414d8ecf3b88174e318122f547bc742aa24724cb2bd72cd3b3417fc055e72fe6c4b47e55af104726e6bfd09ebac2fd303f70a85996673c24ae98d003f5d1f5584dfa5f82fc7be508bc827f7be27aa477405c33657a177bc40cf3835d3ccf17e993cf5fb7893dcca78f513ebeb81ef387678a2d79ffc105b1094e0262cb92e95d21bf81c8814cdfc024a6fef76a434ceb232bc49740349732bd8d90d8b6309f78aa59de6f64113b964c1fc7fd5861323f889fac220284649bd8c7f92be8c90b93e9437f9c577c5beab5bc250e2ccc07de28b651bfe7c4cc96e559477b1b161d5cf9bc63628a0f73b43761b5e2a0fc707e540478190f507f22116ee4f1cd90d8b2e5f3d701b14de9bf576c4bbd56b2fe56640093fa1e109ba8df2b8fd882bfd56fc055d792e59548bd2b15e50f9b3d70c5813faecfc055dbc1fcf844b34c4f2326a6f28d65fb5ca9161d22f9fc26b83079bf0b70d5c3f5435fb12be343674aecc39f963dc58e3cbeb9256616eaaf1c2f0befa1e70d19b81ab852cfd903317711af369ae5fdd33be210fa8f65fcab98ea7edd7dcdf2faa44a6ce33877c1aabce72d7035427eea43cd58bf49c022c062fd17e9b3d4fdd6379ab1be3f20a6f5e5de8258ad3f568843ccb7aff07c11dd11cfb38e6679bf4504161518eb13b2bdabd8eafe759b38a2f6e9125ca1f62031891d3c7f7d484cf36f4bd91f174769be71e01253bc5d413fa7e63a323de353628e78b792f30b15112fd1df5dc1dfdce28e32fdf047b76651fc95f1a2e2d538f4dec8f6a7e2abfab7447a7db57eb2ca897d5a6f809ebe2902a0f4e71271c5453c417d0ac4fdb07ed807abfc4753625a3f98c2df83aa093dea7bc41ee2f394837dd394c763f837134f90e9591f11d3fc638afac24cd3c77a914b1ce07e63941717e9937a0e1c6217ededa8a35996cf1ae9e5159acf8973625a1fadc33f78d5877f18f0572ef482fef0376eda289f998ca79550adff843eb15aaf45fd09abb4be3847bc88444486fef0b748a447e68f3bc4b43eeac39fa21a7364f9d491dec8141d3a79bf0531f3e5715ff6af45778b3b327dfe0571e8c8f4ac39d88ca0f77a0516150aeb55f27ed54ac5c3fac372481c60fe7e790916faa2be98c436fa6b7d9f98c6db9b353147fc0da5be55f99faccf36b185fbcd1d708dda1bdf038b0e16cae34eb12bd33728832d31a096f9e913331bfe2efbc3d55ad5c3fac0fa5e714dfa6bcf25f66bf278670eb65c2a6fa4d7142994c7eb0d6207fe1dd4c1e21f64fa06e7605b8cb8647e647b58b52a1efc218ec05507fdad111d17cf97c7eb2d6286faed2760b386f81934884de4dfcf34cbfbf5657b56b50b85a47f76c03513fda16003362dc47f7f9fd8813ff84d62d743fb29db17915b07febb9c1353f9cde10f4ecd467fc9c7fd1de19fb2be4cc1ae5abf0ae07faee9c37ffd0e71e0c9fb8df03cd717031ee93f72fc2dd433117fc34b620be9a99f133bf09f7e40ece2797c4dec41aff190d8879eb3367180e3e18566999e4d4533da8331b15a1f38d78cfe11ddaf56417fd7873f7a227f32bd7e48cc3cb4cff02fcf760279ff98ceb7fd40fadf88ce17e5013d707fbfa851323fc7c416faa31b9798fcb3911153fe578c98e6abea67c494bff90531cd376d9a9ae5f1e0166c062e7849cce03fc19a98c37f82b666f85b4a1c7a680f657fb61a88f616fd3bc4a3a05050d64f8798f4496a9aa53efd849841cfcd5233f452d77370a307aef9f0d739e28fc82de2dda6a519edd38498e2df3a21a6e7a58877a23d42ffaf74451c79b2fc02e8c7ac9a8ffec70d31b57f1be457b437f0d7f51d31957fbd494cf3dd754bb3cc7f1c6a96e9e19e66ec4f591387184f96a01f1701095c23aea27ddd437d0bc5f804ebe5f0cfb02801d99e1d107394cfba444cfe3f4179876688f14780fc84e279f2fcd252b34c6f70435c45fdf7e9fe961bc8eb139477e838812cdfaeec2f5623316293cfeb0e8929bd1de815152dac8c5733b030c4bf2ad8aa79f0df26b1ed63fd5e9e5f2bd6b7311ea8826b15f0d821ae82e727c416c6a3cb06d8ac99323fc10a6cb9685ffd81e240967760107be048a65f3cad82f986a005b63c1fe553210e0299df58d6a762750f7a0f8e88297dc125583c1fedc73db1e74b7f0eae897df41f4a0f9a511f91dfaa1d227dab2be22890e99b74c13ec7787185e7d76a1ec65701d25bb3021ff156b63735b356c57cc6e89098e6bb82046c4501e225f26fda55067f8bc062f806ff7cd02c9fdf90fe5013bd09f4e75653e210e559477aad5a85faa7217115bc1c28a6f99e12b145f34db2bdaa15e303b43fa7e0a24592e9837e768df6676c6ac436da8335f4b245ff1af111e9b7c50002fd4113ec7a0ce307babfeb33a96f28db9b9a53b4f0f27cf8a72314433c407e1d519fe5f52594a723ee8fe75d6986fe65e22a714733fc7544ec72593fdab23f5f73457f03f519d7bbb6cd907e19ef6b5e310320f5de808b1297e937883dd4171ff5a5680f65f96d643caef9458fa1e01ce5e1d72c8c7797636207febd82fffa2239580f873ff9964df945f9fbb6a830b2fc9b603762e88fe0fe813ace12621b5c52c71947fb23e36b8d09fd91fe186c9511ef4bb8bfe87d32c991ec4fd7b8f2971cfecb6b9e2dcb83c11fb8eda1fdefa2fe7097ee3780bedc73b83c3f97fdff5a287284f9c5117188fe23eb8145ff41deaf04bd42a7ccd19fc1f95195c66f19d21f89fe8a2ccf68461c51ff13d78bf105fa6b75a99f592e6670a41e2570a58cf2e8c760519fe4fddbf7602b407f35b8008bf295cf634b62c664fd68778823e837ab8175fef17c517b69fc5dd38c78d3058bfba37c17c4d49f2ab5c062c08dfeff14ecda81f4075fc60f53742fe14fac0f16ee20f367e079c57624946f4a6c72f4f765bc376ba23c301e2f83557c99d2f19a89781d3b603342fd6574dc2933ec6791fdb362f515f3b7ed0ad8ae62fcd936894d308b893d946fbb0d762cb49fed16b18df25e0dc02e0bd03ee6e0d043bc1be37cab52417efa0c6c71eadf5860f5bc520fec58a82f8b0ab18df9ac7693d841feda0d629761bc6d127ba1d4afd4d68cf122cac7f2cb4ca6d73f0187560deddb11b188b8f27a5733da139fd8c1f160ac19f3c3b2bd346da11fe23bf2635b35cc37b235d8a921bda505b1057f6ad5883db44fa563706862bce72f892df01afee654e87d994da459965ffb012cf496e9696dc08e8f78dbba200e98bcbe156a96d7b716c40cf1a8b4228e42f41f466037403c5c5f81c57018f309a8df4e58a9e1fa8cb88af85d629ae10fea788de2fb29b1096ecbfea0e9da6507fd853571c5977ab7e00faeca9f6129e6d2ff5b3362ca5ff39c98f2d7bcd50c3d52e210fe5282bfb86119e9356e35cbf30d8f98f21b4c89297f0ce5ef89fa83f63026f6a1777348ccd17e1b178ae1bfc6b966190f1b67c494bee63d71c4647d6d458a39c693376097718c37e87a713bf40f8f35231e3e32e2d59838c2f9254333e68be660551e03f883affc718c78e1abfd3e2bdcdf2f4c9607e29d2fe211b8464cf3656d8bd80197507ebe18fecafc185562553e1d62551e15c5288f36fcc177cbe0c65c33f67b1f80bd2aae2f414f9f0768df4a87c48ccac7d72cf530ee88391d2f1153796de0af623c89785e473c0f1c07ed4703e90bdc0a97f929dd118b27487de02f01f7283d8a693ec80f34e3f8297140c727c42afdb96679bc8df264b68bf236f6c06e2594fedb981257b98c676da619c727c43570cb2336919f21fc81f911e2bd81f8cbb883fe6e89aee72ef18858e5372056f95d6896c713f813afd1fb0c0ccfe34e19e39506ea33772bd0b791138bffc9fac4892d8efe29fc8d072ed69b7ce49f731bf3c9fe1131a5df38d60c7f427b18d6d4fb0c75624ef355787e6847185fb2b962a4d7d8078bf297e71b67c455c4e339f21bfa2ed25b823f85dc44fface469c6fc99456c51fa0dcd38ff88d806cf117fa21abd2fd1443c8944bc42fc447c8b5c17f1b6714bec71cc47a13d14a33f70007d234eeb2925ba3faf52fa72cde88f8f886b747c464cf95bc9f6df2a57e8fdad890f369983fd4825b053c578b6b44f6ca27fd3ec1087147f2f15c3bf8d3ad8b542b4c7369897b1fee29f11537eea325e5ac5f22fda47a44ff41f315f50ba24b611ff5b9c38a4f29c6896e969e2fe15315c81bfafc02ca4e79b9a717f9b38c271e346b34cbf71af19ed6d0dacf25397ed8f5515f116fd4962c742f9195db06b87f08723e210fdd912f25315151efdc3013147fa7c4733fa5f7d624a3ff335a3ffc5c0227df2b8013de5005bfadb086c7b989f6ee2fe35559e464531c59b0658e829fddf9811fba16cbf9a163147fd5a9f80fd10f122206601ca3390f1c7121d2ecc5f36f78823f2a70d58df7f461ce1f98db16679bf04f9353dea1fcc43705045fd315c30a3f9735622f6a06730d38cfa86fb890439481faeb754f9b49a60af06fd667760317cc07cd321583c0ffd9d1631a3f92ad95fb26c917fec6f738969fec6b08979007f863fd95e9963fc2efb0b9653acd0161cc1df9dc264fa12b0482ff41b82dd30c4fe07f8afe39928df39f4757c934bffe578be5b982caf08ec849e2cffe61d7184f208911ed7ad32c4db09313dcf981247e05919ec57503f47882f6e40f13098130718cf0407605621fd0ce2aa89f11dea8f578c88657c83bf7985c9eb911fd11ff4a43ead5bc5e8ff96fac421e6e346a80f9e6f53fb8be7798147e9db2766a84f932931c77a160bc02abd4bc44bbf12d0fbdea8ffbe5048a68f411fdf71317f3b3f25663ee203ca5ff4b7a87c0f886bd47f9f13bb545f73b0570e657a8d01713542ff6d411c86d87f01fff3557ec7d7c40ee2f9d223a6f99900fee607ae85f15d8fd8c7fa4940e917e583f907461c62fda48ffa179815cc1777905ea1b689f135ea63a0ca233807bb35ec7730326286fe7e17fe177815cc6f07486f20d283fe029889ee19c6f7286f26ba43389e127ba85f2d942757fe5d2276cb983f0cf688ab949e536213fedc222e1660a47f2c880394df1af137ac38783f7d09ff098b190b793fe447f457301f6cc03f43cf8eb07f634d1cd17814fe188aee1cce7f20f6b09e6eb4c1a2fc65fa57f0c7c8a4f5df08e51b1526db0ff843e486d83f6120de461ef5670df847e49b0ec6df0362dbc67ad88162c49795ccbfadf7b31b65b0c81ffcc7017b21d6934b07c411fa23cb3db05f45fbd0ba21ae21fe2f653cb32b9683f51063047603f4a78d26588403f4af1f886dc46be310ec57501f4b17c455e46f79406c63bc539a110736e68f919e6a85be6fd0b3c062c482f59c3ed80ab17ecd57e0c2e4fde87cd7c57c6fbfa718f3a3c69ad8a7f60ce555f57cc49bd93558d45779bf565731cabf5121f6e13f13a9975db322a42774c185c9f88ef36ba2bf8ff6f794b88afae3578943940f0bc19e87f578e304ecd37afd4ac643db14f945f99f83c5fda47e255c2fda6f9cdf260eca91cc4f07e52d3a34d8df1520bd96f037b4472b621fedcb2802339affaf23bd4270e8336f13d3febc0ed227128cfa51af834d9aef1da2bc6de15f32fd510e2efe93f9cfc0ae89e7f99c98d6639b35628ab7468738427b33ad2bc67c17a3eb7dd26389fc3885c9e353b08887f278ab4c6ca3bdf7e1cf8e5fc1f5fe397115f57303ff16cd07e24d8afbb985493d1ac40cf3b98d23b0685f303f32067be4ff9b633033d13fab432faf30995fd47fd11e617dbeb52466f0e741091c58b47e2ee3991d1426f38bfa2cba07f0b7061df7c8dffd3531f9e3c00007f4be4b8bae0fa2481e4f64ffd26685c9fb4fc02e43bc6bc0df99b83ffaff48af682f103fc6d08b8bfe33f6f3a1bc429142a4ff9438447d68a07e87a27d807fa37e4415fa5e468afc4762fc239fdff18923acc72c509f23bb62a3ff03ff8bdc089cc8fc3be5c2e4f131d8a5f8d9907a3b1521a83c7f3d03abfe57473edfa9161b0e657ce881c51364f984537061b23c5660af86fe69fd98d8a3f635018bea28fdafef81830ae61b1a75c5681f1307cc1cccefb691de5a95be6fd03e03d7ca58ef5b1d800b93c703b0ea0f6d4c62df477fb943ccb1fe36f0c12a3dcd0698f1485e9fc8fea263562bd82f31211601515e9fde82ad88f6131d820b93f5b50b6635f44f96325e15cb85885f1d036c5611bfda327e8bc68bda8b4619acea5b1be5e7e8f36f88697cdf7615e378bc0f2efe93ed03f2e788fe8d4c7f57b647227cf8186fa6f007b730193f657beb78d51af2bfbe24b6b0ffb70dbd3cf5bcf106ec58181f8427c41edad3107a78818bf1693325a6f1c154ce1739be5dc3fcca0acff71d6adfd20e3147ff6e99837d8a1f2da4cf0fca185ffbf76016a1fd0891dea030c977e080c67f6d595f1d668901957c3ef4648515bc87fac13c8ef9a66506f6399edfc0f359c0d0dfaecbfea2c30b93e50d3d45ea315fd9b588e97e1d705829633ea60eff0e1dda4fd85d82bdc8c7fe51d4b7303043f9fc8e6cdf9ca8ccd1beb5e1af9159c3fe800df213891602eb45c86fe450fbdf85fe91ba7f3802071ecaa389fc46cca6f658e6c715a9c5f33a26b8d8802d9f7f05b642c4af410b5c987c5e0656cfdbc8f6c5d5fb1b3709b187fa9234c08549ff76c15ec5c77ed0142cfafb38be048bf1a12c9fb8ab19fd1903cc5df48786b23eb8d52a7d6f6aed10537dddd0f1c264fe72307342ec4794e389a235467b9cb61463ff5972a019fb6fc76016613ebe5e03731bfdd9ae8cbfae590b317e5ac760b382f5b40eae37458dc17ef81258f53f5a48af199623f9bc31f428fa4f327d1d5b31e6d3dbe760d5de2e2fc08e83f10d3f05bbb49fb17f0816e35bbc4f04fdc48009ebd10da618f999cb78efdad588de079a806bb4dfb0d306bb0ced4d674d2c0492f7477a6c359edec4c411c6237da4dfe6f47d8a11f2e7a8e745737061f2fe87c41ef109b14fef075c1007385e47793ac50294d413e5ed04343fe65f82b98ffec50af5430888f5f3f631d862587f6ea13c5c2fc478a2e983457b81fc0e88693fe9a2491c61ff5802fff5d47c6917feef9965f84bbb4b4ceba13da4d72b4cfac30acccb580f1cdc127b688fdbc88fafe225477afdc2a47fb7157b785f2a220eb15fb1d3d78cf536ba9f68ef31bfd425e618fff4a760915fac5754c0a23cb1be05ff0a547fa087f20a0a93cfbb2466d41f437905dc87ffad901e269a2be88df8c05c0ffd87ce19b18ff8d2392566e40fe79ae5f58343cdd89ff8006601e62f2688878c577cbcdf8178c6cd0af4e9c01fb8d003cf3f22f6c91f0f88c9ff3a43628ee7f113cd583fd8037b35f487d38098613f5bcf0307b43ec3e9fe4188f13fef809983fe5f3226a6f8d391fd09a12683ff743ac421d5d78666ccc7999ad1bfac2bc6fc5b6701f6caa8dfcd8498c6d74b944f28e22bc6270e3147f9f6a05f243a68327fdd5831a517e51115252a79401c52fa9b9ae1af3de208e90d279ae1df23b0482fe2e5ad62e427427d8818cd3f24a85f11a7fa38ef12fb68af97526faf2cfa93d80f11824d7affad1b69c6fc1627a6f7e13a0958a41fef13669a91bfae66e8c388297f9d8d62d22306abfc75b866bc8f9829a6f95397d8c5fcd8d207735aefe9e07845747f31ff33039bf4bdb8ce03d8aaa27fd1ba06bbb4bfa067800b93e54bf7f34c8c975bc84fc577d19fe57be080d6afa21330a3f7f35294678557114f3b523faf5aa1f739fbb87f35a8a2ffbb46faaaac8cf16cd421f66cbccf85f2a87213f3cf25a4bfd8a08bf88ee7d75c07e3f115ee2737e4c9fb69c6fa10df07071ceba531f4a8b132fa971bdcbfc639fc271d80439a2fecc8feac08f7b45eb9c0f96661f2fca6628c8726c8afdc6020dbb73638e094df25588cc7a4ffac6ce210eded067a9bbc82fef67c4d6c42ff58f667e4f43b9e077fb5b885f5d9e60138ac20beb78e887d945f82f2b1dd00fdd374022e4c5e7fa818e3a316f26f8bf247f9c8fe991c7ec8f4f5e1cfa2c385f74523a447845fb4e7bd11d80fb05faa87fb0bef86debd2e7184f584fe101c56b0dfa6d7d60cff96e30fcf13fd29ccefa3fce47fb27d823f79cc0d31bfb920f6b07ed6477e3d713fec37457a7d9bc37f99032eace011fccd673eaeefc878ef05357adf6a8ef20c4c1bfbdb3ad02750f3052d3c4fb49f985f0d91ffc0a3f745e22bc5588f68a27c033fc278bd5e02731a7ff58ec1c23f511fdac416f4692e886de89dc21f5961f2f9481f63b43e925ae0d0c2fdead08b7b55f447c38098c65321ca9f337abfa881f2e7218f305f2bdb2b2fb4e9fdb606ca2b14115a323f037bf4fe4482f48621bd7fdc3f26f6496fd95ff12235be49105fa2c224ef2b46f9d551bfa2a086f9d55e0b2cd28bf501c49748f4c7109f909e28a4f981818cdf7ed9f231de6a386097a33ef44ec08cc6df1b3a5fd45fb43732befa221ed3feed4bb015e1fd8bd91ed8a1f69437c03eed1f0b3330ab61bc11f68869fcb127e3835ff538e269d7d18cfae0810b93f531558c7814363463fd2f023313e5318ac1dcc7f1818c877ecd29633f093f021726ef3f22b6b07e63e07935568b903ee9bfbe185fd1fef206317defb15b057b8cf233270ed13f5e86e0c264fa9b8a91bed60accfc08f3a3b2fefb720157ea750a2e4c32d26f851ee2793a240eb17ede95ed9f6f9b35b4af734e4cefbf4d917edbb6717d6c113bd8bf54a7f31dda0fd01d83457e64fde8cfc03ebdafc11f14a3fcba1eb103fdf602cd785ff01a1cd6301f92dac411ea5b57b617e2ec0ae6471a37c436d61b9945eca07decdac42e9e37c88939f90fca4bf416d19fefc2ffc4f80b7a76db609fe6a7ba15c5f0e7ee3db18dfb75af35e3fd9705b1437ca659ea11ce885d70f744b38c0f5c3dcf45f90dc6c421caabd1078bf614fd0fe44f0c37b1fede35c13a7d179a919e73cd180fde11abf44e885d3a7eaa19ef972e883dbc3f13235e783c427d6da13c3dd55ea7156206ffed427f516150de9323e200fbf7bad0d717e9811e7bc42ee26bf75631a5774aec517abbc43ed2cb5ccdd8ff1029c67a45b7451c90ff743463fe16f1cf170320999e88d2135a582f8df635cbeba343621bf53f6e13bb987fe9436f51bbb19fa98df303f57ed012f12770e8fd9d36ea5fd1decaf2edd271adcf8a98f2cb8f89038ce7ba4d6286e31d47b32cefe800acd2dbeb10d37ea13ef40f22da2fb6417a98a8beb83fe22953cfef1e13d3fe946e83989edfad6b46ff68ae19fb4ff17cc6cb11be3f82fc15db95c0745c9437d66726c43ed683d38438c0f87400ff13bd21bccf1da33e71c7417b15e2f9bc30991ed427d1fe237ea665e288be3782f4877605e3b17a42ccd09ec4d0332c4cde7f5f31d63f46684f44f702fbfbfb681f4315af97a8df91d01ff391684f229fd6ffe24bc5b85f72a819fb75d1be462c8c703efc3b0acb989f88d7c43ee29f2ffb6b41d909317eaddf83bd0aca337e20a6e3d1185c98cc4f0216dd258ca78ec1a145fd9b257188f5b3997c7e5071220bfdaf05b830c9b87f85d3fbcf6142ec82d32a7180fe5c7d9f380ce1cf5db0783efa4323e210f3b90d59fec5ebac98bf6cd7c1e20e184fdd13dbb43fc3047313fb2552ba9ed3787a85f414af73c27fc6c4f4bc198ed72cfafe738af4d5fc0ac627fc1c1cd0f82a39568cf145d807f332fabbbd3d621be3ebf52db187f1413d0687b49fa79583a32afab30d5733da5ba4d72c4c3e6f0856cf4ba6e0b082f9b324270ee13f299e674615ac074f903ecb61d8efc38ec085c9fc9a8a91bfc18498de2f0de16f16e718ff8655e210dcc3f36c87de376e227da23f81fd48dc0207f4fe50d8564ccf1b117bc8ef06fe63f32adad33ed22f4613e8df0e0ec085c9fcb41463ff6038007313fdf7de3e31bdafdf3bd08cf76de6c43ec5b78098f64336915f27a2f981926c0f0357ad9f0e507f5ce13f883706b8b0828312985bd8cfc165fb2f8767181f3514637f5872a419fd79f8a7184d60bd6d4cd78726b883f488ee11edf783bfca0647a63f047386f9ed39e28bafae0fcbc434de4fa06760d3fccf80d8afd17c19f227ff93d757c02195e7a8ab18f5738078c16cfa7d240de8c33c6a2f1a1b70e0613e7e794e1ca07cdb63c5d80f947ac48ce2ed8962b4c729fc99097fc5fa28ea2b0bcb185fb6f07ceef9b85f7206f6693cce6ae0c2647eab8a31bfd5873f874e15edcd9a11d37e935607ecd37a7d739fd847ff38855e61f1c12bf9bc43e210ed0fab28467ee23bcdf01f0ee621fa5b3cd48cf88bf2883c07fd070efda280daa3a8a718f74be0ff5158c3fac42827b6309fd097f59f957d87f68f2e89293f61042e4c3e9f8195fec311b1075ecbe733317ac0fbaed11acce8fdcb90130b93fa0f886dc4d3129dcf23acf737a43f32313ea5f7cfeae0c2647ddf80b94de371e9ef62f45bc1fc73e8810b93e5714a6cd3fa709bd8a7fddf57e0b086fef4e280d881de63d91f60a657c57cb7ff406c237e375bc41ced5b1fe9358b0da052af26b830c9b966f44ff03c933b88976de45f74a722bc6fb12476309fc0a43f308bd1fbe07ca219fb39eec0a189f1f41ad7db2ec7fcd806e917a317b4df9c8e337abf2b7214d3fc0bca4b840ff48fc687c42e8e4fe12f4e40e32b86fcc8057b59fef017117fd15e6cee8823b49f63f88feba8ef295b60d13f42bc86ffb901bd8f3349c18cf61b45756217f1957515e3f884ee177a68bf5617c401c6ff7d19af99e7ba980f1f4cc18ce275d4d02ccb8fcf1523ff838cd8c7f1f64a31bd3f8dfc15f11ebf6fa549eca1be4d6e88293d63e8ebbbf4fd85c119317d3fb35405fb2ef4eacdc001bd7f590fc0e28e689f6d627a3f9bdd29a6f5a910cc19e27f4fc64b0115c47f0ebd658096f7eb28c6fedce618cc6b680fa743b0ea1f71466ca27de791668c87907fe6478847ad7bb0d01bf5057acbffe4f36fc1a239c37e4ba48fbb3ebd5f8aface7d0ff3b33d3c8f332aafe48e98d3fe28c41f2eea3ff627de12db886f2dc4071ed9e8cfad90ded07330ff989e8345f713ed87e2809e8ff208035a3fe9239e848cde7f647b8a519eec5eb3bc5f0afdc390d6737ad03f72e9fb68c939317d8f21dd23a6efb724486fc4e87dc24602d6edb91c1f146fa7607f46ff869863fd77c014d3fcd82dd80de8fb9f7b60af067f193c105b986f88cbc436e2cfec1eec57b03f7dbc06337a9f2ea6fb717abf91cf34cbfc34bae0c8a1feb58c2fbcf8f52c285f87d8a1fdc9c76075fe00d7573d13e383d101b18df5d7910bf66be85fcf9b9a311e1d105be89fad3dcdf8fe259d2f22a2d49727e0c2643ca968c6fa74091c72b497935bc5d8dfd3c3f3446f8d7e5f0bf4293ef080f9a2b5663c7f9f98e6c352e4bf169818dfad8660d19ee2fb5c47e0c2e4f532be715374a865f96f7a60dfa5ef636e8869bffada020765ccbf34915e53e40ffd9b05b149f5b9ac197ad3f1b086f8d958128b2e8f4c0fd8b222da6f07bd8af52c7c7ff11aec9bd83f18c25fadc224b734a3fdbf028bfa8ef9265c6f8b7083f1f10a6c46988f4d513eb647bf7f628ef2b17d8bbe6774a398be4f7147cc311e6f8dc1a2ba60bc79464cef0b37e12fb6f068cc5f86c436da3bd6d18cef2dc09fec30c47ea9b84e1ca17fc5913f47a57f80eb1d9fde5f49e87860a37fc24ec185c9f24dc1a27f87f7611bc43ed2c7a1afabcaab0ffd5cd7c4fc472302fb1efa6ff323621ff397a3297180f1fb322566f0df060707f43e4388f2951b2c647adb8ad17f8cf571ac97063e7180f6af1980430bf95919c411caaf83f2f0d4fea33afcc1f3197dff15e5eb05349eea414f8f95a15f724fec60fc17d2f59cc63f6b3ccf53cf8b519e5e54a1f648b607a2b952e30fa4dff723ec57de20fe89e2a2fdc45530a7f70fe25bc5d8cfd3ef83c32aeaf3ba434ced4762113bd85f14c3ff7c911ecc87a3fc03dbc27cc3067a8bfe00de471996884df817477ae5004bd6a74c31d2d3467c168478d644fd0f2217f198e338b302da9f88fac7ec08fb9b233c8fb916edaf40f932bf82f1cd10fab2c0417b92a23cc5e811feb3de28c6fc4a40e7abf8d0bf226688c7acac18e96fc29f99e80fa0ff8afac2a232bdff8378201e80f59a16eecf4584c17a8341ccf1be5a09e929fa1b882ff7c426d5bf29b18dfe48cbd68cf52bba5fe8809b25cdf0f7be66f4b7c062384ff34bd027e4f4be6b7cad18fb7bda88b7a1e81fe07b863938a2f96286f3239ff62fc468cfa22044fbd23a04336a4f129f9863bd3d857f459cf65bb6d1be4422bd787e4933fa338cd8457936568a91bf769fd8c3f9b1ec3f87c5ef93c1feac0c6c517fa37f0b16031cac0737c1be85f97e76a519fbd72d70c0d07f1bb4c12a5e96eac40ce5c74c7061d27f2dcdd8fff8781cef577789697f66e39e98f2d7a0f489fc81d7c401714bb3bcbe2ddbffb0e245982f19f7c101477f6779036655cc2faecb8a693e99ce17fe8bf77b62e208e39770092e4ce6c7d62c8fc71eb107bdda1b62067f1a8fc151057a27487fd5a4fdef8d2a98d1fb7911ee57e5b47f273a051726b9ac19fee06b86fe01317d7fa2192b46fddbd071959e1eb8a6be6fc7505eb522a0c9f601fe54e3f4bda2f53538a4f78d8d8898de678c6a9aa1ef03b189fda5a52eb185f4b41c6207fdf3363d4fa40fedafecbf85c5eb06e031317d5fa70f7d4c559ef13138a0f5830d9e673297be57bd22f6c8bf917f93d3f82b1e107b88b7831931b53feb1631adbf18285fb330e92f079af1be99454cfb7353193f43cb34b13e13f9c494fe04f5cd52fb8fd92558e527e160d12260bf2323a6f59f35ea83f066ea0fe6c416e6837ba1667cdf6641ecd2fc2add2faac23f38f416a325ec37ebdf81dd32f6a32717c4f47da3a403f6e87bd34997b84adf9b75c1223ea23f6580b99adf43fd972f30c9fc3f32be178efa628bf461fc85fc382ebd5f5d47fd707805f393fd6b628abf6b3a5f4438f87f9db84af3ef16b183e7451bcd58ef8d35e3fba436b14be7b7887df8037f64a497eeafd2dfca884dcc87a4d0a3f85c03e64350bf5cb57f758478ea72ea0fcc6e886b34de49894df8cf3821b6a0d7725f31ce1fdc11db38debc2676515e29da1757d418a97f6f4e6cd178b544eca2beb37dcde81fc6c43ef44c283fc584b1d40bfee046343ec9c7c436eddf40fdf61c13f3c129eeefb936beff1d233e7a3eed775e22bd9e1891e0fd119398faa7f329b18ffda5fc5231ea77ef0caceaf37a8f98e697d8ad66c4e78166ec4feb1187d45ea13c3da137d6b33c6295df9058e517f1a9d87e827886f4f8a2ff81fe18fcc3e701e2d9ea4c31bd6f76a098e64b911ed13fa6f87c454cf5ab1f11d3f70ffafbc43ef2c7ce35a37c9ac401f5a733cdf8fe2058341f587f5f578939e6532777c411da2b86f811a8f4442b62da7fd65b1353fd49af35c39f5c624a4f72ad59a6f77ca619e3f3aa667c3f6942acd697e87ea23e221ee0f94c8d0f22d43726e21be6e3ef8923ece719435f26da077c4f08ed112b7a28b2bd60c40cf99fa3fe30f5bc01fa23dca5eff1f9f037517c983f1cc1dfb9885fd83f7b494cefb3b333620e7f8a868a311ec9d13e73311ec1f784bac44184f979947f68db58af8ff0fc3070e9fb8ac86fb19d11fb3f6b8ad13f99c13fc290be373a3f23aee1fa78464cefdff19a62a4af85f21084f9103f2266485f0c7f89029ff63f20de8bde1aca636e69c67a609d3842ff63037f8e221a1f373d62ba7f4bd6f7a82c5a44cc87ae35e3fb5235622a8fc1b1668cef27c41ec697e129b830f9bc36b187f517bf4e4ccfefc9781d55c4801bfa05606662fcdc447a44ef13f1693527a6f9fb418d98beafd7b415d3fc019d5f98bc7f5f33be075921f6d0fe37ce89297d299e5fb5e97b0bfd0dd865b49fe31ecc3cfa3edf0158f428f0bd8833626a1fa61931c3fcdcaa0b8e68fc3c5b6ac6f710ee88957e27c40cfb5352391e8b6a6e84ef5b348845feb1ff70421c62be6984fcd7225abf6b0d15537c514ce3d748c6ebc854f3d921f26f8af135e64f23705441fb391c2a46f98f73cde87fda9ab15e5323a678bd996ac6fbfbf4fcc2e4f3c6c4345ee7323e4596daffb7811e5644df1f9b2e8955ffdc2756dfe3c935637d7a406ca1fc6727c4f4bc669798a3fc2319df225bb5a74df8b7e8af211ed77d6293f4b8d38cfda303620bf57579af18f5671a6ac6fb3a6dcd78df45dd9fbe57b2619af1fb432e35e37b5b5c33f283faec44b47fb46712d3fc42b8a719e37be8ef3a01daeb1efcc9f54dbcaf1c22ffae1abf257bc435ea1fde129bb41f10e9932f00c9ebbb9ad1dea23e7aaabfd56a81235abf69ce35e3fbb80d620fd74fe69a319f3723a6f1751ff5dbe7f43d1f8ef22fda77ec87ba23a6f66589fcc90d65b23c7ac474bfb4a619ed579b98633f4a0ffa04a683f5668efb07aafe3747c4947f3e250e70fd64a619fb99503ec57670e877414ce3ab1ef466a23f89f7052e891decd7efa3bc99e7227e4474be4a4f3b22f6913fbf4d4cf98d0f8819d29382b9eaaff6105fb96fc33f7c9457d1fe62bc582566f47e4a4f33d27341cc319fd89a12d3febc3eca3b74cbf87e7ebf436ce1f9fd36b187efdff6e1dfa147bf1fb05fd58cf5881e31fd7e9d414a4cbf3fa947c7fd2af2d3a3e37e0ddcaf10537de895893d7affa945ccc0bd07706061bdaf77474cefcff4ee8943ec7fe837c18cf66336e97a555ead9898debf60ea7888f6ac616ac67e2bd97f8ca21afd3e9bde15d8a6f7a352f87bc4e8fb7206e28dfcafe0f3d9bfd18c92e1ffe934bc99be80fe660637422332e2c76350c54876f69d4cd69dc44877f69d4caad233fa3bfb4e265519ecec7b995465f8c43263648c8ddc98e87f9918d36767ecec6f37a9caec89cd8d85b13456c6dad83cfbf79dfd832655a93fb186d1345a46dbe818dd67ffbeb37fd0a42a7bdaf68d03e3d038328e8d13e3d4387b726467ffa04955cea55d1897c695716ddc18b7c69d716f3c1865a36254e9e8ce7ebff9464dd896235215539865d88663b88657324aa5925f0a4aacc44b61292ac5f2f8ce7ebff9a5a4946c3b52a8524a4bbd52bf34280d4b5969246c5cca8de3d24428342dcd4af3d2429cb1b3df6e4295a5b055695dda94eaa546a9596a95daa54ea92b55d92bed970e4a87c66de94828725c3a299d0a45ce4ae7a2ce1c962e4a97e28c9dfd7613aa5c09bb2edd946e4b77a5fbd243a95caa94aa25bc4d6396ac926ddc959c922b6b4b5ef27c7189ef8b3f8b77f8b9386367bfdd0c5f6ea088fcd84ffcd4eff97d7f2068e867720d60e48f8d233f2f1dfb137f5ab4f5fecc9f1bc7fec25ffa2ba1cc5a9cb1b3df6e42958db0badff09b7ecb6f8b3f3b7ed7dff3f7a52a07fea17f24eac7b150e3c43f153ae4862714392b0d8b9ffd7371c6ce7ebb09552e845dfa57feb57fe3df8a3feffc7bff01fbb9fc8a5ff56bc56e6c514b7c7f5a1a8b56e5dc5f9672a1892dbfd353d9d9ef37a378c1dc0b8ca078373f0898f8990761100571a14a900469d00bfac120180659300ac6411e4c826929f7ed6016cc8385386367bfdf96d256c13ad804f5a0217e6e06ada01d6ca42a9da01bec05fbc1417028a2d859290b8e7c33380e4e82d3e02c380f2ec4193bfbfd7629ed2ab80e6e82dbe02eb80f1e827250c16fd00d6a811958811d38811b78cc60c5dbc90163c52b382c62314bf0f5969dfd5326f705a4c27aaccf066cc83236626396b3099bb2199bb3853892eeec9f35a9ca7267dfcba42aab9d7d2f93aaac77f6bd4caab2d9d9f7b27fef2ebd9f6c3b55bea3ed54f98ef6a80aabb3fa9f4ecdefb59f9ba3a7aa88ff37fe747a7ea7fddc1c3d8d60acb13d0facc95aaccd3aaccbf6d8fe87cbe4801db22361c7ece44fe5eeb51cfd9d6644ec54fcff4c3cfdfc93a9bd6097ec8a5db39b97edcab65acf6ed91dbb670fc2caacc26edfbd7b95d5d83933c5bd2c663387b942218f1bff74f9bc9e23182fbe7ee9735ffc59fac89d8a4fb7725ebcc0cb83d7cf326276c8635166559e084b79224ae25d7d788ff7f9800f79c6477cfcab2acf6bbdd280e77cc2a7ec81cff8fc9dfb2f0cdff0f992aff89a6f8c00c6ebbcf1b1bcff6edb1ec7d83937441a9bec842f8bff73e3ed92e32ddee61ddee57b7c9f1f889fdabcf5caf36ef9213fe2c7fc849ff2337e2e34bae08b77ee7ec9aff835bfe1b7fc4ed8fdaf7db0e7b59e3ff032fd54e155a14a8dbfa33cb744ba6cee08255cee8546580afd4217560ddff0b0bf55975fe218bb2d3e0929fc78215f15673c0da390bd1e05c2384cc234ec85fd70206c1866e1281c87f12b67e7ec249c84d37016cec345b83458988b7f7bb5d4782f5c85eb7013d695bdd7070b1b6133145e11b6c34ed80df7782ddc0f0fde2a83f0d0f0c3235547c263fafb243ce5c7fa9cb3f03cbc082fc3abbf558d576397882987428930bc9611ac1adef0431175cd57f3741bde85f7e14358965f4c2a175fa108cd70ab8aecbcf8264df125155113cf432f32a42ecbd07aedee11de2b65f2ed47fd469fcac3b69a1e45511c25511af5a27e34888651168dde2b8d682c225833caa34934e54e34138a84861f3d897cd1225a8a3f57d1fad57b6cde7dcabb67bcd60763e7513d6a8437ac1a35d1b2703fbc11ff56dfeecf512b6a479da81bed45fbd1417428ec283a8e4ec4bf6e8962611e9db2a3e82c3a6707d145742914bf10edea69b87ce5ee57d1757413dd4677a28ceec4dfb7d1fd7b7db0e8212a4795a81ad58aaf604476e4146ffbbe571eb151b42dca4211d3e2676d4aecc74fa259cc621e877114cb8860047112a7712feecb63837818675bcf18c5e3388f27f1f40d5db6f6c144a9d545bcaa86d7f12c9e1bb1d0e49a155f39a847a75b73b38897f12a5ec79bb81e378435e356dc8e3b71375e6cf385782f9c733bde17edfc83e1c707ec3632e2c3f868bb2af1717c129fc667c2cec5d9e7f185e1bfd7078b2fe3abf83ab2e39bf896b5e3bbf83e7e88cb71e56d55441c8da20b11150ee36a5c0ba3d87c91122bb663277663a96f622442b3c44f029479c204f1244c22f1779c24dbcf109c263df167ffedb4fc1ac744cb7e105e0bbb8967c920191a2cc98426a7517d7b3f311925e3244f26c93499c99ee843324f16c93259255be2063f8bc69191ac934d6817aa4417493d1a278dc8d8dedb499a492b69279da42b6c0f7efc5e1f4c5cb59f1c2487c951729c9c24a7c959729e5c2497c9953872fd862e61722322c538b94dee44abf7cb99c97df2909413a96e524d6ad24c2a731981133b711237f152e3b533d252eaa741cade53e5971c65227e0955d8293b13aa085d445d3e126e60a77cdb1dd2308dd2384dd234eda1d4d27e3a4887699686db3c321da5e3689ce6f15e11c178924ed2693ae31761be357dd7e93c5da4cb7495aed38dbc7bfdbd3e984c55236da6adb49d76d26eba97eea707e9617a941e6f7bc6a3450d9e44f5a2b57badcd4d4f5219314476cf1eff55bdf19c9ea717e9657af5c619d7e94d7a9bdebd9d8e5f7314e67c59d40df17fa14a588cf94ee32311610eb6975b7a9f3ea4e5b49256d31aa962a6566aa74e7abfed7c71bf637e9cba5183dda65ecfe8957a3e136dfff6f8c86e7a418f49e3d0e4695d797bd6a827bca217f5e25ed24b85f57afddea0377cbb348ade98e1f7b22d771bc5e25f7be39e2c85dea427db86deb332efcd7b8bdeb2b77aed8cdeba27dafb5ebdf7eae8fdb51cb1f3e44ef6c0642d132d8afc2fb94beeb647fe5eb3d7eab57b9d5eb7b7d7db1776d03bec1df58e7b27bde6b6bb8b3ed84defb4570a83e436aef186f8b35ae814ef6dbb7fef2cbaee9df72e7a97b2b4ae7ad769fd73f360bd9bde6defae77df7be8957b955eb5577bebece4b6678af6cbdc721fab67f79c9edb93ed4adfe897fa7e3fe8b3a7aa887fe7fd107564db19fda81ff7937edaefbdaeca6b3912b5a5c95311b5643b5ff4c0844ecded35453eabdf1ff487fdac3fea8f858dfa797fd29ff6b7b668bc94723132f59813cdd39c59fd1973432ec647f3fe7c7b84ec2ffacbfeaabf36fcfe46fc2dec23f360cfee50ef37facd7eabdfee77faddfede5be7a62e2fc507fc0fcedbbe9e23a184177a428b45c8840f9f145ffa7b23d7fbfd83fe61ffa87fdc3fe99ff6cffae7fd0bf12f5be7048b36aa3fe3e7e2cf4b56eb0bdf6407fdabe8341d89585edd565bfad7fd9bfe6dffae7f2ffe2fed23f3602feef1d02ff72bfd6abfd637fbaf8e8c0a0b0343743c7a7ff8bb1d5b67f6ced9ad18a93445f22ee2229162dc22fee5d5d1373befdb7da7eff6bd8131280d7cf193d3b75f3bbf985f2bc68c51335c8ab18a55cce688def1a9e861bc326619040336e0837010c1deef836db9472c3a2ee9a037e80f066f9d27fce42ee583775a9fbf6a6a1601b64d959739127dc3a668914d5615230b3bb4455da9a6dc88c49872eb689d978c488c3417836c301a8c07f96032988abe415594f39b5e59c432264607af47c627653a1bcc078bc172b012b6fc481f6ccb3dd683cda03e680cb6b4764f2d9d0c5ac996d6fef7da5b9a6ccf51e1bbf87a6fd4141e2d7f121efe8aefb3735e7ccb578cd9c365ca531e2ec3a51147cdd7af50c64be29a0f685258680dda83cea03bd81becff3bd622b76bf27373f46f598bfc58ecfa29f6d93ed8cfb29f9aa3dfb5c765703038dcd91bf6e6eac7dfa6caa1c177f6ba0d0e77aa7c3ffba3aa943e60fe9f2ea1ff4255fc0fd81f2fa33fa14acaa3d3d7c6a9ff942a62fc78944e7efdf9bf571576908e922c7a67dcfdf7aa32382aacd0a2d0a4b06daa0c8e07278353a2e0c99fff3a1b1cf64e07429770f9a7eb0a7479d4678b2a6783f3c1c57f872ab1d93b15f565eb5cfe3fa5caa32ebf68a255195c0eae06d7839bc1ed7f852a257ec69b1f9b15fc3b5bfbadf5e4a92a77837bf1e7c3a0bc53e51bd595caa02afeac0dcc81b553e59f50e5fd7665600f9c41f1bbc8fc81373476aafc13aabcdf071b161f54c24fc190ed54f9982af141322876b445f9900fc361348cb18a318c87c9301df69edbe7c72bc3fe70403f0d87d970f46f5765381ee6c3c970aa4b71369c0f17c3e5cb922cec43aaac86eba17ee761581f367ebdcf6e6cffae2acd616bd81e76b47777877bc3fde1c19755391c1e0d8fb5c627c3d39d2a5f50653c3c1b9e8bda72a14bf2727835bcfeb22a37c35b5d53ee86f7c3875755f98826ffbdaa94879561f5496da90dcda135b4bfa2cad019baaaa6883b7999b14ddddd4cfedb0655b252e66741c6a82c8f339e8559f41555b2384b9426599af5b2fe4e95cfdbe0301b64c32ccb46d938cb75794eb26936cbe65f5065a1b415775966ab6d9aec5479cf842a6ba1ca26ab678dac89d8338cb356d6162dfe2f31ec03aae8389875b3bd6c7fa7ca57ac50657826eacac130cc0eb3236aefe3ec383bc97ee93dbdaf0a77754d39cbceb76bb253e53d13aa5c64974295abec3abbc974ef29bbcbee85a72fff822a0f5979a7cad78c54a90855aa592d6b67a61ab5889fcb99f5555544fcb23367a7cad74caae28a3ed841e68d8c5169e4ab514b763b0a46eccbaa9c8df8e375a370148de251324a619f5765d81ff5f0d3a83f1a0c472f8e6f9b7ff9c1b33183c3d110aa0c2d51376e869dc71836ca46a3e731ec13aa3c0ca9a51f8d47f9cb91e11754298d26f8693495b393cf4d2a10d57ffdb79f69852aa3d9683e5a6462c4375a8e562a868dd6a3cda83e6a7c4595613c6a8e5aa449fbd7f1fae75519d8a3cea85bfc34da1bed8b3f0f4687a3a3d1f1e8e48902f2cfd1e9e86c743ebaf817a8722955a98eae46d7d9911a4b8e6e46b7a3bbafa892b111cdb4fc5a4fbea64ab1ea357a10655e1e554655f1774d2a608eac5f54b1478ef8d3fde1aa78852a63635c1afbe360381feb51e0988ff8f311fe475519876379dd38de3eb7f51555c6c938157ff6b0423cee8f07e321f7c6d94b55c6a3f158fc99ff7455c693f1743c139af8e3f9888f177a3e6c33ca86ab2fa9b21cfb529595d261bc1e6fc6f57103f6a5ba7239b81a37c72deca618b7c79d2765ffaf5365dc1db6a08ae81b1b5938de7b6c59c6fbe383a7bde38fa952b42ad94caa72a855391a1f3fdad77ac6e393f1e9f88c7e3e1f5f883f2fb7a87235be167fdefc0b54b9cdea4293eaf86e7435be576b56c3e3f1c338f8bc2a59775c1eca7ef1b8a255a9fe06556a8393b1493f5b637bec8cdd2daa78b9313acf4b3f5b95dc872ac3c3c2f2209baa59ca619cb3acf6747de48375e522a7b14a1e2a55f2e8afabf2df63852a799c27793abe2b2cefe5fd8cab96251f64e7f9f0b3aae4593e2255c65a957ca7cac74daa321956f269a1896857caf92c9feb15de5a36ce179f8e600f6aad6ba7cad74ca8b294aaac842246be1ecfb330df8cd6aabdcfeb79e3719de58375a599b776aafc15832a793b5fe5eb7c9d5d8fe77927efeaf6be9befe5fb9f5345b44607f9e14e95bf625295a3fc383fc9ae61f9697e969fab5e587e2174bafc8c2a5937bf52eb653b55be664295ebfc46a8725b28329e8fe7c37094a9f1bdf0fbbb91f1b9762563f9bd3a7fa7cad74cabf2502852581ee4e55ccfbae495bcfab908961d657a4633af6955cc9d2a1f37a98a95db50252b8b3e9833bcca5ddd37f646cbc7d9fc8fa8323154bf78d89be87d78137fa7cac76d7038090a55b251a1c8707fb83f61233ed123964938893e17c126711e685512ad4a3ae94dfa93016ca7cadb265419e6d6249b8c0a450a1b0793683256bb5d46fe24ff5c049b4cc6fafcc9f4719e78329bcc957d4995807b854d166f9ff5a74bf47758a1ca6439594195c97ab21e07a360b2c10ce530ce8e26f5cff5c1268da7fb2527cddf3593ffc1f2fe77a9d22a14c97b794f44b0e5a48d71e4301e6eb2f3c7f5c80fa9d219979ea8d2fd3b5479be1239d99bec4f0e26e29e9323d4a83f5daabf4195e3c9c9e474725628a255399f5c902ad3c9e5e37ae48754b99a3cdb393ee9fe5a5ffe5204bb79b91299a4935ba1c89df142bb9f6ba4ca3d541917bf80db993c4cca4f54a93cbe35f12155aa93da5355a432e6c4fa9d75e5f94ae4c49e381377e2bd3cebe7daa32a8522133661793079981ac32fab322d4dfd97aa14360da64c18ff2daa3c5b899c86d3681a4f939767fd5c2b5499a6852a8522db55f95c049bf6a65bf7e19336bf4795272b91d3c17428fecca6728fd8743ccdff7499fe0e55a6a26b3c9d4e67a489333246c174fe18c186578fab911f5265313ef8db5579b212395d4e57d3f5743395bbc1a68d69f3dfd0da2b5572475a300cb3c6b455a852ec021f4e9feee1fe902aeda77db0dfa8ca7f91912a9d69370f605295bda2672c55d94cea9f5465fff55ddf3b553e66429583e9e1f4687a0c4d46c6f4249f4d4f8bb17da1ca24cc1a9f54e5ec71c665a7cad74ca872ae54112d4a615793faf402aa18c1f4727af54955ae47b73b55fe9a912a37d3db91310c0b1bdde6fdd14da18854e56ef449558677d99637ec77aa7cc6a42af7c3f3e90334198679675a9e56b42ad5c9fa73aa64dde92fa3c89d2a9f33a18af9a8caf4647a328ea6d6d446bf58a8e23ced517d6cdd7eeaee54f96ba655f10a45a45dcd8c5949ad45cefc59f03955c4356cc677aafc152b5499854a95fc343f1d2d6791dee312cfe2a7efd17d5095e4f577ef76aa7cc41e552914c94fb3553e9ba56a3f5866ce7ab3fe6755796b74bf53e523265519cc86b36c7425ed363b9f8dd4dec9ec68c49f7e0be18375659cff2dedcab36fb43eb7e0c5df6fd90ff886d5e070960b5526b329541947b3d96cfeb89762fc85b78a668bd1abe3c8bfa4cad36fb46e2be90f94f56c496f4ffe2055b255164ead4c7f1d675a1dee7f5e95ac3b7be54b217f4595addf68957f3f59810c66ebd966569f35a402cd596bd69e75665d9c39db9bedcf0e9e5e313b9c1dc9338f0717b3933fadc51655448b92ad46b79387d9593ed03db0f3d9c5e75511d75dceae7ebb2adbbed1fa321e05b36b51c63733a9dcc89edd09ba9f3dd0b15fbeee3acd6695e2dba2b3eaacf6a79578a18a39b36676e68f6ec5a8be93cfd42cbef47967e67e49156fbef50b547f49956ddf68fd459579c9e0737ffee45dbce1b01fd231f6eb15733e0fe7d13c9e277f5a8997aaccd3790faa8ca3c9e5bcafdafaf96078351f7e459579f6dad78ebeaacacb6fb4ce477351e2f3fca52a4fff4e52bc21399f6c3947a9329dcfe6f3f9dbbb99fea82a79270bb3f17ca9dafae95dde795ea61f7eb33b7d6dd6e5abaabcfc46eb7c355f8b3f371489d40ae4b3929fd7e7a27d9937e7ad5f8f3dae59cedbf3cebcfba775d8aacade7c5f44af8e68558cf9816a55e6c53b795f52a56859865b6bcb975579f18dd6f9d1fc787e323fa532562b90cf55399b9fcf2fe697f3ab2daae835cbf9f5fce64fabf0ab2af35ba9ca5d5e15f12b57bb5b8ab724e6f7eaeda0cfab326dbf54f4aff78cff1e9b3fcccb7f3a0d2f4da8529957a1caf42abb99d71e5b95bcfcf4edbb4fd695c5dcfcfeaaccadb93d77e6ee9f4ec74b7baacae461ee61b6b8b085318e9eb7f59f5165182f4af996daf2bd54f9ae065516fe2228e2d7823dce4b2e7856fd2b5f6d5b84f9fa575516d14e95f7ad5065110b55922ccccb8b54cf80b1456fd47a59a6efa992648bfe82c6a08be122dba2ca68a7cafb36385c8c852ab950a5312a2d266ab52bf7b2c662fa05554483a26bcbe2d7bdad4297e54e95f74cabb2cace176bbd372f5e6c86fbcfbf42f54155ea8b865265628cb67c6d7fd1dca9f29e69555ad978d156abf5c38b4567ea3fbeb7f20955ba8bbd2c5533368bfdd996d5e2c5c14e95b74daa72b8385a1c2f4e8633bd5a7f3779d8f6d5eeb7553158ca17a78bb3c5b9aa2dd972b4fb22fb178c54b9585ca2a597df32ee2eae3263db6f1d785d95a858f72854b95edc2c6eb32ea9922eee5e7e5174a7cafb2655b95f3c2ccad84121e3d7ed6c263a50bf7c8ffd6d557a263b63667cb8a84c2e27a16e5bae86d66f52255854d54f7f31d7df7ac5ab30a14a6d612eac85adde84945f3eb85d6cdd0ff1b62a49dd88783a682ddc85a7bfc777b7dc12c3bea6cab2b4f47f4ba9fe085596c19261a50b2dfd92cf2eb6c5afb755618d781ee6ec74192ea3653c1fa8d1e8f2f5df20f5c9b25ca6cbde63a9befc4aebb2bf1c2c874bd1942dc7b3fa52ce082f27cbe972b69c2fe54cfdcff97aebe070b95cae966bf526b728c54d76f272feeb7d55d8c3b29e0cd96dff2ab98bcd6563d954b565b658fe321afda22aed6567d9d5aabcf84aeb724fa8b0df6b2c0f8abf97f209cba3e5b1f8f36429f760fc9cafb78abab2bf3c535ffc96df9edacbbc97f35f1f512516a5c1cea253be589e2f2f9697cb2b5d5bae5ffe16a9afbe55b4bc59de2eef50aa2fbfd25acc312eefd5df588d5c3ee00dd725beebfa63be132aea4a656a3ffec6ba319bd497bfcc7f7d4415c4305ee27eff323696b5a5b9b49636e65e96cef32ff07efd5dafa5bbf448956d5f69fd653572653cdee127a9b22a3dfe1e9bd17ae58fef5eab296fa962f8ec814f0d1ecf8c889df2c390af82155bf155b88a56f12a99ac7f8f2aab74d52355b67da5f5c5dfabfe4aae95ad86f28a1ff3f5d6c16176a73419c6ab6c92bf5e53de5325ba58d68d50d41b330cf921abf3e365b41aadc6ab7c35594da3fcd1feca7b91ab19a9b2ed2bad2f5599af16abe56ab55acb2b7eccd75b455dd9aceaabc6aac9dd556bd55e759e96de4b7b4b954297f820ba5c75d93933d969ff921d8451eaf18bd8e05661ec48d96e14f9b60d0ea37cb597e6fcf8b1cc5eb7f75429a258a18be088fb7c91dc457576c2ea210f231e3fda4e95b74dd495fd412bb94dc74f4bed357b5b95475d8c309ef15274dabf0ac3f828deeb5ff62f93bb47dba9f2b609550eb8680142feb4d45eb3f754812ef181685f783c6767ec36cca35366a63cc90a538fdda9f2b609550ee35a6cc47b1f39fd7d55a04b74c1a7ac217aa6c3789ed4d999c10cf6f4ec9d2a6fdb1ffd4dea3b7bc576aa7c47dba9f21d6da7ca77b49d2adfd17e902af485c3d5d1af479efcf9afb09fa4ca6b477ec29b8e9f33315e395e9dac4e5787fcfce7a8b23a5b9daf2ec4df97ab2be3e5bb91ff021b1cf27a7f96dcf192a833efeaf22d22d8b5d4e56675bbba5bddcbfdf4ffe208c68ee3d25f532532560f1fb3df11c156e55565557d72e45fab4ac8de2ecdb7542934892e3f667f5d95556d65aeac95fde4c8bf5695f74af32d55560f3d73d5fd98fd06552e57ceca5d796b431df9777c9d15f6a84a64c4a5f74af36d558a79e28fd95f6957d62583affdb5dc35b1666bae55f9577c9d759b2aef95e6dbaa2483f0f463b61b45be6dcf5579af34df5325a97fcc76aabc6d8faaa49ea82bb3b74bf39d0816b2b3a7b60e0727ebe8f9bfc176aabc6dcf5579597aeb789dac132328fe5ca7ecec9dba322c56b71e6ddd5bf7d783e7ff06dba9f2b63d57655b091ac56e31fae96d558a5d148f965caf87eb6c3d5a8f0b12cae6ebc97abafefa28f2bfc89ef48c6ba2ae6c1ddd1bc1474691852aecfcd1d6f3f542fcb95caf0a12aaac056dd6f58276aabc6d2f54b97d5aaeca8c40fdf4b62af15c5caf6ddd5837c59fad757bdd61b74295aea0bd79501cdba9f2b63d5785979e96ab3223503fbdad8ae8a559cad6fbeb83f5e1fa48d8f1fa24b48c00ff8ebf77aabc6d4f54113f3d96ea5353251a5aefb4f6f5a8a96c7dba3ea39fced71751d30840f87ba7cadbf64295fcb15c1f4d9568d47c4f953057b6be5c5fd14fd7eb9bb5a86f20fcbd53e56d7bae8a113f96eba3a9120ddfd8672cdb9599117fccbe3ae3b2be5bdfaf1f3e7bdd9f2ee3cfdba32a3c16aa446f97e6dbaa14ef142953fbfc618fff0efbfaece4ba3c4e3f771dad54fe287bae4ab87c597ecfed9db13d0b971fb3afab32cfd79547d27f3ffb36eb4bfaf5dfd6d5756d74be36bf6b3d7aae0a33df2ecdf75461e6c7ec2fd4156bfd744de5b1cc9f7c9bf525fdfa6f6b675dcc387bdf5f95308a4b297fbb34df56e57c96f28fd957db958db1296d9ebfdd4d65fef4dbac2fe9d77f1b8f36c1777e17efb92a49f67669bed3ae9c63e7fdfbf6d5bab2611bbe91dfc17df31baddbe8d9bffd2c5542f67669be338a641fb5bfd2ae6ca24dfcf21bad9f5565936c449f61d3fbfeaa9ccfb855e8f296bda5caa61f973e6a7f65857833d80c851ecfbed1fa6955b2cd6833dee49bc99f2efff755812e6fd9ebaa14577ee6a97f36d79b6911ff36b3cdfccfa6e3357baeca7b67bff1252aa1c96bb5e857fbe3aa2c36cbcd6ab3de6cfe6c3a5eb3dfb5a3f567a9f2dd6da7ca77b49d2adfd176aa7c47dba9f21d6da7ca77b49d2adfd176aa7c47fb49aa6cea9bc6a6b9696dda9bcea7affea6335edbede7a8b2e96ef636fbf2a783cd07af9f2df5cf3b55fe1e558e36c72ffeedd98ce3cb6fb6e2b743fe9cefb2fe50554e362f7fdbed73555e7cb315bf1df2e77c97f587aa72b639977f5f706f73f9ab2abf7cb355fe76c89ff305d01faacad5e65a1356c09ead476eff66eb4e95bf59959bcdede64efe744faa3c5b8fdcfecdd69ff35dd69fa98a50e36153de5436d54d6d634a559ead476eff66ebcff92eeb4f55e5bfc7fe0955f8f9d355e69d2aefdbe3775c7e5da5fff50b225f51a5d06457573e676fd59597baf037de2a7a5d956ddf21d9a9f2b6bd1dc19e97e85b7b5c76aafc4edba9f21d6da7ca77b49d2adfd176aa7c47dba9f21dede7a8b2b136f6c6d9b81b7c6d6afb0c4af006fd20fb39aad48dba7846ddafbff5e5bc9d2affb02ad3719da99f1fbfc8fa7205b2ceeb613daac78faa3cff9d913fc37e8e2af5a49ed67bf5befc2aabae072f5720e70d71e6a03e7ca2cab3df19f933ece7a8224a3bab8feae37afe5495972b9058e3ea3d797bf8f9ef8cfc1986d9c9b8f6135491ca4c36a567aabc5881842af5e9e339cf7f67e4cfb0c1617d569faf4eeb8befae4a7d39136d477d8577b3d517595fae40162b8ff5757df3a8caf3df19f933ac50859f2577abc36faf4abddea837ebad7a5baa425f647db90259efd4bbf5bdfafe13559efdcec89f61a27c4af5839fa0ca7f9389ba7218ba3b55be97ed54f98eb653e53bda4e95ef683b55bea3fd7955426f67b0efa4cace7eb59d2adfd176aa7c47dba9f21d6da7ca77b49fa3ca8b75fbedf66285b85857a91fd55fbe4ff9c4ea27f5d3fa59fdbc7ef1c9f4fcadabcf3f479517ebf65b6cb6dcb66e5fbfac5fbd7acfebfa4dfd56fc7d57bfff2baa3c7957f937a9f253e68c9faedb8b7268ce5ab3f6ac33eba28c8a3786eb0f2f7ebfeaffdfde993527c8b361f8fcfd1b9e33eecbbc4764b5ad5af7ed0cd7aa685b352d3af3fdf7ef61a906a49d62ed5b6cf11e933c48ee0cb910544cb0a9c4556b06e4edddd6ba83f1b6acd7b715874a524db97ad7e3ea2220cd882cddc9d56e397deafd37a8b8afdb3f66b75de885deb6eff458dcd58f4e6fc2f12ba366d59c0a7536ab6d42cf409de4f640422da879b986d7d543e5749664a7653fefaf51d1afe408e6be6e6f8f425d2e1763bb6fec11c37e4730bd8114645d55162331161331150fef51f1babaa9f8cc927c68f9d4fb6b54aee5bce2f4a373ddfe61665fa1176b9ffe1bb923a4217b74eb466c8510d23f90d4241aca35dcae01e64cf6f1fe1b54dcd7ed856afec7486041e4bef1dc5ff58dca088d9dbea382097e5c034dd014c1debd19a3d9a9eb4773261f5a3aec075eef3f42c575dd5e54454dd44543345d54dcf757b5cec8d3359aa385d3732dd176bb221d2dd52a5aa1c753d78fe64c3eb474a472e2fd17a85c42a22fbeed5f6197f4fe3b54444664454ee4bfeef4fdde7f87ca3529a212464554c2a89fa2829e22bdaf1fa3f21ce97dfd1895752459faadf9dbd779ba20954d24595f39d35e90ca3692ac90501181f5825e918176686f468a768683402a4208238268b07aded6ce6cfdd477f05672a8c43e21ed1ba9b0c0e2a808a940376604fd12dce116dda192e5510e56d3d35a05dd9fd1ba9fef00b858a50315ed13fa3e2ad5c0aaa1fa31827e6aa0266aa1b615775017f5501fc5a19c40494853288d32906751ee502b8f0a2e47b996e9583de6b23f56140dc770cc5c8a353cc0437b1d3cc2633cc153fc6045333cc70bac07d926fb7ec066c94b65b6d64bb3f569f97ba9e06560adf0237ec2cf786d46d03f1bc8b75858afbde057480dbc83748f554811c6982086296607078e8b2e47b996e9b83ce66e7fe9b51b29bec5e6769470d98a2af81ed26a906d529cfb34e3a5978a5e3265b2309998f2a3a297f58afec17d880353a99da13a6ee0266e9965e89736e49d61df8c34157721ef612bc2719cc0499cc2699cc159a93ec739d9cf5d0b1c6bc7dced2fbd9697e202512cc5cc88686440866414648b1c2650f27bafd85c8e7c7ca854f59a5ebf1c15323e531332357345b3633bc715f200f98cccada50ba29325ee901579244f52dd67b296bd3cb536640bcb3ab6a3dbdf1d49ad0ac9ef85bc1283ec826c8dc9c42e9d9e57de789c303950d11b7a536fe9ed0b52d907964a10a4981033827ed94b39250c524e8a5674436e89d9428994494572b827555283bc4e1a3eb59aa40569db7674fba31ae9f8b4da253d2befc3734ce290264832c8360113a7e477b6f77d9fc854ba7a0fd2fe05a9a4022b4d32244b72246f46d02f29292f5085c6a846076644e16c4c47908fe9844e650ffa4067744e1754f7a9b5a42bfa489f6c47b73f7da66bba3959baa582bed0576a4054a73bbaa17baa9eb165a0b3de2b093d0969ea7254288a242bf87945cfea393d3fd6c6da05a9e048b2827f065bc696daa53f1953124956f0ef2bcbc552bf3895e8e17a84e3bb3d6591648583caf9bf90fe4e393df21926ff09959f1eb91b0e85e397fc9fde37c3a6884a18155109a3222a615444258cba4e2a945be310adb10fb4f8e1ba3ee3884785f58be21e0f14b219a8af938aa3cff4e5bbf37f4f5469c9074e971e11fc199dd523ce1e171e2af28cde46d5a81975c81b46531addeba9a1483c8e6b79660677ee5e7c2d54ec3c44545c337a1b6da363748d9e3582c4ff08d6567c8f609e99c1dfc6224754cea3e299d1db881b0923e95ee724f2a3e2f6791b8bfc9feb771cc1dc337a1b29236d648cac7b9d93c8878a6766f01ffb0cf03bde2bee19bde18c9233f24661a7bc378e582abbc6007b66068fa89ca323156946ef9db61b986794dd70373a1d477c52db3506d8333378442592a4ab3eaffc5a5df5b7c85fab884a18155109a34241e50ba3007fab7e9e8ab97458a637f496ded1122dd30abda7555aa375daa04ddaa26ddaf1a84b7bb44fe33441933445d33443b33447f3a00253588c696cc0866cc4c66cc2a6ec81cdd8dc8a1690ea102d4176b482e811d699b227f6ccd66c03cb46b0f65c198cd7a6e62bb66582bdb05766b01d447bb657064c9da6a76986a0844184518618639c15d90dbb05ef3b566265f02e81c6acc2ee5915a27b5683a87e886cd5588335e6ab69eced191e2aacc95aaccd3aaccb7aaccfe22cc1922cc5d22cc3b22ce7519e15b8c2635cb334e0433ee263d0844ff9039ff1395f701db4e42bfec89ff8335ff30d445b4805442fa0257fe506dff13d574188634e38dd2538742d878732580853bcc86ff8ed283fcaf33b5e62395ee66565c02bfc9e57790d4a75508337790bf236eff02eeff13e8ff3044ff2144f83963cc3b33cc7f3bcc00b45a5188354b3235bc54171304d2dc4a86a3fbf44e57ffffef37f1ff7e09e</data>
+ </image>
+ <image name="image17">
+ <data format="PNG" length="222118">89504e470d0a1a0a0000000d49484452000003000000028b08060000004181ef210000200049444154789cec9d777c5455f6c0bfaf4e4d66528140a8a18920a2a254b1c1ae62c3b5ae1dd78e5d5c5d7bc1b6ba0a96d5755574755db17754046c6003a5480b451220bd4d9fd77e7f0c191292492611057fbeefe7139899fbeeb9e79d7bde7be7d627545656b233238ebedf6af1a38d8d8d8d8d8d8d8d8d8dcd6f8acd8bee1576fe4d6efaa531f09f71ffedbf964e3636363636363636363636bf103d475d6741f38640b20130e2e8fbad998fdd0bc0eb8b83bfba723636363636363636363636bb96c6f8bee7a8ebac91ddd70b004265656532f89ff379fd6e55d0c6c6c6c6c6c6c6c6c666777110cf752adf62cedce3659d38d6c765175fc7fa05d70acda60019ba9952806c0651ad20a6ea47b31c98a6c0ce0b0584edff58f60a021b1b1b1b1b1b1b1b9bdf1063e4ff306ddab4ce659e358b2ff4d3f778598d0885074db76eb8f5463e5e166b33bfc3acc1effc0431c742ad1b405da4270d64b56804d8d8d8d8d8d8d8d8d8d8fc9638d8f95fa64d9b86a6699dcaaf280ab366cd6261f4d466b204a1c5fadb36b12c2ba52c005114b12c0b2b456f7b63798de94d65011c3eccc18c5bef4cac0188c7750ccd6853a1184e228a4570f0bbb81a16e2fce114ccc8419856c74eccc6c6c6c6c6c6c6c6c6668fc299f8cf30da8e8753a1284a22bf6624655996c5860d1bf8f2cb2fd3923161c2040a0a0a92df9bca320c03411058b56a157dfbf6455194168d005114a9ababa3b6b6965ebd7a251b13495924627ed8be0838ae19e86d4cff1131708b5bc15b42c41322ea09935ffa3d9ecdbda837bbd88d001b1b1b1b1b1b1b1b9bdf3ca6993a1e4e87a6f1b4699a2c5cb8900b2eb820adbc73e6cca15bb76eadca120481cf3efb8c934e3a89e38e3b8e071e7800a7d3996c0488a248696929679e7926959595bcf1c61bf4eddbb785acf8f68640b20160e8adb5782c1c4203997231429f2fa81bb21cdda5211a223543bf26c311217bcd0402463f2296db9e0e64f39be3bddb7b70d8554b007078f37f31d9f31e1cb14bcb694b6f77ae83bf9d9849861e47ababe2967f6da6d6918de2f223ca32979c96c5209781d550c50dffdc44959285eacee2bddb0b292e0d6099060802c5ef2ee5be554e54770ea79edc8dc37a3b29f4cb8c3d7f2e0e6fde2eb3d7aeac83634ecfe6708f05a64e51a18f759beb0088369470e9e3b5a89e1c14a7afc37245594a69b7edab9f00987a421607741588c775242dcc33cfade28b061faa3b1b41943b2c4f90444e99ec63624f8140dce4a7f9df72e7d74e544f3692e24e5bff746dfc4b5d0fbb5aeec9e77761dd93ab581cb6505c7e04414aa69d34c59fd257db4a3bf7f41cf6f39ae8ba812ac479f3b515bcb1d183eac94194d4a4fce34febc25f06298cbf683e8acb87c39b9f52aee272f0d4e93aa73e548e204a28aeacb4ce6f57fa7153db7bbb74e7f68b7359fbc6721efb268aeac941525c40fa3ed9960dbb0cf070ed44178eb8862a69bcf3ea32e614bb51dd3988b2232d7d6d6c76379d1d0148e66f124f77a631d1b4fc9d652d5bb68c4020c0ecd9b38946a33cf8e083646464200802ebd7af67ead4a97cfdf5d7646464505c5cdcac01d0282bae8940630320de720440127432a58d787b7c42c3de2b0976af443045444b004b40f384281ff5399e5eabc95eb62f8ead8753a7f54033c50e9fac8dcdee2454b70d00c999fb8bc9fe25ca4925effcb37358fc8f8f796a55195d868ee0f12916a7bd58816ac088530652b0640927beb98901474ce0dee3754ef9cf360c53000a39f99a3788876b70fa0a901437aacb81ae9b7cb7681bef3cf713af3c7838e1ba6de8babecbce63ea3dcbd1e2f1c4b9b43112990e2fff7303ff0957a3456af96af6714cb97436002e7f21aa3b1b5d3711d2284312c16872d8d0c9f929edd63410fb7171090f7db79948a886bc817bf1c6d5458c9fb61487a6e1cce8d66179e3ff94cf247123c75ef635515da35b411eba2e23680696d0315ba5eb7fbfd4f5b0abe4bafc5e8ed6d633795b198228232899c939af92489bbeda56da7f9e2de61fd5d568916a5c795d9977f7085ef8cb7c344dc3e5eb01409f91d91c5abe1a060da5a1622d4e5f0f24676e4ab95a438867f5028e9257f34aad895bf2346b08a66257fa31246cefcacae5ee4b72f8ea994f787471350e6f3ea2232be947e9fa645b369c71b29f87fefa1e1f6e2ec75b50c482fbf7e3d9bfcc43d3f4a40d6d6cf67476e5084063ef7c7e7e3e83070f4eb91ec0344d56ac58d12ccfceb2344d63ead4a934343470efbdf73267ce1c745d67e6cc995457572783ffecec6c1e7ae8210e3df45062b1180e87a399ac78bcd90840f3350092a091e5fa1175d08794efbf12dda9a144123d2086aa23028221a18445c2ddaa88e62ca0cbf7d5e4ac3c8af25011bab5a337c6c6664f2752570680bfe7bedc7076363d641d2956cf3d0ffdc80ad38fe2ca42561d5c70723607e659847593ca1fbfe3da57457a4dd88b9bc6b890250b0711663ff9031f5665a0ba739ac906187e485fcedfdf4fb76e997c307b114ffd98e85d77f87c29cb1d7e581ed30f5068081b844bbfe7e2670cc65f3a028067ffb61f966571ce8c15a8ee9c64efe278afc04dcb1241e8b6ef97d2f5f283893cfe39a66171d2de4378f4d1f544ea2b593377315d9f1c4ee4910558a6080c25525f463c5c8deae98a209818ba81a819fcb022482c94588014a9df86a11b7872f66a61cb79f7f761dcc55f01a07af29b7d3fe0e8412dce457165f1ef19fb70c0e9af03f0e9230771d51b659c35d4497e8ed2cc4eae2c3f77fc2587ac78848dcb5673d8d107326aea3c648717d593e8813474034337933d1d91fa44d0e9f076c7d04d9caa931bcfcf6fd5d69ffcbd889b3fa8e0e4012ab59fafe0bacf2d1477a2a7fda4bde594761373bcc9f3ff705980b86662ea2615abd7a2b82713ad2fc3342c14e78e9eef74e48992c4d57b2b3c7afe17d4d594a1b8b2a9a88aa37a0c24cdc0109af75215ec9fc5f507caedfae2e2a78fe286f72b386da0935c35ca5df7ffc0f79a0fc59ddda69ff638a85b4af93b07b5aad7c16d7fc925578bb0e18735404f8215c548aa175fc1702e3fdd4f91db4495623cffcfa5ccadca60e051fbf037e77ace7a2d8428bb70f9f379f33a27475cbb064b1051dd8920b368929725b31712a90fa1387d7c74779f66f576e5875558d68efa6feaab3fac6848e9c735511d73bbff28b248ac6e3391baad988685eaee8627d7c39da3c34cb9ec073e3b782891ba6d58968c2767af94722dcb64c1ff6a78e23893e71f2a47547cc9fa688b5de9c7d0134b3279ecb6a1cc7ff4031efb7c03b29a81ec30b63ff78db47db23d1b7e5babe3a68a48fd36fc3d8b88d6fd44b86e2ba601aa7b4703d8c6664fe6678f003489a71b651d72c8213cf3cc338862eb9de4baae73c20927b428bfa92c5dd7110481abafbe1ac33078f0c10779edb5d70887c3949696b26cd932f2f2f2b8e79e7b9832650ad168b455bde2dbd738371901d85148a6bc15479f85548c5c81299b38822e34570c43311075112cd0dc310443c051ef42736b94effb035d222e3c2b32a9d676ed540a1b9b5f92c6d6fe5153f389bcb990e33ed94ccf51e379fe6a3f87ff6d0baa6e30e59afde8b9e45b8ebc7d2d96699055e043d77d6c5dba8973e747d02235387372f9f8f65ebc71f14a745d07fa37eb493864e3679cf8af0d741d761c9fdc339899e77d81ae1b4cb9aa7fca726f9dd88f33ce9ec3fafa6a32bae6606859cc9fb914fe7d3093a73e8a69c4c9e97b28ff9ede9fb366ac06e09dda1e5cb28f8b7bbff15234fe50547717e2d100866931d429b0a4218c287b50bd79289eeee85a9c48a00280ff3e7c262e07946daae59f2f6de1275c58c820b951337a022039b3314db3d93da329e1edc18ae8c869f6fdd689235b9c8ba0241623194dbadb47aff99c539ed84c76bfd1cdec74d2b5fd297b793e672f28a1d7e8f11c7634046b7e42756727cb42f2a0667850330a017065f503c0d3653800c75ed23ba5ada18803577eca090f6dc49dd517c59d8ba01b5882d1a6dd1cbe3e3b4e3e597e4f864eec49c5d22fd0b538441a9ad92b1d790e971b9728e09a329657fa7b11a2119ef8f73abe0eab989684b593fdb72edbc6b91f55a6e58b63572ce44f0f6fa2e8b0293c7fb98fc36edc82c33081a2947eba751929e53bbc5d9be972dcb9f954cd99cf790b4be9397a3c87035a3c8220bb99786e3e2b9ffd941b5695e3caedc12777f7e1f58b97b3fa5d998207fa107de63304c543ffc9fdd9f8c16242f5f548aa17514d34708fe927f3427103ba66a066640234ab37d99199ecb16ee1ab6df8b1207bf9d3d5fd393e47a5bb27c4e5e73c816166625a022602375ee8e3aee96f511b09278e57bc3bf2b72137505643de9022746d3391867244d5dfca55b313bbd08f979c09ff9d75246f5f7303ff5cdf05d9e943f17647f174c312d4a49ee9fb78ea73bde7d6253c7ddf9f39b736487eb6c955e73c89b9dd86a9ee1736367b1a3f7f046087af37edcd8fc7e32977186a5ca8bb739ea6b21af5324d93e9d3a7a3280a77dd7517efbefb2e00d9d9d9fce31fffe0d8638f251c0ea7d46bfb807ba201a06946b377006477fd9adae12b410035e820921d42d445d490034bb290620a525c26e68d12ce0be0aaf1622806f5c37e20afb237151b0f4fd34c3636bb9fc6e0f3f4028963e66d201aa866e3e79fe2bbf21422f5df619a02e7f595f9d35f7f24da5085e2caa1be5c47765938b332b97d6a7f0a5c71744dc399d98540f9ab7872cd66b201667c568d6998d46f598bea1949b4be1cd3b0da2cf795f531eeb97000cfbdb788b94b4ab1fc4e6435d1db6a9a169669611a26a7dcf039b22bd183fbd01d4bb9edfc3ff0faa971d6afd880452ef1701dcaf69139cbb0302d10d5c4f196097a2cc29f2e7a93555b2ad0a301269e7e228f5d9fcb84e91b7078baa0b87301697bb90066caf786441aca017065efd5ec7b6be7222a0919d1605532ff1d1faf231aae6d61a753ba481c3d7f03d1400d3f7db9082822da5086a16bc9b252d56da3ae6dd91ae096b96b89066b7064f442d24d0cdd82ed532452d9adb91d1275d373df6cee1d15e1d4735762a120a9592decd59ebcc6de9afcafdee7c8dbd63364f2f9bcfcb79e8cbd7435866e24473d1af1f8dcdc7cfab0b47cf1f68fd76db7e36232af3c9e68c3122c2bd13395ca4f7306f64e295f7636d7e5f40289a3176c241aa8e6a72f16c135fd300d13c33039a7a74cc5d9c338ca483c8582ba8b60c51ab4688867ea873135a396472b425c3056e581a9eb89040d5c3e67d22efbbb05ae0e6809db29be96f5a6ca582486bc5bfaaa445b7efccac36b78315cc3a0037af1e8fde31875d1124c4b64ca9905943d379f0fb754233b128d0e51f662188df953cbb50c13c55380a11bc442b538fd9d9913dc793f06787e6105534f1ec1d3b7ad03cff6e01fb5c33ed99e0dcffdeb08befdc71c6e9dbf9e3ea3ffc0cbf78d65d4c54b314da1cdf70cd9d8ec49949696762a5f6e6e6294b2a9af575454243f070201aaaaaa5ae403c8cbcb0312c17f7979397ebfbf85aca67af9fd7e264d9ac4ecd9b3d9b06103007bedb517a3478fa6b4b494482492522fadd908c04ebb00a93925684e0d25e420921d440dab887119cd1d473444042ce29e186ad881155388fac378ca33d01d3a4ad626f475764bdfe6b783b9fde12a0286ae212819b873876021601806d140259605463c8220b971e70e43523d00dc7b557f5eb9e91d5ef9712b92ea65e51ba7639a26d1607533d90061c189ece9862b7b3082206222110bd7b559eec3b7cce39d3e0e0e197d241f9fdbc084ebd7230a89e978aab73b004a466ff4686d72ba805e6772c5cdf3d1a2b5387d0339f8e0e589a93ca6c592b0c9de0e81af4206a2e2400b9525820b0136847c480e13d31498f7ea02669e712ad1862f310d10d41d8b171bcfa9b51e3dc3020c1313300cabd9f1ad9d8ba6c5d3b69345626854543371660f044090dc9846ead1889d756dcbd600f53851bc0538fc4588b20b6b7bdeb6ecb673d93d86e7f0cfe305a65ef0066b22faf6b9d6d9cd8e4b479e11086059f0c0a79598886cfcea6b3c7f3b934860015d0fda979927e46199064b667dc6fd955e1eb96f7cdabe88e840f174c599dd1f10300c33d9084b65ff19d30a5b959f37626f1e3db5a0992e96d51f53d711944c9cd9039ad59524c005173fcda6866a5c594518b17a64571e82ece58de7aa78766a37fefd440e03ebbfe3d3fa3882a820a859cdec67e83a8605a625a7acb7f67cb5b5344337300c83a51f2fc277e96918e6b7e89ac6d97d051af20fe2a31347829068287df4d4c95c3ef531363694a1b87292bfef2c574002ac84ce6624f97bc17e5db967a2d2cc6eb233abd982e35de1c7004fdf3e13f1e669bc737b578ebb7f33f14810d9d97cda56477c3c955e7fee2173d0a25a0cd3e2a76fbe22f3f6f331cda5e8ba668f00d8fc6690e5f6d7e9b445535f6f2a4b14c594b29b4e0d92a41dd3e85b9395999949696929175e78211b376e243737976030c8975f7ec945175dc4cc9933f17abd2da600254700b4c41d3239052852b7217990a54610004bb490e2327254219c1542b444e490034c114bb0886546705779b1b0301c068221a2cb412275eb3b662d1b9bddc66062a1c4dce8c73744b86e449c2be65793b7573ef51b17120f95214a0e1e5811e4ae235dfcf9c50d441a36e2ef9241a0da205f1e4cf1ea2584aaaad9f7e48b0188054a31cd4460db281b408f2576f28887cb9bfd9fb25cd9cda07c2f2b976e64f992755cfcf6e9042bdf40716651ab8fc2172fa742b388d415d374970e3553c2ac8f605906532e1ac6d74f3e88160d21c80a4f2eaa67da78834fe76ca5db500f5b3f7f9f58702ba2e2a2500db03126a07872e9b3ff10c2954b89d46f428b5623c88dc3933becd5da75be28d89fe37c35fc774b94ac5e899b55b4613382ec6670d7ac56cf05c6a465a7a74ba25c332cca359fd59233206f7b5a1982e44871cf69a9ebe31b7aa5ac63003d9a283b16dcda4cd2938bbaa4b45bd3b20b470ee0e9930dce3df329bea9ae4371e5629a31b448355ab4a643f22ccbe099adbd386bb0cc3ddf2be40c1a4eb87639b140296b5e7f86e316f4458f3500203b32c997c7a7ed8bd3f7d5b9726135b983f268d8f429f1d0b61d364861ff7c9956e5af7bfb598efb7260335d9edc34926bf78971d5a735e40eca6f56570faf0973fb110aa73c578ea8b8e8b357374a3786102499addf7e8972f9111c7a9ec5d7f7dd4e3ce84176f88887cbd12289e0f6cb607f8650c917219d48fd7a60ef14f5d696af364f1325077ddc318a432602027dc78c2254b98478a80c430b72c04915c443e5e8d13a2435838d9fdecefe93ae40766492a16c428fd58320b45aa6eace25165c4f2cb40d411093bf177fb88ae3de6e68663739568b202a6dea0a1df5e31158669c47a7ff0df7a30ff0eae56126dfbd08bcdd90d48c0ef9647b7acd6b28e2cc5e75cc5c11217ff868620dab8885cad0e3f5f62e4036bf191445c1e974360bc4db221a8d6e9f6a99a0e9f5d254463a0d0041109ae5692a4b51143c1e0f5bb76e65ead4a9ac5ebd9a9e3d7b3273e64cd6af5fcf1d77dcc1471f7dc445175dc4bffef5af168d804659f1786267a0e4226049dad1fad0abb391639bc1144050d05c1a88166aad13cd1dc3122d1cf52e223921344f1c2926236a12a22112adca6c26cbc6664f471413c1f3ff6ef9887b6e3c9d0fced090e3b55c38ed6344c983eaf6f3d69def32e8ca497cfa4799902152f6c3475c3a3bc2058f2de5f1e72ea3b63cc0a6afbf040623c96a5266e3ff4d3f375e1fed95ebf0e430fd864964893ab20aff79e041cc5803383cdcfcfe66de7cf6226a221a7fbaea6d5e9f7912274eff08801e23c7f1d044373104d62ffa94f3de89e1f0e4a07a72f8fec9796cbef1043ef8a3811028e5dcab5622c919a8ee6c6ef9db78bc828e8580555fce2517cc41569c28ce4cfe74eb78cecf4ddc9416cdb982c0b6b738f6c62d282e7fb320e2e67f7cc7bf675dc269e535147ffb2dd00fcb88223b32539e4bba767af1d6f93c76fb79cc3dab8e4ddf7f876976c732a2488a33e53d6767596dd53180b8fdb89de5b565b797ef1ecb89d77e00c0ab970f402fafe0b6fbff8c200808a2c29957bd41cc509973ff1f93c7a525cf3299f5d70ff9fb8d97f281184725ccd5173d852439901c5e44494092769cdf45fffc8147d3f4c58ff6fa036f9c914b37779c2b2e9d8728ba76d82085fd2f7e62398fa490bfb32e2fddf2218fcd98cadc33ebd8b06431d03b5957afdcfa1e83af3d9545534e2126a86cfb711117ff731bb2e244946566ac16f9fbfe22232fda82e81b84c393d3eca1f9bf1521fe5ce461f1f220227a8b7a3bfea6b1297df54f77fcb1d53487af27375c37964c49c742c4acddc6857f79154971a13833515d9908828124ef08ce45514014052449e484db0ee6821465fa0af7a5f2fbf94892842839927635115bd84d924484561609fe5c3f569c1988a2c85377ff0fc7cda7f2d67516c7fe7d2d4862f2fa4dd7c74fbcf3c894f6bdf3e64f9979dd851ca5c770c9316ebeec092451467178edb8c0e63783aaaae4e4e4f0ce3befd0d0d090f238511439f8e083c9c8c820180c267f6feaeb8dc1bc699ac8b24c7676764a598d73fc9bdeef9acacacccc64ebd6ad9c7efae9ac5bb78ec2c2421e79e411468d1ac5b871e31045915b6eb9854f3ef984a953a7327bf66c3c1e4f0b59712d71df140a0f9a6e8d3afc14369494270feadba518f9f08544731bc082983786ee8ee3ac7313ce0d6289269e321fb1ac30525c46093a90630a728307fda383d954deaf7d0bdbd8ec0184abd7253fabde2ec44395e8d17a4c238e20ca284e1f8a3b17515288052bd0a375589689a4b8515c7e0c2d82a9c7d063f58892032d529b5884e84abdd0cf9dd33fed720541408bd6a347eb30b430b2c387e2cac2b24cf4681d5ab41e676677044144debef05194d4ed79ead1630d88928aecf4e3f0e6615916f160395ab41e231e4252ddc80e1faa270f2c2399cf32752cd34076fab6efe1ed448bd412ae5e8769ea08a28427a73fb2d38fecd8d10088872ad1c2d568d17a4459458bd4a13833911d99a89ebc56cfc588075bd8a8353b39337b106b28251eada7ebf04378ef9a287b1fff36aa27175ff7fddbac5b774e7f00f458434a5b6be1aa16c7376268e1d4766bf20614438b10a9dd8416a945921d28ee6c6467d68e6d14b76f012788725af2b04ce2a12af45843f2fd0cb22313c59dd362379958b00c2d5cd3ae2fae7c7b1a7dc65c891e6bc0959558dc99ac9f9d6cd0d486922323a5fc9deda5c71a92e707a047eb138b4f9d3e546f57e2a18a849f5926a2ec4471fa909d3e644726d1fa1222f525987a1467660f5cfe4244d995942dbbb2786b5a15632e5f8acbd733d1fbde4467231e4ae9ab8220a648f3619946f29ab12ca399ff2baee60fed9d7dabad328fbffd68a4db67f15c791cc595832bab371de1e7fa71d3fc8e8c6e4403db30620124d58b23a35bf2fa4dd7c705414a79ae9611271eae428f36d68985ecf46ff7d75dbfcdb28dcdaee4ccfdd6316dda344a4a4af0783c8c1c3992f5eb53cf68916599679e7986891327120e87e9ddbb37b366cde2b9effa2765959595f1d65b6f71db6db7b1cf3efba4dc05c8344dbefdf65b1e7bec31468f1e4d4141410b598ddb7fce983183c2c24266cf9ecdb061c3080402088280cfe763ce9c395c7df5d584c3619e7ffe798e3cf2487c3e5f521640dfc22e2cfaf8a51d6b009ab6322aeb7ad263f1081ca3bfc35274a4984250a9473005444dc494adc45a005dc259ebc651ef065d46f8663865753ded96becd6f06a7372ff95971f91045015d71a0c71a90556f222871fa1084446f9fae3ad1a2f50882882449288e5c4c434357d444c0a0ba509cbe365fd2244962dae51ab100a62c63c90a8a232f194459968526cb48929cec61901a7b7a65094b4afc89ce0c6497bf894e16a29087a4a8e83167b22cc599891e6dc0dc9e0f59dea1872313538f604a220e6f2e96a9210852b2f7b3e9f5eef064277e53542c534fd8c39189a4b81144a9d57331e22e5a63673b657419c44b778dc7b04cdc5a05d75df820b29283c3ed6ff59ed3346f63bad486ada5263de43bcb93244f9b766b44541c90d90559752208d2f6e15c31d923db5882ec4c4f9eecc8429444f488033d1e40523cc96079e79e62a737074992d3f245597561997154970f5156511c3e6497bf850d9ad9d0e14929bf85bd5c3e44c142561c187a14c5e14671fa130d6777269224a0a94ef4683d822021c90ab2ac6c2f3367478fb7ea4171b8693ac54d0b94f2b23a9143b356f1453c88c3939d7c119824892009297d551052a48902962863c932962e81b0ddff5d7e64472682b0b3ad77f2ad14653a33bb7181b88209552692ace0f06677f8f9f873fdb8f9bd26135114d1e3010412bd93499969fab820a6b6afe4cc46922434c589110f261a114e1f8ad3dfeac8868dcd9e882ccb88a2c8befbee4b7e7eea5d2d254922373717499252f6da4b92c4a1871e4a666666bbe59e79e6998c1c39b2d914a0a6b242a110575e79259aa671c2092750545444241249961d0a8538e18413f0f97c6cdbb68d499326110a85f0f97ccd6435be0958283c68ba3574f414ea0281642102e09623e4e66ec0d1672d8a334238b701c3194777e8988a8923e0443044bc5bb231c21e425bfa5155d98788e1c2b25f096c6363b38bb14c233982108fd462193a8acb87eace45f5d8bd8be912acdad123eccdeddfc6917b269669106dd882651a08a284d3d7a34580bec76059441a4a13a33708b87cddd37a11988d8dcdafcf294357316dda342a2a2af0783c0483c176b704f57abd689a463c1ea76bd7aecc9a358b97960f4eca2a2f2feff0a2625dd7e9d2a54b0b59656565489284d3e944d77562b1588bbc8220e072b9b02c8b68348a6559cdf402f06764b0fccbd7120d8081fb1f43cc88ed24046441c7a3d493e1acc5ebad4471d5a3885a62d1afe1448b780986f20944b208687e0c243bf8b7b1b1f945b02c132d528716a9478f05901d1e14a71fc5e5b383aa0e100f57273fa7f352aa3d113d16d81e5483ec6cd943bfc76059c9695008228ab3fd5e401b1b9bddc7898357326ddab44ee59d356b1673560dd9e3653924076bbe7d2bd100e8b3cf51888a1db9dbd8d8d8d8d8d8d8d8fc7e99326059a7f2bdb676d86f4296a9096cfce1dd4403a0fbe03fe0f1d93d6836363636363636363636ff5f09d5eb6c59f5c18e45c099adbc7cc4c6c6c6c6c6c6c6c6c6c6e6ff078d8b8065006da75d806c6c6c6c6c6c6c6c6c6c6cfe7fa1356d007cf2c87ebb55191b1b1b1b1b1b1b1b1b1b9b5f9e11477f82dded6f636363636363636363f33bc26e00d8d8d8d8d8d8d8d8d8d8fc8e68b301b06ad52a56ad5af5c36526da00002000494441546be962d309ec3ab2b1b1b1b1b1b1b1b1e908ed8e000c1e3c38ad5718dbec3eec3ab2b1b1b1b1b1b1b1b149973637ffef4c60a9693a3ffcb0813e7dba639a260d0d415455a2a0207797ef34545c5c4c241221128900a0280a1e8f87010306ecd272f6647e4fc17f341a25180ce2f57a71bbdd98a68965590882f0cb15aa69c4d7ac45dbba0dcb3291bb75431d3800d1e1d8654598a6896118808524c988a23d33efe7a01b26f37ea861537994602cf18243af4ba25f1707870ccd46927e417ff91df1ee77e5d4c61d6467b8304c8b9afa20bd7c1a138675dbddaad974909b662d6df5f73ba6edfb2b6bf2ff0bc33078f7dd77f9eaabafa8adad251e8f130a85183a7428679d7516ddbb77dfdd2adafc8e110a0f9a6e2d79fbda760f6c9c663278f0e0368f334d939f7e2a479615860f1f08c0860da56cdebc8d21437affece0a6b6b696929212860e1d4a381c66f3e6cd6cd9b2858686060441c0eff7535858c8ba75eb183366ccef263886f4eba8298661108d46d1340d4834a29c4e279224ed129d22563de5f17504e2d58040869a4317b50897e0ebb0ac582cc6dab56b110481bdf6da8bfafa7aa2d12800f1781c5555c9ccccc4ed76ffec4681158912fcef4bc4df790f6f24825ed803ddedc6b9762d0d4e17c28471649e720a6a7edecf2a271e8f515f5f4f6565258661929f9f4f565616aa6abf97a333ac290df2c0eb9bd96f602efd7b64e0f72800d48634be2faee5c78db55c7f521f8abab977b3a6bf6d9eff6c2b457d7ad22bd749e33be405017ed81840af2fe5e8030b77ab7e36e973d3aca53c7edb11ada61d3ae5595e7e72f2afacd1ff0f0281004f3df51423468ca0a0a080c58b17337ffe7c0441a0b2b2927038cc7df7ddc788112376b7aa36bf43461c7d7fdb23003bd3d8dbdcd0d0d022cd344d4451441445faf4e9c69a35252c5af4032347ee4ddfbe3d0806c36cda5446dfbe059d56b8bcbc9c214386d0bf7f7f162d5ac4534f3dc5a2458b28292921180c363bf6befbeee3f3cf3f67d2a449bb2c98fd2dd0561d35c5b22c028100e5e5e598a6892008088290ec51efd2a50b1919199d0ea4752bcec6e8d72cdaf2264658c46165220a027121002e9d51dd8fa58f7324b2907ea0ab280a191919ac5ebd9aaaaa2a366fde4c341aa55bb76ee4e5e5e1f178d8b66d1bddbb77273f3fbfd3ba9bb5b5d45c7b3d3e2d4e974b2e421a3b06293303002b16c7bb6429c167665379c934326fb9898cbd8774aa1c4dd3282fafa0ac6c1bb2ac20cb12a5a52544a351ba74e982d3e9ec94dcdf2b5b6be29c3f6b1513f6edcad0be7e1459a436a403a0eb163df23cd40434ce9fb99297fe3a9c7c9fb29b35fe6d525a15e2fb4a275d7a88ac2ad71044c002d3b2901d0ede5b2f316e5000bf2f6377ab6ad3016ac389ff0d134c0b3ef9a17ef72af41b67e6cc99ecbffffe9c70c2090074efde1db7dbcd51471d852008dc79e75d5c78e185bcfcf2cbf4eedd7bf72a6bf3bb24edeef8f6a69acc9bb784f2f29ae4f781030b292929a3ae2e0040cf9e055455d56359562a11edb279f3662a2a2a38f5d45339f5d45379fae9a7a9acaca44f9f3e8c1a358a030e38809e3d7b02307dfa74468d1ac5bbefbedbe9f27e6ba43b1dc8344d2a2b2b292d2d455555fc7e3f595959f8fd7efc7e3faaaa52525242656525a66976580fc3d2f8bae6553e5afd1cb9461183734633a0eb3e147519c6c0ec83c8d58b98bb6a365f57bf8a616969cb154591828202faf6ed4b6969295bb66ca15fbf7ef87c3e4cd3a45fbf7eecb7df7e646565a1695aa77ccd8a44a9bef67af2f2f3c8bcff5ea4d107816960d4d561d4d56146c238070f24fbaedbc91b3d8ac06d7710abaded7039a669b2a5b494f5c5c51415f567df7df765e8d0610c1c38889f7edac4ead5ab88c7e31d96fb7be6aaa7d6e076ab08a2c077ebebd95411a1b221cee6aa081b2b22d48575727c0eaef8d3209e9957b6bbd5fdcdb2706525822b83cd0d3a5b8306e52193f290c9d680c9c63a1dd393cda72b2a76b79a369de4de19b7f2331ed336c0fcf9f359be7c39ddba25a6c3452206cf3df73a55d55132fcf974efde9d934f3e8d9292121e7ef8e1e408bc8dcdaf498776016a686848d9b3aceb26df7f5f4c45452218fae69b55f4ebd7938c0c0fb158c2b963b138f1b8de6965b76cd9427e7e3e5f7ffd353ffdf413005555552c5fbe9c6fbef9866fbef986cd9b370370fdf5d7939f9fdf6a405cf9d5334c1e3392f11326307ef458a63dbebad33aed6e3a52478d442211cacbcbf1783cb8dd6e144569f6e7f57af1783c94959525d7577484d2e80abefee97d7a640e26b79b0f475e0c39378c9c1b46cd8b91dbdd4761e66016fff42ea5d11569cbb52c0b5114511485aaaa2aeaebebe9d1a307e3c68d233b3b9bb56bd7120a8570381ce8babe7d5e7dc76878fe057c9a8672d699888a8cecf7a3575535fb33a351d4bc5c32a71c4776f7eed43dff22bade31bf364d936028488fc242b2b2b292bf7bbd5efaf52b62dbb632eaeb53f7c0e5e5b59c7ad4da6fe9f2cd8b77f3c7b107317efc04c68d1ec3d4bf3edc6959bb831f3647f9666d2d822851d9a0b1b92acafab2089346e433b830838866515a1d655b6d9c2d3531de5eb48d555b63adca6acb164d6dbcb3bd7f8efd3bc377ffbd873f8c1bcb84091318337612f7fcf7bb66e96fffed54f61b7b30938eb97e97966b59020ea744830611046282405414085b5017b7f0b814a2eddce7d3b5f19e445b7aed0a9ddbf2a75fd326d75c9f7e03202f2f8f09132630e1e0f18c1c7734cf7e5bb54b75f9ad3eab5f79e5150cc360c99225d4d545a8ad5bc6c1133e61e2c84fb0ca3e615d71192fcf7915c33078efbdf758bb766d0b1949db6eff9bf64169bbe5a6eb339db5eb2f754fb1d93db43b0528dd29254ea7c2b871fbf2e69b0b71bb1d14167665c080ded4d7879065999a9a3a42110d87a3f3c3eec71d771c6fbef926ebd7afe78b2fbee0b9e79ee39b6fbea1a2a2025996e9ddbb37a3478fe68c33ce60f0e0c1dc73cf3d9c77de792de45cf0e79b38e383959c5ce40333ca8faba21dd645d72d64f9e7cd33df153220fd3a8244105d565686c7e3c1ebf5228a225eaf97783c8ea6690882802449646464601806656565f4eddb37ede934ba15e3b32dffa38bbf07b93d5c84280104045348cc1516c05035727b66102aedc1675bfe47f77e7b210bed2faad5340dc330a8acaca4b8b838b95621272787030e38804d9b36b17af56a323333f1fbfd00489294b6ee96a611ff602efe13a6600483b8060f44cac840edd58be03789e04acecac2d3bf7fe278c3441837169eff0fb1d34e46cecd4dab1c48d483695a646767b748cbc8f08265128fb51ea0ee6a4ae75ecb698f4679e7dd4f19e857c18c316ff66dbf4ad96dd191eb63c18a5abc6e154595a80919f8339dc44d585112625345949525412ccb4291045e58504a5520ce273f5433b8a0f994c4f66c317ffefc943ab495b6abd9f2d1744e9e19e6838fe653e455d082c55c71c41fb82e7721f71e91585838eddf9fb06c4b1999bb78d1736196c4ba5a83ec4c273e8f8c4b15b12c08c54c645927108852e84b3d72b8a7fadb9ec6afe94f4db97fc6ad5c7dfdad691fbf60c10200aa963cc48853afe5ec35cfec325d7e8bcfea6834caa2458bf0783c7cf8e1871415edcd98b1858c1bb31ed6ae44734ee3ab551b79e18567b12c8b5028c4d2a54b1932a4e554d246dba64bba3ed359bbfe52f7149bdd439b23001dd961a6bcbc1a4dd3193d7a38ddbb77a1a8a890dada7a229130c16088caca5a6a6aa344aa36fc2c85c78c19c3dcb9731933660c4f3cf1044b962ca1b4b4944d9b36b160c1022ebbec32727272b8ebaebb5a0dfe01568675fae5bb125f44277b0df127d3e2c1e55c76e2240e3df410468f3d9a9756ee98de919797c7ebb74f65d2118772c0febd197fcb8e9d136235ef5238e034ac0ec838fb3fc57cfaf70b18b1df680e99308ec9172cecb03d3aba0b50341a251e8f27837fcbb2703a9d646565e172256cd2b89e23232383783c9e5c689b0ed5b12d3468db28e8eec354eab0e2127bbb8f6498e718f6f11cc370cfb138f51ce2522ddd7b64d3a095511ddb9296ecf5ebd753535343341a451004ba76ed8ac7e34110041c0e074545450c1f3e9c6030c8aa55abd26a103525be662d6e4dc3c84af4fad7bd3f977879394a76369ee1c31044918c91fb27cef3cdb7506fbd83eecfbf882f1627b2b263ef62501485bdf7de9bacac2c2ccb6af6671826822860fe8c71f8bcbc3c3ef9c7348efac3e18cd8fb4066bc5792f2d859d7cc61da7f6724823100d1c161e7cc48a6b7e7cfa9ca49e5dbb1ea2f387bd228c68d1fc7a84967f3654dac99bca6d747ba1497c5c9cd7470cd94224e3fa40735218392aa382f7e564669759cac4c27dd72dc94d5c5e9d3d58bd7a9b0aeace514abf66c71c8218700f0fe19c700247be79aa6015c7fcca464daf8b143c8cfeff2b3edd99447ae9ec3c52fcea0c89be85051bc45cc78f1225ebefa1100cefee3e1840c93630e3b84536f6a7d8797ce326e68016a7d093db255ba652b14e4aa14e4aa74cb92e9ea5771d7ac62ffa14529f3b7676320a50d36bc702d93264de49083c773d0f8e378e9c7f46c172efb9813c60e67dca19338f78e779af58eb6551fa988562ee0a4f1fb32eed0494cbdeb9d66699da9dfb6fc69e7b4d54f1cc9d8bf7e9d9419a97a959e83ce6557cddab9faaf9d9b029433fc02a2751f27bfb737a2918e9fef49cfea74304d939b6eba8992921256af5ecdc081039938711c79b94320fe3291cc9788661dcea8038733e3ae7bf07a33f0783ccc993387ad5bb7a655465bd740d37b505bb465d754f25bbba774e6dab1d973687704a031886a6f87991e3df2983b7711871d36129faf90502886280a98a6c9d6addb0846257ab9375133ff3e7c834ec53bf4d44e2b3d74e850162e5cc8b871e358b26409814080fafa7ab66eddca90214358b26409175c7041cafc8f9c3b9a63f7398871878d67fca17fe4ec5326e216132ddaff9c740ac3eefd8c9943b3096e7e8d217ff81ba7fcf85832ef8743af63eecd0388d77f4ad17eb760dcf61612b0ead1fb1970fe23081d900130a0e00d3ed8b085be4e997045c7a7db40fa7504895e744551906539197002c8b28ccfe7c3e974d2d0d0402412411445545545d3b464e3a03d02f16abc5e274eb745548fe011bbd2cf3b1245dad1c3bfa5610d1b8da564bbba9099e92010afa68bb36fbbb28b8b8bc9cece26333393ae5dbb120a859a354e044140555542a110cb972f27232383bcbcbcb41781eb5bb7226667a357552148128822d52fbf42f6f1c7e1e8d11df58844101778e431dcf3e6e308844000a724515bd6b139e5f5f5f5343434a0eb3a9224e1743a11048168344a2010202b2b9b68349a6c8c758677fb5fc9bb57f6a561e3b3ec35f14a6e38f295568f9b5315e1fbeede9472daf3e754e59cf760ebbefdef13a7a24e7b87cf8e2fa2f8f5bf70d4942759b3605a32bde9f5912e995e05b72af2faa2321ae2165e978a5312712a22c3fbf938b05f06b7cd598fdfab525e1d41374cfc992d1759b7678b46fef8fc5b909797b287eeeeb7e6026019016e3cfa400a6f782d99d6597b36e5e5ca304b7b365f649b59781ee1cafd80bb79f6fd8fc96b43bf9f83288a4c19e6e19f9face7dca3fbd13f4346b3a0382af0c6e7c5fc653f3f8a927aa4371d1ba7b241f723fecadc3fe700d0b0fe35861e732ba7ac7cb8dd7cff3ae912bafef5035e9ddc870d6f5fccdb4dca6aaf3e5ae3e9932f2477fafbbc3cb90f1bdebc80b73a20af351ddbf2a79dd3f4c85aaa879c4bfd9d9fe19305bebae53ef6bff94576559fac53817027961ffd34ff1edc5da6a47d7c3a7ebe273dabd361faf4e9cc9e3d1b00bfdfcf15575c81dbed01202eec45cc338848431591489cc9938fe7abafbee2c30fdfa3baba9aebaebb8ee79f7fbe99bcc6c620c0a3ef7dc410b7d2ee35900e6dd93595fcd6ee299db9766cf61c76d92e4063c7eec33bef7cc60b2fbcc7de7bf7c7ed76118fc771b91c38dc5978aa16905df918f9b112822b365015d5c83de04cc0820edeba5455253f3f9f65cb96d1ab572fbefcf24beaeaea38e8a08358b76e1d471d75549bf98fb8f335969fbd84799f7fc9fbcf5dc953ef5ec79217ce02e0fe1faae9326d0affd97eac57ac6b9677c6d1899e2dd5379e4bb2cfe5bee23aae2fcae4b6d91bb8f1db011d920170e6f03ca65ef857ce397e3253261fdc213bb4467bd3810441681650366d0488a288c3e1c0e3f1100a85300c23b9b353ba4896822ceb2085c088621a06c2f6721b310c83101b7110409215242bbd696193264da2aaaa8a929212264c98c0b66ddb505515cbb288c7e3ac5dbb96cf3fff9c65cb96e1f7fb93fbeba7db00b02c0b291e47faa90441551154156755259457c09ddba7282cfd9e8c975f4d7c16004b043ade5bdfd858a9abab4beec0240802814080783c4ecf9ebd8846a33f6bd1fc9d47f60120b3cf19c4eb3b3f67b33d7f4e554e2adf9eb9ba8ecf27271a7c7d27cfa0ee9231c08e0640d3eb235d0e1890c5c22565ac2d0dd0353f034991c9f73b10449186a8c9c2b50d88b28c2069988681dfa372e0407ffb827f0e96cea3e71dc237c3eee0c32bc6247feeac3dd32cf467289c1e866130fb9b28878de84f7d559c7925512451c4ef123868580fde5ebd91abfbfdbc3252d920b0e903a64e7d9a9fea7524512052b50e78b8dd7c8f17d7f3c5a45e00f4fec3edc09c645a7bf5d11a3357d7f179a3bc23ef027634f07ed9fa05d93580fb4785b9e6b3ad3c3156e1aa7783bcf160ef0ecbd9554c9830012352c1dacd51eeff3cfdd1a674ecb0273dabd3c1344d0e38e000962d5bc649279d44bf7efdb02c8b584c231c8e1289c48844a284c3314c138e3862328b177f4ed7ae5d5bdd09a8b506617bd7403ab465d78ec8efccb563b3e7907603209da92693278f63c992d5ac5bb799dada000e8783ba80cea8228d1e153329307e2257860c234849f13f283315ba1ed8b99180bcbc3c366cd8405959195dbb76252727879a9a1a0a0a0a5a9d57bd33d9452338b16804534e3d8682de138084f31b96c5f31fcea3506d3d68cc927704c3a7dd7610c7dcf40517dfb592e5591772c8f621ed8ec8b8f1dda51cfbe5c7bcf7fa2cf69f398fd5f3ee48d3022d49a78e1c0e078661a0eb3aa22836dbe547d334028140724b554110300ca3437bd2e7387ba0d59ac4cc720cc1c2320c5a34f00c0197e2401062e831991c7f8fb464abaa4a767636e5e5e5442211144521168b251782af5cb99268344abf7efde8d5ab171e8fa7430b81e56edd30ebebc95fb36341963074085293e09f7d87c3c30fc0e55727363e974462311d293727ed721a49ac03309353b19afed65ee09fa74a94c48da48f19f11224b5f990bb4b6cb4bb84652516656e7af562ce9ef52300a31e7f8dbb07677362ae8be7b606b9b4b0f56d1bdbf3e7d6ca81d4be6d360b5205849dfca3e9f5912e0715b9c8cac9c48cc7d03403a72a326a908fda90c5baf228a260e25444e2511da72cb0f790ae8ceceb62e780b93d5b748457af3f9267adb3597cf709cd7eefac3d9b72529e9ba73607b8aacf8eeb3d50f26fdc7927fd6cbddb63cee2327c053d50158118024e8f0816044c0bb74322ece9ce8265db52be102c1d1ba7b2c159a74ce78cb7bee794bdf330b52aba140c4e2b5f5bb4571f1d6557d46f7b4cb8ef622e3ff6294a6f590be3ff4e4fc7eedbea3a11a49accbdf758aeb9ea45ce7cf322002441c02431cfd8325b8e6ea76b873de5599d0ef7dc730fe5e5e55c76d9651c7ae8a100442231c2e144e09f6800347e8e939bdb8dfcfc6e1c7becb11c7ffcf16995d1de35b033adddf321b55d3b227f575f3b36bf2ebb6c17a046468c18c4c9274fe4dc738fe19c732673c2514390d63e4adfac2de415ba110add787214fa6607a1f83e4abe7cb1d3caf7eddb97afbefa8a030f3c90b163c7b272e5cab45e82f5ea8255c9c77e7df13c14ef8e17715cbb4f2e57cf5e92fcbe7149cbd5f98d141c762fb12fffc6dbd7bfc8c85bcfe8b80c2bceaa2a83a163fec8d577dc4dddea57dbd57d673a5a478aa2e07038884422c920d3344dc2e130151515040281444fb824255faed5d670fece6438b2c9318652d9508e2886d9165cc1dc75ffe483358f6eff7b8ce2ea45b86427a1609c6c7d28198ef61b6c90088e6559a667cf9ec4e371aaabab59b16205efbdf71e6bd6acc1eff7939f9f4f5151117ebf9f6ddbb651535393762fba3a700081ed5371044944183e0ce9fe7b1289975d9508fab73702ac59ffc070bb309c4eea1415a97fc77b8a62b1587261b36118dbe7ff1b689a462c166b730bd62bf7cee6fa979625bf2f7be97ab2f7beaadd727b9ff0180b162c60c18205c907c1a5f71ecfcc3fdfc8ba86ede3fe96c6fc67ff96ccd3916b22491bbe7df9a02c6e7c7f13009bdebb11ffa0cbda97d70e5dbd70c2b8eeb8dc0e74dd44d70c16aca86365699858dc40b62c26eeeda75b964a51a18fb1c372c971b7f48bf66cd1946c45a23cde7a1d7df1d09fb969d901ccfff725ecbc76b053f6dc894bfe7e228f9d763deb02093db56031379cf61827fefd920ecbea089aa6b3b84cc6e356280b9b94472dca2316655193f288c5d6b089d723b370b394d27f3b62e39dd91a33e9599068f42c7ba17d7f6fe4c27e3e6efd2831cf7cf387b7364beb4c7d5c3ac0c72d73133bcefd34f7a69f2d0fdaf6a79dd3bcddcfe34fc6b35c70e5022eb97b7c5af2db63ee92fae4df672b3afa0e009189d7beccdeab67f0e8ba442ff0389fca7f36259e453f7d7873a774da639ed569a2aa2a8585859c78e2891416f6c4b220188c100a35fe45939fc3e1c448405e5e3e83070fc6eb6d7fea2174fc1a68ed9edf965d3b227f57dbcfe6d76597ed02b433aa9a081a7bf6eb8fb5fff96c2cfe3bc3f6d541142162a00635f6ca0fb2ecc7bbd9844cefd19debb992659968348ad3e94c7bcffaaf9fbd9efb6ea8c6a50a44ad1c66bcf0af64dad973fec7ca732f67e4733a4e747a1c700d2f8e687d0ea0a476e78e1126177f16e5dbe70b3a2cc332a3dc7cfa3154c605b45094b36eef5c63a82375d4b87876e3c68d406244a0aeae2ef93230455112537442212291087dfaf4e9d00bb50444c6149cc66b9b57426125f9bd444c3ea27197630bc8cb33a80a46a92fc9e5b89ea721a4f93a0ad3348946a3d4d4d4601806595959545454e0f7fbc9cece4e3610b2b3b3c9cdcd251008505c5c8ccfe74bebe62a3a1c88938ea0eccbc5b87bf4c07bce594840e08187d06331183c08fef92fbc575d8eb2cf30c2871f46c327f3898d1945561aa34ecdecb4dda6a228224912922435fbdcf498d638eb7fcfb1ecfc6b38f0490d07319482913cffbf333ba443238547fe83e7abef62da1fc713969c601a0c1877328dcbc93a724d34d2966f9ff7ca335cf8e7d319ff808ceeeec733afb4be58bf235816ece30f503a308fba609c986e61c52cf25c023ea78c53b21044812cbf9b2cafcaa08c10d072e7a9f66cd19407ce18c7c4710793e5925a0cd54f99f111b9030671f4613b72361ed3197bee4c8f89f7f1dfca195cfa8709c414154d7370d4b497b86162ead1b4091326247568fab9237cb2bc82c29edd7138246455c2a90848db7704d1740b533071382d94ec2e2c5f5fc63efdbbb490d1111befccf3779ec199e3469355904dd111d700efa7a5f7f9ff9bc99fff740ce3fede857ee3fe8228ed98b5df99fa98fabfc739fd846319f760578a264c0376cc5fef6cfdb6e54fada55d7cdb7026dc54c4d4ee9eb46c908a3ba6edcba1539e05e0eaa979fceb5fffa2413c0ea0436f011644170f3c3e85f167dccf258befe2c1999772e2d11398ddbd1b830ebf0278b6c3baed29cfea8e72d24927f1e28baf3268f08184c212a130c4a27122e130c1a041386ca2e9120b167ec4902183292a4abf03a9b3d74053dab26b47e4ff52f6b3f975100a0f9a6e2d79fbda9407344e29e968036067d6cc7b0e65d3031c3051850d01581f04ddc2cc51f8e8a742f6bfeab34ec97df3cd37993c7932b9b9b93cf8e0839c73ce393f4bcfdf229da9a3baba3acab62f5c75bbdd381c0e044140d33442a110a669d2b56bd7e4769a1dc1b24cd6567fc3c28a27217f3ddd727c781d6e040182b108dbaaeaa1a21fe3f3ffc2809c031084f41b00151515c905bebd7bf746d3346a6b6b292f2f27168b3168d020f2f2f2505595dada5a2a2a2ae8d5ab177ebf3fad868c1e0c527ed915f87bf546cdcd41edd58bf8f6774e3445edd58be0774ba82d2e46b9e526727af74296d35f52535353434d4d0db5b5b5a8aa8acfe7431445eaebeb0987c36465652108027dfbf6fd5dbdc9bab39896c5a2a525fcb0ba122db717dedc5c8614386930246a823a7a2c8e08d45754a0d46d61df41f98c185240275f16fdbbe53f8b2b89fabae3754a78dd226e87882c8b6059c4758b50d4a4216c10081b740d6f66ca81ad4f03fab531f51a90b311812d0bff8fbdf38e93aa3a1bfff7de693bdb975d96dda54a074510145050b1979f60890535961863621235315163f226197d63349a6acc6b346aa2d1d862c548ec0a88802e024aefb8c0b26c2fb3d3eebdbf3feeccee943b33776667b6c0f97e3e303bcfa9f7dc993bcf73ce739ee362ee2d1e76aeb9afafbbd5239e5f780c8baf7a9d7ffcbfe119ab331439efb1c71ecb589d8723070e1ce0a597fe8f33ce18c4a8aa2aeaea4a69f38ca5d30b8a52438e73279ed62dfceb99f73876f637b96ce1d5e2392fe855a6cf7f207351809231e1b4ab59ffae958f17ddcf9c310ae4c8d0e447f6fa7178d30f1d15525a7d3e5f4a33d58712a9de234dd3282c2cc466b35153534363636397dfb9c562c1e974327cf8709c4e279aa6a531ae12634a6650c02ff868ebbff972cb27786dfbd0340d67a09c91d2799c3cee62ca4b8692ca06705996193c7830279c70020e8703abd58adfefa7b4b494402040636323e5e5e5141414a0691a252525e4e4e4e070243f632084353f9fb25fdf43fd4fff873caf17a9a010396a5f85a641d3f24f68afa941baed47140f1f9692f21f72f5096d520e0402f8fd7e6459261008a0aa6ad78a8cc01cb224317644298d2d1e0e36efc74207f53915149714e2c85769f1b969da77805c4f1b1543f23962788950fed3607f8b9771432d58ed328579560a9c320eab8c8646a74fc322ebae6cf956a8afef3fc7c976d63dcb3997bf88ac79699787f2bb171eefeb2ea58daf650967ccff31eea2d3f9e81c73fba7c2f1fbfdac5ebd3a46fed1471ff1e8a38f525d5dcd9ffffc6766cf9e8ddd6e8f09033d6bd6acb4fb7e38a0280156acb89e5ffc02e8f441c33a2afd0acbb65e4fc7e0e3b860fedf0127346ce4ecd1fb59fefaedbcf46f27975eb6b0afbb2e38ccc8581420331c79fa15ac0968bcbff46e4e9d6d054152fe8000002000494441548746d301d8ab4e624a5a3582d3e9a4aeae8e40209052bcfafe48c293fb0e1e345547b27ba4695ac429b9e5e5e5b8dd6e7c3edd1fd76eb7939b9bdb155927dc3dc50c211f768fc78345c96156c5858c6d9a4b6b47936e78e4955056321839e0a0adb58d9c9c9caeb0a466b0582ce4e5752f79873632db6c36860c19d2154e5392249c4ea7e9f0a5e1382a8650f6bbfb69fee7bfe878eb6d6c95437014eba7f57a9b9bf0efab459976348eebaea578f8b0940c8cd0f8d7d6d6b27bf76e0e1e3ca81f5065b361b158ba0e632b2b2ba3a2a28240201013b94960cc90b23c4e3e6e24b5f56e5a3d2ad69c00b90e1faaa2909f1ba06a643ec5b9c5540ece23cf99fe81848702e93e6ba694f8d8fdd53e664e1b4949a1ee02e49425544dc26dd728b241be45e28b0dfb19696f00aae2d6d59be4557d8f251f65777f446f612f3a898f96ac4a9e310ed75d775dcc333d373797fbefbf9fbd7bf762b7db99356b16b7de7a2b53a74ec5ebf576fdb6aaaaca33cf3cd3e36b1828a4f33d9124998ef6e379ea91a718e16c23705063c397797cd6b001e7502f3b36d43161480dc57e853d9b6c2cdf3c84c1331bbbf6dc0d6432a1c3087a8fa42e40e164ca1da8facd67a87deb4f143adc34e74ee6d8afff9ccab1e99a00f0e28b2f525757c7d5575f4d4141cfa377f425465fa054be3866ee5128f467f89e89d046d9f059e790e299ca4c7478149bd00c77785ba11f9dd00f50e85f4f66bb1545e9325632f9000d0402789b9be95cbf117f6d2daaa661292bc5326e2c398306e1743a539af907fd07d4eff7d3d8d8487d7d3d2d2d2d783c1e1445e9da83e1743a29282860d0a0411417177719076245c03c8aaaa16a109ae697340d59025916631822dd67cdde7db52cdf78904ebf4a5eae03bbcd8a26cbf8153f8a2f40b1c3c284aa5c468e1c918d6e0bb2c0ba75ebb8fefaeb696d6d45d3348a8a8a78f6d9671933a687f15c0f01d2f99e288ac2ead5abd95b53833f10c066b33162c4088e38e2081a1b1bd9b469139d6e374812a5a5a58c1d3b96cacaca947f4ffa233dd56104bdc3f4f90f2436007aeaf623488ff02f50b22f8eb8470281205d5279d60804872be27b921a62bcfa3fd3e73f903cfc8a99d8f282cc12fac2a4eaf623100804a990eab34620381c11df93d410e3353048680008c5b2ef10cabf4020e80dc48fb440901cf13d490d315efd1fd3518004fd17718f04028140201008046611a145040281402010080482c30861000804028140201008048711c2001008040281402010080e2384012010080402814020101c460803402010080402814020388c10068040201008040281407018210c008140201008040281e0304218000281402010080402c161843000040281402010080482c30861000804028140201008048711c2001008040281402010080e2384012010080402814020101c46587b52b8a4a404afd78bdbeda6b5b595dffce6373c3aa11ade0456ec868e06400b2b21c1a032387f04ccee51bf53e36de0b346a81c049700f9bdd8764fd909ec014e0ebeaf0186a559d7bbc08a3638ba001624c9bb1ff86700766d07d5078e52185b053380c2a8bc5a9cf7d1af89f218d595282d5e1de17f2bc001609d1fea3683e20d4b94c092032327c305c0785d9431a4ea0c562610080402816040a0cd889b7443f50ceeb8e30e0a0ba315a9de27f32b000dc0ae0074b611a3b1596d307468ef2affff0156d641d52058c8c052fe41bf43e18a697b0fea1a0de4e4c10e6ff27a0a815c2bc8c18f48c0036d8017fdb686ffc340169d1e9e473559363a2d593bd17964a00028b3813d9fc881d440f141c301d80c78928c87402010080402c12142e60d804d40631da8fea80409f20a608a25e34dc66531505d07c3ca75e5dfd97b4d670c0b917aabd283ba46019532b475c2fa247973d18d00ab4557a6151fb83dd019d58768053c9e721f2d372a1b4fe937d30e71ea7000e5404139c8d10b5e2ab85b6017d098643c040281402010080e117ae40264c86615da9ad035b4302c56a8a8ecbdd9ffb7814fc394ff9c5e6a37d348441a0032d00c14a751978c6e04ecb0c046605692760b008b05d040f383bf133a722010acaba76e3c89f285cbccb812c56bcb826ec894e6426b3e789a232b0c78e1603b6cce87c180dda08d9e60d4e7c38164ee5487ebb8648a44e32bc6562010f45732e96adb1f9f7599bcbe2c93d9158016a0be1102bed8b4dc7c98e4d06764b3cd72e0d3835031182e6560cefcc7c301d4f7a0fc6820bf006a5bf4fd0489284277db922440057fd00dc84ffa33faf1d2a2eb50e3e48fae2fba0ea3fc0e74e53eb714e4a815282d00adf5b01be106241008040281e0b020a306c0e62ddba0ad9998d97fd902a565705c265b8bc36a6049031417c185529ff8fc4f281ec9a4e223b0c5b89c64805cf47d16e95289ae0cbb7dfa2a4022f2009b9d2e9356f14007ba0110a2b7fdfacdd41fddafd02a405191bef13702157c6e7dd3f35e623eba02814020100804871a19d550f7d4ee064f476c82dd09230ba12c93ad19b00578af59575acfb6eb8a6e2f51ee1cc4c3737fc2dc8a69943b0775c957d47dc1b2da35dcb6e24fc605dde84abd590ad037e20648ffee8d04b65a61bb026724d8935104d8433e319a1e45c70df888af289b710b8a973715171f33f58590d057010601070bc1efa6fb02247dbf4a733d6c2d833164de0d48201008040281a01f91d11580767f3ba851bb5425190a8b604a265b32a01e58ec868002a717e88a5c9691257df87e7ffcad7c79c9f35c74c4a911ca3fc0ecf229fcf8e8ab587efe13b115d491fa6c7e1eba82ba379d1e0709b9013534ebae2f09dbb20717003450fcfaca81974803209dcdbc6ad46b3257a2642e43c95c856ce8fb26f2cbc1628bba5005dccdfa981ad8af994692e1ce9360dd85f0c17c78ebd4f4ebbaf044f87c01fc4f3eacbb26737dec0bb41b34964d9c08c0c449cbd06e30efe029c9c5dc79d29bacbb70391fcc5fc25ba7dedb95b6ee9acd867f1f4ef4646ca71ff528db2eabe683f94b7971dad1d9eae221414fc659bb41e3cb13e646bcef6d127d3feebfbc96d196ee09a3534eddc29df98587cc77aaa7f7eec3f91fb2e2e2adfc73da9c1ef563edd56b4de5331af744650f95fb940ced86c4efa319e8bf9b3d21a306808642ccf4abc506e515d9350034e035a0a9158e2f85a9596c0bb86fe64d2c5bf038cab756b1f28227f9e1942b189c5392b0ccf1438e66d982c7b96fe64dba6027fa66dee1261a8c7e0e15a147ae4997a1c0202b74faf5a84df128001c39bac60aba71e76def8e04d4977efd668c8ef07f12ba41536401ab33b622c50b0d9abe2f22cbbfbbf34e80850198fa0a9cb208aefe22fdbaee1c0dd35f875fb5c3756f65ae8f7dc59763f5f8c933c6a43628f34e58c6c2c0df99faca099cb2e824aefe628361beebdeba2aad7e1d0a3f9ee98eed2bb3bec1452fcde694452772ed26b3e390ee4fcbc03f9b32dd71065833ea6f8cb0988b9497d9cf64f271ffc7173bf9cd908ae03b899f5736f0407b6bdadfa9fe484feeddbc45f398fbea7c2e3ff6c54c77cb9064e37e283cb304d925fb4f5b478e1e79269bbc02ecde0b4755c0bcec36b574c163dc31ed1ae654e856c6ccf2234d979d5331953ba65dc3d2d31fd395e8f1260a452bbea087b56c27f1ec7d3286019a0c3b02f1f3e4a0af3648a16ded9a1e35a713dd05a92ffdfa535d0980ee55809c2290a27e64553fb436e886554f42ad9ae037e3e07b9f7577ebc0c1eeb4aaa1b0ee52587529dc5ed52d5f770dfcf464587a313c17347067cc82c9367d15e1482b3c71962e2f2b83f597c02ba7c1c6ab23eb08b1364cfec535f0abd36071b0fc900aa8be04965c00b7057fef3f9c9f914b4fcab3ee6bb04a56ae753fd7253be3b46d5c91a31b6de3277cc82383cb63cafd66dc38bef7d96b6163fa4fc3fa9f38ab5b3ea4e207545fb28a2517ace6b68a2100acbb663b3f3df939965ebc9be7a64e0760d8f007196d1bce87f33fe4f7151586f50e04d21ddb83aaca29432660013a3cdd87e9198ddf17d7ece057a7bdcae2b36ee4ec33767049b0ee71e33fe0f160ddc9ca0d74d21d67809f2dff92a7274d8891478f59f46772ce499bb834c74971e1ef68fdfa5f00987fde1e265a753fd1aaa177b2eed255acba742db7575576d51b6fdc674dfe3baf4d3f3b42b663ebaf993bf33400f272bfc7c8ba5f1220f1772a59bffa1b3db9770016b98c40601b00e3263cc607e7bdcf67976ee2b7634777e5317ac69496ddcc9797ace0b5d37f833db8e72ed9d885c6dda8acf133cb1ad3eee186d16f5b385f5c03bf3a15565d063f19b88f7ad364d7009064282c8649596ce363e08bfd30ac4a3fd1354b58249975173fc7dc8a6949f3aa9a82aac5d722e78e9ec67dd7de64bef16803a0147d53eb36f355c47004e0cc858604d180ece8fb13c267a4023e7d1f40f40a40785fc3ff998dd7df13a5df6c9a057d5523b70ce4683720153c2d508b6ee064916936586510280be0a1d3e0be37e09437e097a777cb2d16f8e01338f9653835680054af841d7e98b708d687d971d79d0a97bc02972d8551267e672d16787f199c135c41f8d399e05aa4af4edc1a744f9ab728f5eb4c87cdeb9bf9eea0efd1b8be7bf66ad5aa27b86d8afe10b97e5a09b7d51f8c2937cd6663952fcea0c6e14f67de836bd1c99cb2e8226e3df50e002c962a3ef8e46a4e7ef9384e9dfa6b006abeba991dfeaf98b7681eb7d6d6a67b697d4eba637bee9b3730ebe8bfb2f38ad5dc36bc7bc9d278fc86f2feb2cb38e7adbfb0f2d397b87de238002e9f56c9ed0df5a6ca0d74d21d67803dbbbf8136f5ffc893226309468f59f46772eb864fb9ae7c30a3c6cde32fcde7304496f946de123605f407c343a7fd9cfbde388553deb89f5f9efe5057bd46e33e73f213fcdcf96fce5ffddf883e78bc8b783bef1714cb12938efa16af7df6594cffa3fb99ac5ffd8d9edcbb0fe77f48f5c2fff0d7f7af0460d7ceef73ca1ba732fbe5055c35bbdb25d1e81973dda9b771f92b73b974c97f38c2aaffde9a1d3ba3b246cf2ca3760f553e9cdffd2f1ca3dfb6702c16786f19cc7d056eef816bee4021bb66b8c50683cb606c6cd2a4e223985b318d132b8fa1d096879a4ef8153730ca0f5f0786d94c87fbb4cb360e7a9a58baff7396d5ae614bcb9e84f943caffe492d109f3818637d0862c59b1c889e39d9a312412320cf80cdd8567621ae5870385f97a38d0edc1faa291091a0056741f1a559f29f7a04702ca098ac395f9f0d7708c66e4cdbccf541ae87dcd41379e9a9c7a54a3f0027e8fbe97a40e3d7a5496e2f9aef1c34c3b2c33d057cf76c042b7becfda19f6115214f824987f7f92fa8fb7c0fdc1df885d61bf15e143127e690105deef9ed86581032ace801f014dd1e7f9659986c607b8e3f45739ffddffe3d2a0aca5ed3e6ac73c8b63ed635cd2f23fdcaec5dedc357e3f33ed7696a560042c7038a9386371f03a75ab4f51bee2139f0fa8633f87d61450ba635b77e049ae58fc2479790b68baec3f3cf084be0fc068fc02ca57bcefd53f4ccd2dbf409ef85b6c5f3ec6373dffcbddaa6aaadc4027dd7106d0b476bebbd6c2df478e88901b8d59384d2d7f60f2ac299ce0a8e7a1157bb9ad781e335a9fee4a3fdb91c34277073e5ec4e9f85b973c7adc65a998bfcf18c5c9cf2c36ecdf835bdab9a7b89482b156befb69534c7a743f9b5a7e96b05ffd8d9edcbb798be6e1b09f44d3e58ff08327cf65f2e8ffe52f138f27a00470d84abbf2193d634eb06ce281400058c22e459f3c4c764f43189535e2507eb645133e6115be0720d96f9ba2c007c19f90dafeb9489551b27b898e9c181ff789c5a37878ee9dccab9a91993626a75ff4daf1ba79f8febe4fb971e9bd710d81874fbc33a9f2af690a2d9eaff4f3b37286214b163434344d4542429222175be6544c45966454cd84e163f4bc19017c0e6c4077b14af5a033277a94a41a15760027c7c9e7203276be1ae88e4214cfd5c6ccfb444642a6ca19a5590946372a006f2b84afd46801686b813d45faf8462f1264883bb6c29fa7c3312bf4f783cbe060f06c87173ae122272c92c09de64ac40a05265a618714b90250ab41850c8d16189dc0cdf8bf5ef8db3bb0d8d3bdfda3b7f0fb3fe591b647f8cc1ffe7456b96bcf641e98fe075e5c799261b93bb66ee5cfd3ff1fc7ac780580c1655772b0fe99846dfdd7ebe16fef9cc3624f275257c85e6333c9df2b0798649774c7f6985c279fbb3bf1fb0f2091d725371ebfeeef93a675f2cbe673f9e6b8292c5979a9e972039d74c739c4a68d5772d465f744c88cc62cfc33e9f7afa6bae055bee17e9c271adab9e4c43fb2f1cbf3bad25fe8747391339745d285b83b5f08ab3972dc55ad99d3de7a99f7cefc39b3deba0b4fd43375d3fa87b9e874174aab8b76034538ba9f9a1a48d8affe464fef9da2d661b7e9937b0fcdfa0617feb39c26792c7557bd1c962bf619f3b13291c9562bdbe5e319155c714f764f43189505a36756bc29a0c38764bf6d160bccb3c3720d2afbe7225546c9e2cfbb04797911d17826168f62ddc5cf654ef9cf10a7561dc7ba8b9f637cd18898348b24b36064ac76ac69dddaafa2f9d9ddf421fb5b3e21c756862c59f12b9d74781bf12b1e3403cdf4e3dab5e694ff7858d015ff4620dd4da42300bb03ea9be347bf711274010a1e49aca9ba01107d18585ff8f5a753ce82beaae11c04d1e734682ab85b611f59d5473e5c0e2fd8835180ce83a7c236c8dfba186e3a17de39076e369e844bca131fc0cb17c28b27c39eb087d84fd7c1ca8be0e939f05582ebbbf16db87b81deb7e783012d7a6b0f00c0ddcbee8e91adfbfc777c67b2cacf9b1a0dcb7cb87c2e2fd8bfc5ba0b3fe683f33ee2a929c967066e7cfba7dcbde0633e38ef1d9e9f735ac2bc0fd6d4f3ee992ff3cbc1bd185b380ba433b637cffb2f1f9ef7012b2efc077f5d715197dcccf87db2ea751e3c7e023f3e589752b9814e3ae31c4251f670c3ae632264466316fd997cbc7d069ecd6bf078dfa471f8041e3fd8edaa72ebe29bb9e9dc7779e79cef72f3e25b13b67fb0ee21166cb0b2ece46fc7a8891dee47d830e89bbcb76a896159a37e26ea577f24dd7bf7e1fc0f597ac1229ef9f46b00fc71fb172c5bf01e4fcfb992034ae2dffabfbfff5b5ebc70192f9cb4809d81ee87b399b18b57f65079666512a3dfb6701405ce3c11965d04f7bfdffbfdeb6da4e1b36fd7562fba2dadc225252578bd5edc6e37adadadcc9a358bfafae054a66c85b113e0fb395da7ff7e70de23fd4ef90fe78bc66d1cfdef8511b2474ffa19df9a7861844cd35402aa179bc589a27ad85cfb3aed9e1aa68eb81e9039d0b6990e5f0355855328700c46363810ec376b9ee427abfe9cbc5335c056e01483341ff03abacffad9a47eeec11ee0e976f0b6c1c24ae3bd1a4b80ff1e80c603fa6cb96c85b2f130c3a16f460e9990f166e97b3a639f6a9a99b2ede86746d46c055f6b643e6b3e4c9e0057a1bb0aa58b541dbf2fd926e896e5b0c3beaf41e9b37dd48744a4382eb9ce2b587bfc01c6bdff5eda5d3aa44834be626cfb25629c072ee2de65904c2e3e64f8f775dd3570f4933dac4402b4f87aee0dd533b8e38e3b282cec8982d173a6cf7f208b2e40361b0cee56fee78f3ca95f2bff0053068de5e1b97772e3b2ee0d3b978e3e23265f67a0159b9c835f7153bded1fb4fb773373eccd74f85a58bbef155abc7b995675090539e5c8d1d1668065b56bcc29ffc9b0a3bb402d433f01f9ac14cb0f050af2a1b5518f28646400d8899c29d7543d1290cfa1cf928705088aa0b7fcfad331186ce83efed61cf0b5456650fdd00a34d13303a00f292e80d74f861c07fccf3b7ddd9b9e33a8e4673c77ca25fc64f1097ddd95430e31b699c36cdc78cd604fdce188f4e8c0704311df918143b298ffa9d6213ddaf3fafa33d93300ec0ee88e3666b8e975ed9a2d3cffafffd2dede8924f7dec3c0ef0f30685021975d7e16538e1e179116decfdf1f7f2b45f6fc887445f5d3eaada524a78ae51bfe465dcb17cc9874051bf67d4cf59e1729291ccc2963bfc790828986caff3ef7412e78fb4799bb98c9e8670aec003603b111e4e263413f9d79b706351a86a6b91db05af450a01add06809fe47b00c265bda1d89bad37e40664cb07a9216a1f80021d6db0b740379006e046a0e65638a997a2f6f4068d4df770e6cbf724cf28481931b69963a028b482d410df9181c3a1aeb0679a2ca937921e62322cb2cc890606c0fdf7fd8335ab139d44955ddc6e0f77fdef8d1414766f6c3b6ad0184a1c8534795b39b93236566e53670d2ddebdecfc6a39ebb62e66ccf8692c59ff067bead772e498e33863e2ad14e554221928d31ec5c7bc45dfa6c1d3925a47936d15988e7e8aed67e81197cc9d23a33314f8c20e8d4dd03188b03d7e3a4e4096a06bcf83a4cf927bd157008cdaea6d171fb3c64488503420471148d6280340054f3b1c2830a84820100804028160e0939d4dc0920479f91111808e2c1913936dfbd6c4e137b3cd81da063a3a6243ad14d8721953388ce96591f13535346a9ad7b171c7fbbcb7fc696c39c5acdbba9975db96326ec434ce9d7c27c5395586ca7fa3b79599af5ccdd6242147d3a21218071c043e4db16c15bab1d6e181af0cd2730039f431095e57281250f84652339b72d34d4bb61138595ab44c42770372ca7aa8da0834f075ea2e40874e6012814020100804822eb2640058203f5ff7b30ee25162633cdb1df6ac346f169bcd8a24c52aeb2f9ff900db16be1a23f7063ad85ab3820deb57d2dae165c7de7ab66ddfc5b811533977caade4d94b63ca80eef633f395abf9a231cd93bbccb8961e8deeb3fe05fa2657b354004e27787cc6078259099e041ce6ecaf2a7a18d0e82840e928e7d16966cb26331812d5a505afcb09581c44ba3e69ba8b5307fa350a0402814020101c6264c700b058a12052b136d2610d74ef7ec18c32e3a38bf7d47fc1ea354bd85bd34053878fc6e64686960fe3e2e37f4249ce48c3326b1bb670f4bf17b2bd35de71bb19a214ddffbf5585952994cb070aece0578c4f98b2a0bb0085a32a7a04a2f0d38021beb24d82f4e8b454c37a924416af2d0b710c00f4158e0ef4cdc0028140201008048718d93100ec763d44e42184aa0558b77539757b1b717b35bcaa97fcdc62ae3de76e86e41befbcfdece006a6bd7445ea3effe932192896f5d3819b5328570620417d5bac226d236a0500dd4fde4fa4019069c53e1563229dfa24f40855b65c83134154f07a7497aa1e1cd520100804028140d01fc9ce26e09cc8084087026e5f0b1b37ada1bede8d9ca351e8c8e19a736f6774f9748ca2e77c7a7003335fb9bac7ed0ece2b61ca5163193b693847145451e2280c8579e7cbc66d2cad5dc3da862d7ae612f4bd00ab02f099154e37d9483960b74147271c2c8834dee4d07f325d01e6d1ba957a95d8cbd7a25e8dd292a5272b9b6a7d4675db007b9eeeb2a685f9fb681af83cd092eaf1ca02814020100804fd9f2c180012387206fc0a80aaaa34d436225b2c940e29c1ed6966f396b534b57829b05b38e7e42b3966f4d9480661703eeba1f23f34af1cd78c1b985b318d89c5a392e66ff3bbb971e9bd3cb36db11ecb7fa315362b30d3622e967d19e07080cfa7cf7a87df3b0bb1be5a9aa6cffe87560042764157ba411b6614fb6c2afdd17f4be89f7eab15644bd44cbf067e0fb4c4a93f19dfae4ea39040307099316306d5d5b19f7b2117722117f2c34dce23b1a2fe48e60d0049829c9ca05bc9c066e7e69d2c7f7339d7fce02ad6effd84166f13394556e69d7c1217ccb909d960f83634ed60f6abd7a6d5de7d336f626ec534e6544c4da95c812d97a74ffd5f009e61318c00d674c2e7f970b2890a4ad1ef594b876e008463032ca1d9ffa021a0a9baf21f20be5f3e9857ec5355fcd355faa36532b1079d8532047cfa09cba98454150804028140201800647e0f8024438e5357ac0630b22c33f6a871eca9d9cac7ff798d9a0ddb69dcad525fd3c6b1150b705014536677fb7e8e7fed1b285a6a8ee376d9c6d2058f71c7b46b5256fec379f8c43b29770ed2dd806c4ed8a09a8b643308fd9ef9156888ee1c60b505fde4434680068ad6fffcfa53ad3b6400c41cd8a681e2070f69ed0148d48dbeaea727f29ee4316be3f5949e8e95513dd918fbf0f464e553494ff4f548b56e814020101cba48c367dfaead5e745b5a854b4a4af07abdb8dd6e5a5b5b99356b16f54d6d30ed28883a92b9e19af719e488f4479933f31a9a9bdbd2ed7b8f993e6312f7ffee875456192f572801857f3ff322ad4d1bb9f06b67f1d893ffe6ddf73fa330a79c334e3d936ffff07a644ba40d95fbc41c3a03b1214fe35168cf63d5054f31a178648fae2584abfa51eefaf451781ed8d5026717c131260afe15d8b805a68c87ebc3e42af06760d3665083c1ff651b944e80c936dd5d287c08fadaaf3f95fa7de807a8edd8039df59199edf9306d025c87e101c90909ba0085bca37a4a4fea892e1b7a9faadc4c9d66db4e562e5db2517f36c63efc3d09ea4f961e5d67aae39dc9f19f316346866a12080482814df50df1d36ea89ec11d77dc4161a119ffecec317dfe0359700192253dba4a147b3bea620c80f22183fad400c8cdcb21372ffe464f8bd5c2a8d16378e9d977c8c97770daa92770c28cf93cf9d40b2cfd6409dfb9f55b3165f2ac4ed30640694e11d5173dcdc8fcf83ba69b9a5ad9ba790fbb77efa3a6a68eb6d60e344d439224c68d1fc1e5579e13917f6ec5345d211f0decb0c2979833000ad1b581f676220e70084dfc474f85ab0a2836e34dc0d03b4a7f4feb9708ee713058080b9d7590410d35bc0bd14a9b59652c9112675487d9ee4b51afd926badfd16d9b9525c2685c92b59b884c8e7df87d8f47b2f4447d4b257fa6c6bf3ff9e00ab9900bb990f7d91e0006c68448e60d008b05f262c54b6b3f67caa0b111b29ffcec3a5e78ee6d9a9bda62f699ca1699b656379b36eec4e7f3a7dc0da73387f113465050988712883cd2351050282b2b66e195e7505868d0d9308a4b8a696e74d3d4d4427b471b1eb783d2c1a548523152747c7c60ddc5cff1ecb6b7f8d18a3f24ac37d79ac3ca0b9e3454fe354d63ebd63dbcf8dc3bacf8641df5f5cdf8bc3e7c3e3faadaad12381cb61803e0c48a69fa1f63815579b0bf0df617248fca54847eef3c1ee8ccd763e447f68a08ad3eb40f20538a796f29fde1843602cb5622d52d89ae8dce2a1971944b55798c47b8b1105d2e55e5ddc820894ecbc40c7abc3642e9898ca144b268a215e67467cee391c9b1cf24898c84de1c7f814020100c1cb2b0022083c1a4fab2da357c77f22511b259b3a730e3d8c9a86aaca3b5244904020116bdb6847b7ff5784a46404e8e9d9b7eb09085579c832c4b685aec4fa42ccb58adc977786ed9af9bc7a80000200049444154b21545f2939bebc4e3f5b163cb768a0b4a59fcceabf83c3eec39919b1d2a73cbb8f5e82b995331950bdefe11b5ee68a77a9db7cffd0b630a87c5c81b1b5af8d7338b79e98577a9ab6b4cd837af37764c1c96607f4ad195fef53e588f3903c06603bf1fda303000a07b13b0a6cf90473b18674231efa9d21f2e37e31624a3bb344952547ead7b8f43964955994a65c5208491429fc81d24d9ccb6d96149e672126576c5f437599da9b417fe3e5ebbc9c8c4d8675a8136bb0ad11be32f1008048281411636014b8691539eddf616abead6c7c8ad560b76bb2de69fcd66c5e9cce1f43367533228355fa961c38770fc9ca9381c7a3d46f59b51fe0fec3dc85f1e7c90134f9e8e23c78ed566a1a5a181f1a32712f06bfcf3ef4f191a1700b3ca8f62ddc5cf71f6f01362d27e33eb66c3cdbefbf7d573b7eb511e7ee885a4cabf29860358609b922ca7eef563b582a2427b983ca43544fcea6ba0aadd33e4e1460061efe3c912a5c7cb4b9cbc89ea4f96ae1174710aad0018e4ef87078199711f31ca9f69a533537586ea899ead4eb5fe546d35a376cdb49189b14f6637f726991a7f814020100c1c326f00c8921e3ad2801b97dd9b72758aa260b3a5b65061b359b159d35fdc50558d3d3b6a38ffff5dc0d8f1a55cf1f5f9b4b4b48124515862c76eb171e3b76ee1e7aebb78fcfffe8ecfe333ac67704e098bcf7990dfcdfe61847c6ec84d278cbaba467ef1b3bff0ce5b9fa4ddef184601f905d0d002bb92e47502560b280a7484c9bba20845ab026ae40c794f94fe64f9325d7f345d118ea21a54d18d9c7e44bc596c33f9cdd69f893cc9ca47fb9fa7d2563a8a7ea28526b3646aeca395eb4c29d9660d93de1e7f81402010f43f321f05c8afc0f9a3618e7199e965137978ee9dcc2c3fd2541b75758d5cb5f067d4d41c30ddaf89938ee081dfff90d163625d6c92d1d2d4ca1baf2ee657bf7671fa69d3f9f9ffdc48f1a002f6d6d4b169eb2e2c9a4ced762ba3c64ea7ba7a057ff9dbef9977ea1c6ef9c10f386aea9186fb020056d67dc9ec57afe5be993771c7b46b22d25455e3de5f3dcebf9e7e33e5feaedff2728c4c7af4d8ee37ff00b6d5c289157056828af6014f3440671b9c3f0a6606e51ee05160d3463d34268aae30e70f83f1a5309458832fd1d466b4826ef4b759593c4d24d9d46a48ae024dc0d67668d9015ac8a54ad2dd82264c816f13c71d2a0171a20045cfb01ae589d7dd78f913a545b769d476b42c993c59d9446d27ba86787d48264bd46632f717b3f56563ece3f52bd9fb44fd33ea9351dbd9187f110548201008740ee32840b26114a010abeb3731ebd56bf8edec1f30b7621ab3ca8fca7817d2415554766dddcd3df7fc9a95ab3ee03bdfb9986f5d7f1958a0bdcd8d2ccb043c7e4a860ea2a5a1898d6bd771dcb173b833bf987ffceb51ce9f7f0177ddede2c2af5d487e51ecc6e259e547b1f28227f1abb181f9376fdac52b2fbd9f9d0b1b016c93614780845b3e1ce89b801515dc617243255a034d35afccf754e90f97274b37536f745d9294ba2f880912f963279225ca93a8ce54eb8f9766469e6abf13c9cdf6bb276da69b375b636fa64e3375a4da27b36da4733dfd290a87900bb9900bb988029498ec84018de30214ce8f57fc11d00fc1928321804a738aa9b932f55970b334785a28cd893dc0cbe7f5f1ec93cf73d7ddbfe0f81326f2fc73bfe7c829e3696d6dc3e7f12323031a8aa2e2eb083072c220766fdacaf64d050cad18c96ddffd05ef7cb8981ffde80e16bdf63a77fdea2e264d9914d38ed1aa87a669bcf2d27b74767ab271c9301270e6426333ec2b83aa38f92ce88a70408d74018a508a0d34e444ae358994ee447913954f25dd6c9e440827e8018d99597e81402010080e3732bf0740d3cc9d3e1bc4a7faf1283e3c8ab11f7d263156fefddc7fef03fcf2ee9f70c71d57f1e8dfee61e2e4d13436361350740770bfc78f06288a4a5b733bb985b98c3cb2904debd7d150df4887dbcdc9279cc94fbf7f2fdbb7ece7a28bbfc6274b57985238f7d6d4f1eedb2b327ca5610c030af3c1ed85ed09f2e5a26f025635fd80ac104691708cfceca3df9bf1bf4fc76f3fd57acde45135e37b25d36313399e6b8490f78efcd8193352725911f2f4e402814020185864de005055307f106e9fe2717bb8f15bdfe7d9e79fe06f8fdcc5b76fbc024996686a6e43b6caa87e95fd9b0fe0717b916d162459a2fd603bbe0e3fc3c794d3de59c357bb6be8ecf4d1d8d8c8a0e272ae5ff80346941ec9790bcee3ddc5ef253502aa3fdb407d7d4bf62ed20194017e35f146603b60b1c61a70a1483f892e2499d21f4f814f563e591b66fa60aa9fe1a17ea4c83f33bf4626100804028140d0a764de005094481ff27e8adfe7e7fbdffd011f2f7f8b271eb98733ce3991e696563c1e2f369b95d6fa56b656ef40b6c80c1a528cea5390ad16145565dfd65af20b73197d6419bb766e435534bc1e1f4d4d8d689ac682d32fe3842967b1f0ca852cfbf0e384fd58b7762b8a92e5503355e8b3fb75ad8957672489ae03b04204d0ef69a21d8de928fdf1caf5343d9d3c31279a052f4ef88d0804028140203804c97c1420b7074e9d00f353af6f685e79cc1e806c4401d2548d67fef11c3fbae37b3cfff4ef9977c6f134353423cb12014561fff65a1a0fb45035a682d2ca126c362b75b50dac5eb389d2d2626a36ee65fc8cd1d41d68e0c547573375ea29582c328140004d55b1481640e685ff3c41837b374b962ca57278454c3ffcfe00d75ef50bd6acde94d2388593340a10e8ae3fcfb680d2095757c011712a7bd00f3b76c07113e0caa0ec2be0192fecde06aa9faea371f387c18432a8c0f0dc07a0effcfacdd6d11505a81edabf0a0a825abf3507a64e8604bbf9e331e3d1d4cb08040281402018f81cbe518006800bd0ce6dbbf9eef7becd03f7dfcabcd366d3d4d084c56ac1dddec9ca256b29cacf63f2b113b03b6d280105555691240935a0e2cc775038389fcd6bb7337aca48346b07fbbedacbf09123f0fb02a06a78553f56d9c659732ee6b17fff965ffffa1e1efcbf3f2345cd286fd9bc9b9aaf6a53eabbc52233624425432a4a696e6e8b495fd3b025b65025909b0b752db09bf80600742bc6213ad123038523492059baf3479737aab327e9d9caa3a2af7068d1cb229a1eead44e5a844705e86fd109845cc8855cc8855cc8855c44013aec0c00555179e4af8f326dfa38aeb8e23cdadb3bb0d9ed34d637b1ecc36aaaaa0633f5b84948928c12509064094992d0340d9fc787b7d3c7b03155ecff702d7e9f1f7b81caee9aed0c1b3692804f41d3545455c3af29d86c4ee61c7326afbef63a3ffcc10f193d6174445f366fda4547bbf9e83f168bcca50bcfe25bdfbe882115a5f8fdb1fe3ccb6ad7c416cc050a6c5013809a64ad4469ce0aba5b5038920cb235f16942a928e3bda9f4471b007e822b1b51859384b31508040281402018a864670f4047f26c7d45e3c1269e7dee692ebfec3cf28bf2503595f676374bdeff94b2f2411c7bc2d1484804fc01ac360b9224d152d78ae255d054154f9b979cbc1c065596d050dbc4a0f27cea1af7e1f3fa50020a7ebf42c0af10f007f07a3a19553511d997cb534f3d8516a548d7d535e2f3f9e3f43496238f1acb2db75ec9908a5200c313920d0d0080527485bdbedd747b40504136f09197a4feedd76f364fd7f54561b5e98693402010080402c1214616a20029e0eecc78b59940d334de79eb5d8a4b1c2c38ef143a3b3d58649925efaf22bf208f134e9a4ec01f4009a8389c0efc3e853d1b6a68ae6bc19663c599efa46e4f3d9e0e2f830617b1bfa68ebcfc1c5a3b9af0787c28015557fe03ba11e0f3fab0c976c60e3f9ab7df7f9ba6fae688feb83b3ca8aa1aa7b7914892c4ccd9475150105f2bfd705f35cf6f7fdb38710860b743871b1acc8e18d002783a0d8c80307fa64c2aecd17fa75347c20dbf6172153de4a9d10a80d50ab1e7b9090402814020100c78b2730e80af9ffa0069f0cebbef70ccd4490ca928c56a91d9f0e5363c1e2fb3e74c034d45515472721d341c68e28be51b501595aa719558ec56ec4e3b8a1260eff6fd1414e5d1d2dc86bbc38d5ff1e2717b50145557fe830680df1f201050282da860c7b6af686c88d4bc5b5b3b625605e261b1c854550d8e9bbeb2ee4b6e5c766ffc0a4a018703bc3e88b7ed20648c84ef55e804023e625700e4eed3738d94ed4ccfe447ff9d6e1e431720252a2360b343dfeed111080402814020c80a998f02545f0fc387c34de5107bee5642b21d05c8e3f670cac967b060c1b1fce4a7dfa1fe403dafbdfc1e63278ce2f83953696f7393e374b065e34eb66dd8c5c44963183ea612bbd34e5d6d039fafd94461613e7bb6d630e99871ac5cf2391b366f63d97b3b3863d61538721cf87c7e340d3455435335ac561b0d8d75bcb9e2295e78e5294e39e394aefedc79fb83bcfeea87a6aec966b372f73ddf63c1052747c857d5ad6759ed1a7eb4e20f892ba8039e68839606387b149c1c95ae01bfeb809a3d306b125c1e94ff17786f0fb436d2752a98ec80a27130c6a19f316089aa27fc359abedaf06b24ef00b6f9a17933a8e146ab045563e0ca22181ba78e0488284002814020101c9e1cbe5180007c3e3848ca0640b6696f6da7e1601d1543ca902c76f6ecd98fdd6e63cc9861f87d016c362b5b36ed624df546669d309511470cc5e7d37dfb3545a5a5ae95aae143b0d8adecd9b99fcaa1e5ac5eb31e0d0d8fd78bd56ad7f3860c004d43d2642cb21dab6ce360ddc188fe48d16181d2e0a1f5cff3cfad6f26cf5804d81de00b40a341ba075002ba6f7fdce83752f76bbc4dc03ddd109cc93c89d242b3ff013768517b0024199cf969af00882840422ee4422ee4422ee487a77ca04401cabc0b10e86e267559a9b94728aa8a125070e4d801958e7637a5834b2828cc475535dadadcac58fa39c71c379923c60cc3e7f5a12a2a56ab958ed64eeaf736d2d9eea1747031db36eec4919783df1740d3d4aebd034a4089f8170828688a86a6ca6892397fff786806daad2c99bc850ec06187800aad06e92103c0620167985c21d6ff5f9240b6247601224ad65b7efdf1e446fffc40c043e449c0e8c64d9e455fdd10080499c1d5d71d100804024188ecac00f4530320272707bbd381bbb313d0f0fb03c8c1309f36bb9535d51b183b612463c78dc0e3f1a1aa2a394e07fbf7d451b3b316cda2d1dad4c6906165204b7474b8f178bcba61a182e25751fc1a1a1a9a0a9aa682acea86040a79797dbcabd489be47a3b593482d1f3d74abaae8ca7d78f84b377a64a708ed5a8e7f4a6e7f98ed3753562178cdded84c161b14902df3582038bc7085bd86fe5ed4171d110804024188eca838fea00b503f23373f9723461dc1debd07002b9224d1d4d002683437b6b07ddb1ec68e1f89aa6aa8aa8ac361a7bdcdcdc6f5db291a5c40e5a8211ca83d488ed3416e7e2ecd0d6d78fcba01202be8b3fe8aaaaf04280aaaa2a1aad0e1e940d1bc54545646f4a7e70e4029928f1edfde6b70f6400710088045829c3079c8303022f4e9c9f4865fb37912c9e3ad0884d21482ab1e061b9c6d76288e5356608cabaf3b20e877b8a07a7e75a4e2ef0a930b040281a0cfc8ce0a80a2404b1bfa346affc16ab570f49153d9b8e1332040797909ab577e49fdc1663c9d1eac360b854579baefbe04b22cb369c30e7c8a9fb11347b2afae9efd7beb501405bbc342436d233ebf1f34099009f803a88a8aa6828a069a8684469bbb99e2f23c0697c58fe29336a984f5cf4557f0fd7e5de10f5f90684337006439d200f0d31d1da88be00a40c805281ebdedd79f4abeae15008373187272210bb7ea90c415f6ea22e333bbae68417535f38de451dd10f411aec8bf67cc98413506beb38b6650edaa1637ab9f313ff8fd8a21c9f74e20100c3cb2130508a0b20aaeaf846189eb0827db5180003e7a7b1937dc78356fbef13043470ce5c9c75f64f4e8e154560de6bd775770c5d7cfc3e6b0214b121ded6ede5ebc8cb1e3463275fa24defb60059faf5ccfa9e7cce18b359bf872cd66bed8b099da9d12f38ebe4cdf0ba028801a742b97b0ca363eddf41ea3663879feb917c80d8be3ffb33b1ee2d557de37754d369b95bbeef92ee75f302f427eed3f5d3cd9f986b981791b7867071439e13b95913eee1f038b7682cd02578c804941f9df80b51bc01fb66a602d84f2b17004ba1111be949129a53fd3e5a3ff6e0776b443eb0ed0c28c00498661e3e18a3c883cb8d934331ed56738672c8abf11687ed8c6a1453332b36168bee166a4f449d62fa36b4c76dd8930ea7fbc3ec4bbd645336624ad27d13865e35e64aace74fad05b6d8766f4cd7ee653251bd761748fd2e96374dfa2c73d53dfcb6c8f819936925d4b5f7dd61391897b2a10a4f239723d12fff373e847010270bb6117291900bdc1f459d3b0c8b93cf3dc227e71d74f39f6b823d9f0e576c68e1b81e20fd0d8d44a454519168b4c5b7b0736ab8d1123abf0fafcd8ec76dc6e0fee7637ee0e0f0dcd2d78bd0124350f09197f40df37a001a81ab26ca5cdddc2574d9bf9ee993f23373fea10af4cf800351139639f0807fa0cbfaae9076085d38abe02e074442edc78b5281720a9fb0c8070fa835fbf519a515e157df6dfdf1e1b0148b642611e5424682309d5d5d5b8aa018399cf108bc2a207b832a420b8c2fece443403575091099787b7515d4dececee7c62f2bbc2ea77111fc3fe47f529248fbe82f0fcd5067257549fe28d43c6ee858bae0b325367f4388730bc2f66fb60b2ed4cd0edd113bf3d57d8df11d7e5eace90c9fbe24a228bf83bf45d8cca6fe6fb12dd375794cc15af1e57d46b57e1f8dfc74444576386e87c3320e1f5c6fdde99ec635fe022f5e761f4fd8bfe3b5c96b09e387d5a94e47968b6fe9e3c1fc2f366abfebec445f2eb7225c8ef8a2a13fd3ebc9e814af60c008f07f664adf6b4c92bc8e5965b7ec01ffe7437dfbbf1eb1c39f568962df99cbdfbea9838790c7b76ed63d8d0722449425135144dc562d103dd5b2c320155a5c3ddc9c1038d783d5ebc3e1f0e5b39a8a0280a9aa6a16912681a56d9c6a63dd5140db170e9c2cbb2e3f4df8a7903c0891ebd47d374d79ee87afc0a58e56ed7202ffaa16ed187954916ddff3f7a0f80119952fa13e533db4e284d413fe04ce98ccd6c75c0207477a91ee08afec315991e3e3f109e94b930643dc785fe43383f4a166ad7f0c7de15fbd605715d087aeb011add6e3c5251c4bbe421ed37ac912e171782c640927aa2c7b90b03b92b597f0c9497ac85bd7391507137757f5dddafd5541bda10e9dc17a3cf67bc7ae2c9cde08a6a97eaea08033051c11817a96039a3717061fe7a5d61f2de7c6ea4db6ef6c332a646c4048d81dc155d20cef737dee72af47d8fae27ee4449969f0fd9aabf2fe5ae38fd274cee4a903f3c2df4bd3ed4c89e01e0f7439d41b4993e469665be7ef5e53cf9e493fce2977fe42f8fdcc789f38ee583773fe1cc734ee4bd773e61c2c423281f32889c1c07adadedecad39c0e4a3c6a22a2a92a49fe05bb3f700b224d1daec614461254a404555821180340d9bec605fc376b6d4ade4c1077f4be99041d9b9a00e830dbd8990305e0168415f01b05abb5700dad1cf74880893298164edfee46422ee7f3ae5d3cd076106804104208733a3feff3316051f4caea0c09520733f64511c05d7e02d10f62076756770913d85a3afe9dae46a842bceab01a92ab8fd021799fd3cbb82d79ba1bd01465564dbb1a37a7e353d769677a5370e3d6952101f57d8df3382025754625cc5344e9dc90c4e57d4fb6c193ca176fa628229dbb848dd6088b752574df07b1d5d6080933d034055a0b919763b6164d65a498bbcc23c1efddb23cc9e7d1c63c70ce787b7dfc4c68d3b58fbf9464a0615f1f1d2d55cb2f02c4a8a0b70e4d8d9be7d0f474d1b0f80c566a5b9a995a6a6165a9a5bf0745819327404be801e0d080dec961c5adaeb59bee555aebee632aebbe19bd9bb189f1fea3117b33e78902faa1abb02e0eed4157d87a3fb53e12668008429c912dd2b00a9fafe274acbb6d21f1e1dc80778da831180c29121b7108624a8375d5c61afaeb8b9fa1d0915dc44b818b0468f295cfacb8c45c69b5c8df2e2e2d0097fe9e2d0bcaf26e952f421d28569d1c0559804415cc47e4f5dfa4b3551cfc3d0df87caf75a10898bf82b9caef82b960385ec190000ededb0897e6700001c356d32afbeb2888b2fbe908375cdfcf087d7f1daabef30a8a4883d5fed67e947d59c72d6898c1b3f8a8debb7d1deee4696251c3976dadbddb4b5b6f3e5c6ed0c2b9c4eaebd008fcf8d45b222cb36f6366ce3b35d6fb2e0a233f8e39ffe84cd9ec56156543de4aa19032014b9072215e44ef4d0a0b204f961a181429181229041b6e99f9ce828407de9d76fb64e153dfca7b725d6ffdf6285c2a2ec1800215c1c120f0e53b8c25e0fa51f4817615367a995ab76656086b8af7085cd84b9b2db4ebf361e5d518abeab5b9ed1250617c6caa6203bb8ba5fab5d61cf6757779aa1cb1651f90587062e127fe75c612b7524c9db4fc95e142000ab0d8e3a0a6e3477dc406f44018a408395cb3fe5da6baf61c2c40a2e3aff4c1aeb9b713a1d34b7b471e6d927326efc709efee722264f1a43bbbb93952bd7b16dcb6e16bffd11ee0e89d3265d45697e1501254087a7952db59fb1bbf973be79dd35dc7bdfbde417e7c76dfe673f7988575fee6114a09b6ee6c996e530d744252b81d7be028b060b47c09141792df0b75a6868841326c3a541f927c0eb5f4163e850070d241be48d841145500e58e2b4d5db7efd66ebf402fb81035bc11f7524724e21cc180717d3b33d00df36f94be04a33ad377045bdf6b4ae4cd4231830ccc850141533d1857a8bbeee4bf8d90999ea4326ce63e80ff7a62718ddd75034b354a29af524029aa07f91cebd0c2f537d43fc7c87471420d0678f0fd6c1be0aa84aaf0a4d03bfdf20567bc26603a86a222d308804b3e61cc7871f7dc4ffdcf9737ef5ebc7183eb40c8b2c316edc48fef1f88b9c75ce49540e2d67c9479fd1d0d8c2be7d757cb27c354dad1d1c5d793a4e4b31fb1a76b1bf6927fbdb373072fc109ef9f3539c7ef669e417c557fe41df346c1645515002b1f9adc8d068b2128da03f7fd46ee426745722ab15c23f93ad40207aec257d05c048f1ef4bbf7eb3797de8fb26146f54260972f2f5e83fbdb56dc565322d51be507ab23ca990adfa3259a7a05f139a1deff166bee09ff1fce1b3bab9391a57a84bd57db3d9b13a2c1a8f2b43d3cdae0cf4d3c04db03f6d064d2607ba57b74272baaf2b429ea81e57ece7b43f5eaf9027d8dbe0ea7e357bdfbbe4f3c323680d0c4330bb06001a34b7c21a7306804f8955f4ed762ba565c51c386056cb85d2d2620a0af362e49f1ddcc0b18327c7c887540de6e1c71e62cf8eaff8eb5f1ee5dd256fb1e9bfcb7058e1f3cf3732b8bc940307ead8b869273e9f9f769f17891c9a5b1b58d6f602f98365264e1fcf2fbefe47ce9d7f2e050966fdc3a9ac2c439224b4e8283b06389d39949616c5c8ebeaeaf40dbc6650d02d2a498a54e09b007f006cd6c813705b82f22e24ddffdfe2d0cb1bb91385d35f94fed07b15ddddc9d3187b00986c818232184acfa33519f52bd53a5d09ea32caeb8a7a6f44785df1f66f24baa746d710afce787920763f8496a06cba98e9573a7565aabe786369a6ee44f9a2d3c2df27bb8e6cdc878180cb60939f4b7fe9b79b205d916ffb3c7a982bea7580606a137f2ab822cb1d16ae9e87022efda5477b785c0cb889ae8c19009224e1b0388271e6c3a2c6783a61ab0733b12a1bbcb19a6c71710137fff00afeb368299d9d5e6439fe2f5420a09097e764fe82931912157567e7debd1cf79fabf9fc6bff625ae9f898b2569b95d1138ee0be3fdc43e3c11fb379d36676eddcc3ae1d3ba83b504b617e151515e308282a168b95aa8a4a468f3d82b1e3c6306af468264c188fdd698fdbb776bf9b7c5ba45fc9c5979d81a2aaecdeb90f4996910c2e2da4af4f9d368163671e1993be74d97228ce014c181d01f41500d9aa9f0910a2093d6a535e4ea401d0867eaa733892052c16dd00300affd9177efd66f3fad1afc9df8e6e0d40d746066b0e94dba03249fd660857b832a150b9c2fe8e57a72bcedfa1f7f114c368b90be38758bc684ff194cd68a2db086f2bbaaf3dc19562bfcc92a9fad2898a954ebe50dee87e667a5c7a89f0b0aae1a4ba272162f36e08573f56f407022e83bffbd39e1f579c282e98dcc49f467b5df56730aa95204bb8486f4f57b2ba122019297b7d4046570006170ea1a1b1018f1a169a5209c0813af86c041c9bb8bcaaa97c5cbb96391553bb64922471e249d339f1a4e93deadbb2952ba1158e79e90a969fff04c70f39da309f6c9129ab28a5ace204e6cc3b0100bfd78fdf1fd067eab5a0b1e37460b19adbdbb065cf6ecefef826765cfe7a847ce8d0726efdf155695fd397bbb7d3dcda02b9e6fa810f3d04a82c41b8add208f802506c8392a0cc0bb4ab710c0012af00f487d9fe6842877f75b481121d3a35ccfda787f1ff13126fa6dd48113753573c65ee97c42adc7761ce95e89706f932ad2886f7ef9744f62dbaefa1314b264b8491416634339eea35269b6d37aa2f7ae37c32b9517b668c809e7c9ecc8e79bae3962eae585144d8d930122a7c42d1cf1e2efd25de66f7eaf9bd3023ee8a7d1fd7c01b189e1a826ce122f3c6990b78c438c9e9b7e174f69fd0f819350046541cc1dada3de08f52b05adb602d490d008065b56b220c804cb063cf1e6ebce5163867081c0b27bc761d0fccbe850b479dc298c2e44715db1c366c0e5b5a6dfffdb9e7b8f1c507f19ee5e3b9ed6fb370cc9969d563c4479baaf5d97845d15d5b927daeda8180a2afd2842fc8b47841f183ddde6d00b4a29fe61c730a70300250f82160e1af46f495d21f8e027400de46d0426e4d416d4ab64151991ead2abddb9c9c7494c5f0bc21a4b0d778c643745d2e83ba424a77b8f2ed4257c013f53b5d12b9e4b8c2da09ffdb688cd251b2938dad99fbd0d37bd09b98fdde247343eae97de84d5c916f85c2d7b7c49c7f122e0f5fc9894acf18d9aa371d5c6447d1140c383c363f1e4f8a673765918c45016a6b6be34ffffb271e7de7bf74eedb16a9384a325454c1d5436074f27a972e788cb915d3d2ea9311b3afba9a952fbd023327c015dd72ab6ce1e1b97772ee883954e566f0f427e08d3d4bb9f1c7f752b3740d2ca88219506c2f60ddc5cf313cbfe77126d7346ce1989baf80377743811dbe5d99fc00ab7f02ab36c0d032b8a55c37183a81079b60f71e98341e6e0a5a119b80670f42ed5eba7d7d647094ebf7b28a4837a268fa83d21f9ede01ec53a16953f00460e8d2641c0570f478b80073e15493118a02944849323bf39fcc9d255de52b5efba9d61f7dc41f334f00002000494441540fccf8b69b9d8937aa3b9deb8dbe56a3fec4eb7b741fcdbc37db1fb3f2e8b474f3f5e27dc8541420c1a14daa5188924566e9cf9178b211c5a92fc844e4a8de247aac7be33ec48b02e4f4dbb861eb2c6eb9e5160a0a0ab2d2b6593216054892242449a2784431459515741edc0bdef6ee0c9a0a4dcd506dce0038f1f5ebb96fe64d9c3dfc78a61af8eb9be5f3facddcb8ec5e56b66cd0dd5ef6368356dcf5c3155015beb5e457003c34e776e6564ceb517bb5ee0696d67ececdcb1fa0d6dd009b82b1f583fa7eb3af8da3ffbd90874fbc33ed9500bf1ae0d18d2ff3fd8fef0fbae148fa5900668c4a0ffafe0cabb57bb5a009f079c06a81e2b0258483e8670374f9ca6b7a5bb2bdfb0c8068b2e10ad493bc2114f443cd3a6ac3a2ff042f409221b758dffcdbb7dfc7d449d77d28d5fa1361a448a78b9132da13e3a627eda6da566fcc82477f0fb2d55e06ee43c6a20009f9a12daf4e2dbf99e847fde2ba8ce4e197dd93284e2e83fa5df1326701573f194fb3f2688325acffd1fb3f32b799ded8b028f23a282e2eeed299cd0480c9263d320042171162f0e0c1948dcca5764709f8dcbae21fc2d7093bdba0adc094a2f593557fe627abfecc9125a3995b318d132b8f21d79a83daac418d5b57ac473a237cb66db295367f074bf77fceb2da35ac6fdaa1271c0d7c96af1b216b8ae198d8f6befff1fd0014daf338b66c32670d3f9eb915d33821ce5e0180758d5b5956bb864feb36b0ac760ddb5abf8acce0f10615eb6e51b3af8dcbdffb29372ebdb7ebbac6178d40d5d4f8aec1cdb0c2fb054b6b3f6765dd979189a0fbf59b31003abda069600f9bba3f08787d60b341f8bee946f45380a37b23db753799f06d07fd6db63f5aee437769f2b5d26dd004132d0e282bd70dd36cb9ff648368e52cd595844cf7a1a7e5d3e97f3a8abed1e72add6b48f51ef48474561cccf6a9b7ef8340902e2efd25a1423600c2eec4db8b624ad17475cbe36d82cf7ab8cc8184abaf3bd04d993b97c18333eb6dd2137abc021032022449a2aaaa8acad1f97cb9a11c5aea21d0d99d5155a0fe207c5a00a79aaf7f7dd30ed637ede0918d2f770b1ff6c3d69d30733c2c3451c908a062086cda0a5f6268008468f575f0febe4f797fdfa7005824998adc324a1c0558250b8aa6d219f072d0d3448baf3d7e457ef418fa16d9706369b3af8d37f62ce58d3d4b93f77f0d60e411155a0150557d836b22bce811992c52e469bf7580d70f765ba4fb4b23516700487a831687ae28872b53fd4de90f4f0fcdfeb71f00d560f3afa3408ffc338448a326d3a4e297de538c14b278eda7d3af50fda9fada27ca175e9751df12c912d565942fda573f597de99029a538d3ca756fde07814090795cdd7f1e120afa6144657b3e5547561d1a2b00216459c662b13062c408e6ac3b928d47d453b3b7105a3c44fce2b4b7c3173e38357eb84c531c63833d36d85e0775e5fa89b4c99862819d76f8ea20340f8e0c7799004553d9db51c7de8ebad4fae84377cdb15ab2a758da08865df5275f016805fc3e7dd370f80a4c680520bfa8cb550937d01c883d044cb282d5d17d8640a259f744efd3cd9b6a7a68f6bf05f0358116da9712d45e649b1efb7f34d939fc2b91e2994866a68e644aad99ba3221373b136d466e767c7ad2663a7933790f12a565e2fa33f1b9c8e47d1008040201c35a0b99e33c9291234762b158906519353c647e1fd0a34dc083060d221008e0f178686f6fa7b5b595eaea6a962e5dca63efae42d9b51e94703712090695c2f92361760f7bfea70ed8b317e68c878b4ce4d7803fb6c1fe3a387d0c642e188f31edc09f0ee8ae35b70f4a9a3d21f1560056032fef03d50be71f01b312d4b11578ba063adc70c678382b287fc8031b36c3f02ab869b07e9cc06ee0a926d8bb3ba83407a77bad05ff9fbdfb8e6faa7a1f38feb9499aee0285b25128ab6c4459564a19b241812f8222020ac24f41111017438688a2a838582aa2b8511cc8520419a2a80882ec3d659455bad2e4dedf1f69d2a4cd6a9bd2069e37afbcc85de79e7b73939ee79e73ee81e81ad61a95505c370570f5de9582b6ebf7b68eedeeff25e0d47f90f65f8e0000088e823a35ac9d7ffdf1fc7f9b617247a6d891bbd5d754d1ded7124288a2a3cc73ee03a057750cd9d68456ad5a71ebadb712151545444404a65ccdacaf9d027702b65563e8743a0c0603414141d4a95387b367cfd2e0c009b69d3d06c917706a2b72e532fc69861605ac7c68140e27f5b0fb2cfc57d6fa0c778f9905ea475a0380dd69d0a1909fc5aacbda676156f128009af5f47adb4d1260cab48ef66b1b503819b89a62dd363c3c7b2cb133405a8a431f8eac76084a90b5d6c11f6300785b373fcb73061519580300a7bbff590b1583f5ee7f2db2cf87bfcc0bdc273c5cb7e667fdefe6f9ccc2bf24ce124208ab0667cb52bb766dead4a9435050100683019dae30db1cfba6c039b035ff31180c188d4682838369d8a0217d6e8ba75ab918f4861c057db3198e1f875f0ab8e33b80f26520e922acf7719be640a928387bce7a57bd30e901b2dae7677a5bb9006c0186b7bfb817804cb3f50940b602ef7f405a9a352828edd051e10c594f00cad160586fb43efad3d6fed7b10f80bb2024e7324febe677b9abf5cd640538c75d0ffc151406154a5a0380e2332e8710420821ae037a5547e3ffca734f503c0d1b3624383818a3d188c16040afd77b4fa0901538005014255700105d3a9a5bdb3421f1d678ca45c7a00b313814503548be027fa658dba5e797016854c2dac67eef1938e6c33651406c0c6464589bcf14a660ac1d80cde6821d27b82fdcdb0abd3ab2dbe5bb63ab01303a3cede73facedff838dcefd28cee2e6094041d6118475149f42bfab6d54ace31b5c4a85cccb383d8d0a40d1435459a80194466e570a218410c26f2a5f8962c8b626f40f4ba44993264447475f5f01806313a0a0a0208c462321212184868652ba7469063df2005dba75232eb616e1d15104851b5182f580054e9d82b505cc7d0250be2c5cc8432dc06d4044181c3b05070bb87f6f0c7a6ba13ba980e9b8fb9434b03fd6d2dbb574d9640d468cc6ec0ed0a7b13eaad418943d88d87fc0b964171d80756008f3fca84c7f16fa73a697976d32b08e6f90722a471f14b0defd0f874a25a01e72f75f082184107e73e7a158065eba9d5b6fbd9566cd9a51ba7469424343090909c16834121414542c9a00f9ed2940b61a008bc582c562b13fdee88141f7d3b1f39dfcf4d34fecdebd9b3367ce909c9c8c6a51a97242e596bf9a1668df976b9fe0b794344a25a5d1ecaf3b7cda6657658593a7cfd06c77794a5caa54a0fd7bb2a3e49f9ccfd468935c1ffef2346cae3726f8cbc5939354331b4b5e46553412d406aed7c9b2d3f00787a3a3a9161d4dfd9dd636ea87d376b12b2a8a52d125b8dd72ab7da092cd860d9c8e767e4c521021948b2c4df5c8ba8487921d94e4ecc49ea370ee6571ee47b37b2adcfbd061deacc125733a8782b671a944285a8e8845412126b23c4d2bdf42f0599db5b64308218410c20f9a356b46c58a1589888820343494f0f070a700a0b8f40128d05380ca94b13e385ed3345455c56c36633299484f4f27353595b4b434d2d2d2c8c8c820232303b3d96c0f0e1c1f7f54d4cf42154208218410a2a0c2c3c3090e0e26383898d0d050424343090b0bcb1500242515b47948fe15f829408e6c9d818d46eb5de89c7d038c46239999994e3504b697104208218410812e3232d21e00848484101212626fff6f1b03a038f04b00601bd1ccd6a9c16834da0382a0a02082838331994c984c267b0060ab0190004008218410425c0f4a942861bff16d7bd93afedacac98a52f44f1ff15b0d80631060eb189c3308b03501525535d7dd7f0904841042082144208b8888c06030d8c7c7b235f9b1ddf92f0e857ff0630000d941804ea7b33f2148afd73bddf5b7bd6c057e29f80b2184104288eb41484888fd6ebfade06f2bf41797c23f143000387ffebcbff221841042082144404b4fcf39f868f1543c7a2208218410420821ae090900841042082184b8814800208410420821c40d4402002184104208216e2012000821841042087103f1eb634085fffcf6db6f6cdfbebda8b3715d69d4a8112d5ab428ea6c0821841042142909008a215be17ff4e8d1459d95ebcaac59b300240810420821c40d4d028062c856f84f494929eaac5c579a356bc6962d5b240010420821c40dcd2f01c0b66ddbd8b3678f3f9212a2d09d3d7b969f7ffeb9a8b35164e2e2e2e4fb5a00717171346edcb8a8b321841042e45b8103005be17fe8d0a1fec88f005e79e595a2cec275ad7af5ea54af5ebda8b35164162c5820dfd70258b0600180040142082102568103803d7bf63064c8104c26933ff22344a151140540ae55e41c14449f3e7df8f2cb2f250010420811b0fcd20448d334344df3475242143ab956e51c14849c3b218410814e020071c3916b55ce4141c8b913420811e8fcf61420f9a3e81fdecee3dc7bbaf0d9d95400fefdf75fead5ab074058d97e2cff6278bef71b131343855633f9e7eb414ef3ce9d3be7d3b6beac5790bcf9237d5b13205555edef6f54f27dcd3f3977420821029ddf6a00545575bbdc94bc999baa75a7d1b48dac1a1ee78f5d16aad2a54b93949454d4d97069f817cbb115f363626258b76e5dbed2319b350c06e742708d1d1378ff686f1ebc39b26099f423b3d9ff852d6f355673fed799cfce5983ac9d3b7752bf7e7d00c262fab162c9ffe57bbfc5e9baf2f47df5e7f17ff76c3f9e5f778ad2a55bf2e3f72fe59aceeb39290ee750020021841081ee9a3401daf7de04aaf4ff3ffe9df512dab0f7fdb1cb42b56eddba80fd239f91b48961f78de5609a017368755efd741eb7470703d68061fec81eccdd709898fef3583ca8a6d3b66fbcd59df60366f3e0fae772a56bbaba83b183c7b233c944ba2982c7e67d48bf7aa55831a00700898989007c30aa14fd373ccba6579b7261f718e25a7fc4eac327691c1ec49bcd6a60f97a1ba32a47e4299f369a2585378677e297728fb2645a3ff4f93c47de3edbe15f66075965ca94710ab2f2725db80ab28acb75e5291f79397e57c7e868c4bb6bd871ea0c517a054dd3724de7e7bb56d4e7b0a8f72f8410421494ce1f89d80200d72f95e96fef66c28467e86358c39ce3c9f66565ca9461cdac1174e9d88e5bea35e3851f8ed997a59fdfc8c00e2db8a3d51db4e830904d49e95eb7db3db733f14ffd6e5f2ff5dc12aad41e8c9ab5cd8faf3c42c7f6edb8b5e1edcc5c758215af3c4ad7ceedb9a55e3366ac3c61df2e3131d1fefee9ee1d68ddba35ad5bb7a6557c5d6262cada976524ffc3c8ff75a04d9b445ac677e3d39d17bc9c0bef2f4f77667df15e9f87300eff880deb37f0d1f02006f79aefb47c7583a758f5e3cfb90aff00553acca6fde5054cfb3bf71dd6c5f7f4a3e1c44ff9f9e7b5acfe64304ff5b106099d3ffa0eb0064debd6ada37cab819c5cf5390007e6fdca6dffabc21bdb93d02c5778fb4c18c32a86e72b9f16d369c6ff2f9e3d0da7b0349f857fc72640be7e1e90fbfaf6766d7e3df9413ab46fc3c08ff67b4dcb5b7a29a77fa4577c23ee68d381c153bea74c993205bec6dce5c3d775731ee3c1c563e9d0e14e12135ad1bcd55d7cfaaff57b30b0533b522c2adddb26d26ffcd65cd339bf6b99a97b796650179ac6b7a275422bfa3db7d5e7bc17c539144208210255a1f701483e369b4dc1fdf9a85430b5c735e4bec95b1836bf8d7df90f3547b16c542c570e2fa25ec7513cd3790900eff67908e388ef59dfb30607963e4cb75ef3d9b37684c7edaa0f788da4fa0f7169ea7a4a18147e9ff832b74df818b2f2b62c76042b56c7917c7411b5e2db73dfdceff97e7475928f2ea2ee9da318b7ef8b5cc733fddb95d6694b3213bab7a0ca335fd9972dbea71f0d676ce08d06a5b87aec6bea777e96beffbe5328e7d157b3f75c6263b7580062bb4de7d2a3f1c048fbf2e9dd6bb8df58313079e143341d3489a7b7bde5b468e6f624ca8decc5e2ace908dd2597498494be8bea298f71287d069faeb9c06bdf0da7df33ff92fcf216b4ca8f11aa53f295cfe1ed12887e742973fbd5f7e12c7896d7739c737d6fd7e6eafae35839a196cb6d5deddb537a0bfa3c42b9a756b2a45b350e7dff08dfe723ffbe1c535ed7753cc68cb34fb1f2bed2005c39f8350def7a9ebe3b5f67e1f21f295bb62c6bd7aecddaca79dab1400fb0b86f6ff6b47f9bdfdf6f05c0e593692ef75dd4e750020021841081aed09b006d9ef8210dc77d86a669dcd4732a67c70fe152e66f94c86a3630a55355344d23b26a7f4c979fb1a7f3e69e4bacef5a0d4dd3a8d6751a9746dc81a63d6a4fd7d576fa909abcd42285b1eb4f31f70e03a3975fe5eb576fb6a739ad7b2d344d23a2cabd584c4f32a57335fbb4e3be6dc7943d61e6ed216dd9d2700aab1ebfddbe6ce6b624ca3de65828be58e0c24141b75771dc5e41c1b979462983e74a9f324d2630a4446d1e5f7dc269be45d3f868f51aaa18bddd7b571855378a99dbffe047fdbdccba7938baed0338f27112d5876437e7c96b3e3b25d661c68a55a4de538f305dc13af0163400f0766dbed0adbadb7db89aef29bd3907afb0a1c34d689ac6cd1d27034b8a4500e0788c570eafe489210b397ac98c41af90767e3f9af69adbeddd4dcff8f31c3f7dd1d23e1d5531c4e700e05a9e43090084104204ba42ed04ac665ee0a935a7c9dc7e0fb7be9ab543f534cffc7e9ab75a960720180d55d500054d33dbd3b1604d53554155351414a77db8db2e61c6fff144af051c1bbf1f5abd44e5a0eced42ecdbe8734d3ba601ce9d24bf7eb62b8bd407d838ed6ea7f966343e58be8aca0e85e28236e129a8c7e34a317ec511e6f688e5c8f2f1948c7b2ccf693cf6e138eadef9b8d3bc271b9561cca2ad7c31b4290087b7eea35a13eb1de0e8203d674c2ae58cd6427be3117518f3cc482adeb5004517caff45ef60e27b29f4d95439dff9ec3df53bf4937bd26a80995f3e1c47843eef4180ad09505e9b71e4fc4cbd5d9b513af7d781abf9ded2cb5ea6ba4d23aff29286ab751d8f71d07d4fd17fe99ff4ad17839a799e4a373570fb5df234ad603b56cf9f6d519fc3a2fe8e0b2184100555a87d00fedbfc0ca9373fcdb63fb6b0658bf5b56e7157d63ef78dcbf6bc8ed3236b9762e28a23689ac691e51329597b84db76c08ed3e11506d3cbfc218f8cf985e1d3eef0699b9cd38eef37cd7e80e7ffb98dd5f387a3c7f9f8c6342cc3931f66b7533ebc755f81db1617b4703164c94232e6dc4f42eb04ee9f9bc1c22543f29c4664d58798d260bfd3bc415f7e4ec51f9fa659abd624b48ae7b9c5ffda97bd3aa0151d5ab5b677042edb622817771ca5ed406b139f8421d5f93da32203ca8615289f774f5acae4ba7f9270df74ae58f27f17b6a07d00f2726d7a4bcb5b7a0fc74631e5276b1f97a33f4ef1987e418e292febe69c772a43a54a8548344de39f4fc63a2dcfb9aea7e9a79ac5f0f8825fedd3974fa616eb732884104204aa42ed03b064fc7a9a4d1cefb42ca6d914f4079bf357f26097dbd9a6077f3a9f110307d2f67503e6d058e67f36d8695d77db013c3cb1211d9eafcea00a613e6f9373daf6fe9e193f51a6666d7a76bcd3beecc71f7f04e0814f16b36bd8186e5f6c260433956e7b820f1b7b6863ef83bc142e5c3d1b3f38ba250b57fceaf3faee960dfefa1f063b4c0745d4e7f52fd6b8dcb6db4b5fd2cd310fa53a38a5576bf0724e0f76de262ff9749ceef69cf3bef223af05b89cebe7f5da74d4a44913fbfbd0323dd9b86abcc7f41efcf83506f6eb459b59e5888d7f109d7e995f0aa07949c3d5ba8ef3164ebe8f87dab4a6648552546ff704b02a5fdfbb7b167dceae4747d3b2f5442282a042fcab2c7abe71ae7d17f539940040082144a053aab418a76dfdfec97c27f0d9679fd1bf7f7f525353fd98ad825932a0392bfb2fe1dd4e558a3a2b79a6691a8b162d62f4e8d1a4a4a4e45a1e1313e376dbc21c8ceb7ab073e74e366ddac4c0810303662030d57c110ca5d001a7364ca3ed9874f66c9956a034972e5d4acf9e3dfd93c100e0ef73989696c6ca952be9d7af9fff32298410425c234dbacf2cdc3e0037dd7493db6d8e1d3be68f5d3b315dd944f7decf905aa20dabda570cc8b6badeee2e4a21bfe08a62246077df056fdf8394339fd173d052746a0657f5157871f1dc6bde07c051cee3288cefb1bff9fb1c4a0d801042884057a84f013a7af4a8c76dfc2d28f27656aefea550f751d80231cf81a628ceb1bbef82b7bc84957f98552b1fced336bec86f1a398f2310ae577f9fc3403866218410c293421f0740e48d9cc7c2e3f814a01b9d9c83fc937327841022d015fa3800226fe43c163e39c7720e0a42ce9d104288402701403193969656d459b8eea5a5a5111a1a5ad4d92852f27dcd3f3977420821029d5f0200e998ea3f4b972ea54993262e9f00240aa65ebd7aa4a6a6de704fc17145024d218410e2c655e000e0e2c58b2c5dbad41f7911589f71deb469d3a2cec675cb766e6ff46bf6463f7e7f98376f5e5167410821c40da851a346b468d1a24069142800f8e38f3fd0e9748c1e3dba409910d9e4ce7fe14b4c4cb48f5a2c84104208114866cd9a0550a020a04001c0d6ad5bdd0e5825447125d7ab104208210255b366cdd8b2654b8102009d1ff32384104208218428e62400104208218410e20622018010420821841037100900841042082184b8814800208410420821c40d4402002184104208216e20120008218410420871039100400821841042881b880400420821841042dc402400104208218410e20622018010420821841037100900841042082184b8814800208410420821c40da4d8060031313134ecf541ae79be6e5b980a3b7d717df8e39317e97c470b12121269757b3c0f3dfd46516729979cd7b25cdb420821c4f5cf50d419f0a4c68e09bc7fb4370fde1c59d459b1339bb5a2ce82080027563dc97d6fa7b3ec87f5d42e69043583358b261775b6bc5abb766d5167410821841085acd8d60000bcf156775e1a30dbe532d3d51d3cd6a7236ddbb6e1f63bbaf3d9bf17015831a0070089898924262672e49b9ec48ff903800bbbc750b66c59b6a56402f066b31abc7ee22a0019499b18d4b125ad125ad1b2e3207ebd9061df574c4c0c4ba73c44c73bdb3268f101fb7ccd92c2eb435bd173fc6758fc7ff82280bd39f64b467e3add5af807d005d36ef074fb726fd7dbcfaf8da46ba7f634a9df9ce9cb8ffbb4ccdd7702c09cb68f670777a5d91d0924b64ee0def17fe7faae00b469d3a6c0795cffca309adc7a3b6d125bd16dd82f053c9342082184f0b7625d0350a5c36cda8fabc1b4bf8733fe96d24ecb16dfd38f862f6d60768368ae1efb9a7a9d9ea3dfae77e8fcd1771013c3ba75eb00484ffa8693e33f87579b7260deafdcf6bf2abcb13d89f79b87f1f69930feae180ec07b7d1ec23872191b7ad6e0c0d2a174ed359fbdeb46daf7b7bac153ac9a580b809827c1623acdc4be9d496afb1a4b47b64108475f9e4f635ba508b7cbbd5d6f3fd47c821f9e88e5cae10fa8dbe1099eedb2c4eb3277df0980c57d7bb3a7fddb6c599800c0e5936994a8e4fc5df1571e87ccfa8695874e121b6220f56c5afe4ea0104208210a4d910400bffdf61bdbb76f77b96cd8b061d9138a81c90b1fa2e9a0493cbded2da7f5666e4fa2dcc85e2cce9a8ed05d72995e48e9bba89ef21887d267f0e99a0bbcf6dd70fa3df32fc92f6f41abfc18a13a0580d97b2eb1b15b2c00b1dda673e9d17820bbb033bd7b0da77487b74b20fad1a5cced57df69febc79f3bc1dbe28c61a356a448b162d3caee3f3f5eb81b7eb6d5a976a0044551b80e9f2334edbba5be6e93b31e3cf73ac59126f9f2e5129b4d0f2f840e3181e1afe34837b76a357b7d64e69caf743082184c8e64bb9a3305cf300c05678f2b5a054a6c9048694a8cde3ab4f38cdb7681a1fad5e4315a3de4b0a0aa3ea463173fb1ffca8bf9759370f47b77d00473e4ea2fa90ecc2888ae6b48d82e2944a2983736ba94e897598b16215a9f7d4234c97bdaeafc7258a275b01d5dd97d1d7ebb74f99503e3c759511555cf75ff176bd85daaf293d9a66f66999a7ef84a2e49ae5557ef338fe87bfb9ebd79f58bef44d6e9bbd863d6ba6da97c9f743082184c8e6addc5158ae791f80bc14fe6d1efb701cdf8d78dc69de938dca3066d156fbf4e1adfbecefa383f49c31a9f6e9c623eab0e6999154bceb2e145d28ff17bd8389efeda74f97caf6751e8f2bc5f815470038b27c3c25e31ef398a7de53bfe3b9d88db41af032572dd231f87a316cd830b777f7c1f7eb77c44b3d99dd7f3cfbaf98ac33b44cd67ef09c7d795eaf375f78fa4e3cdbac2c8fcdfbd53e7df9a4b5694eceef8aa37ce55133b1fbbc8506f19d1933f5452eedf92a1f4722841042dc18bc953b0a4bb1ee046c1359f521a634d8ef346fd0979f53f1c7a769d6aa3509ade2796ef1bff665af0e68458756aded1d1bcbb618cac51d47693bd0da9c216148757ecfa8c880b261f66d862c5948c69cfb49689dc0fd733358b86488d77cdd3d692993ebfe49c27dd3b92241807050a5cb6b7c34b42c233b279090904842abb67cbcb7827d797eae376f3c7d27eefde42b6afdf122b7c527d026318147e6ee01727f571ce5278f9a9acec4fb3b91d8a60dad5b0f64e0944f0a7c5c42082184f02fa54a8b71dad6ef9fccd7c6f3e6cd63f4e8d1a4a4a4e4691b6906208a334fd7a85cbf42082184f0a7bc962dfefefb6fb66cd992eff24893ee3303a30640082184104208e11f120008218410420871039100400821841042881b880400420821841042dc402400104208218410e20622018010420821841037100900841042082184b8814800208410420821c40dc450d419f0e6b7df7e2b922192c5f5a351a346b468d1829898189fb7193f7e7cbe9609218410f9316ddab4a2ce82f0135bb9a3382bd60180adf0dfac59b3a2ce8a08605bb66c29ea2c082184101e4959e7fa612b7714e720a0580700b6c2ffdebd7bfd96665c5c1c007bf6ecf15b9aa270f5ebd78f6ddbb6e5f9338b8b8ba371e3c6dc71c71dcc9a35cb3effdcb973fecea2104208912fb6da697f9675ae07717171015b561b3d7a34b366cd9200a0a0860e1deab7b4162c58e0f73445e1dab061037bf6ecc9f36766fbace3e3e30b235b42082184df48b9c4d982050b02f69ca8aa5ad459f02a20020093c9e49774525252ecef5555c56c36fb255d51b86c857f8bc582aaaa3eff1f1f1fcfa64d9b240010420851ecf9abac733db095d702b5ac663014ffe275f1cf21a0695aae79c9c9c95cbd7a9592254b12121282a228794a47d33497e90a218410425c6b5226c9663b1752562b3c011b00a4a7a7b375eb562222222855aa14152a54a074e95b0a54300000200049444154d21e03819ce9c8452584104288e240ca24d972deb015fe17100180abb654e1e1e104070773e6cc19fefbef3f3232322851a2047abdde6d3a392fa84068a32584104288eb9f9449b239d600c879291c011100e48cfe2c160ba74f9fe6ca952be8743a1445e1f4e9d3942b578ef2e5cba3d3b91edfcc5313a073bfbdcfa027dee18a311c2d2393460fbccfdb8fc415ce0109bf2957ae1ca74e9d2aea6c08218410052277bab3796b02f4c7c7d319fff637a4e843d1324dd44ee8cbfb2f8f02a074e9d2242525f92d2f8ee9f93beda214500180a6695cb9728583070f72f2e4495455c56030a0691a2693896ddbb651b16245626363898888c8d51cc8530030f4bef10c58b58bbe354a809acebfbbd3f3fc65349b350c06ef7d110a3b8d1b85edd169152b56e4c48913459c1b21841022ff2400c8e6290038b16a2cfdde4ae787e51ba85dd2086a063f2d9a6c5f6fddba752ecf657ecb5739d3bb5e3ea78008005455c5643271f4e85176edda85a669848484a0d3e9ec1787edfda143873876ec18f5ebd7a752a54a4e3db1737e688ed54affa69a892d139c35cf489d3a46fb72d3d51d3c39f849765e30916e8a60e4dc45f4ab570a80b265cb326f440fe66d3cccd9730789bc6b29bf3c7f0b0019179753b3c5c71cddfb31993ea611d37f2e1f0dac5998a7f3ba101d1ded345db972658e1e3d5a44b9114208210a469aba64732cafe53c2f6f8cf99291cbfea16694216b59106d074eb3af979898c8d9b36781dce5ab85f7684c7a64343f1d48264caf51a1d51b7c32f516ca962d6bdfc6b69d6dda96deca07ee02a075ebd600ac5dbbb6d08eff5a088800202323833d7bf670f0e041828383d1ebf5582c16344d43afd7dbdb88699a86d1682db86fdfbe9dd4d4546ad4a8610f023cd500cc1edc921e8d5b90d02e8156899d19d8ef4ec274d6487171df7b69f0e27a5e6f508aabc796d2a0cb73f4ddf9b67ddbd50dc6b162424d4c973750abe9f398277d831ed8f5d64c6a0d9d0d9ae6731a39f329722b59b2a4cbf937df7c33870f1fbec6b9114208210a4efef667f35403b0e47c1a5b2b867b3c5f8ecb1ccb578bee6ec4ee766ff1dbfbad00b87c2acd695feed2d0348d8e8bbe8172e5f8f9e79f5dae1f680222003875ea94bdf0afd3e9c8ccccc46030a0288afd03b03505cacccc44afd76330183870e00051515154a85001708e22735e54eda72c61fbc0bff979e366567e349af7963fc91f1f3d00c02bdb9228f7786f3ece5a374277d169db17bac6a2691a415177f048f443cc3c7089a7aa4732e5c3433cbba5269aa6f99c86f0eed2a54b1e9fff2f841042041a290364b3fd2d77d707c03adffdf6eeca572ffd798e1f3f6f699f8eaa10e27300e0ea7d200b880060d7ae5df6a7fb98cd66fb5d7eb3d98ca228a8aa6aef0f101c1c8cc964b23709dabf7f3fe5cb9707bc8f03502ab631bd631b7377dfaedc54a33d9a36c0ba4f343e58be8aca46bdd3f63625f4d98148bf89cdb97be226864ff9971da51ea67554109aa6e5290d21841042dc58a40c90cd530d40ef32a17c74329947aa447add1e9ccb578a9b34f58a8245d3d0019a9a962b8deb310070fdb89c62e6e2c58be8f57acc6633414141582c16cc66337abdde5e0b603018ecf38d46a33d38387ffebc3d4070d507c0f6fa6add2e2c59ef2fedff99a0f0c6f665a31b94e1c9457fd9a70f6ddd6b7f9f339d72892f60da3c9eefc67f4ad3f1f7e62b0d7939bf84107069cf37f4efd8929b2a95a762e56a34896fcfa41f4f1675b67c12131363efb4efab65cfdd4bcd2a15e83af041b65ecd2ca49c09517c14f5dfdae2f4cad907c0f1f57f2fdcc59b0f4c64dfe50ceb3c8b899f174d702a33b87aafaa2ae39ac6f0f8fc5fedd3974ea4a0aa2af15146161fbe8caaaa1c593dc96d1ad1063dff6598af8b724b40d400582c1600fbdd7e8bc582d168b4de597718223a282888f4f474a74ec1b6be02e0b906e08f45e379754212a1468574ad34533e78c7befc814f3e62f7b0b1c42f361382994ab78d6251a31a4e69d9e8822a30a9b1ca631bd2f9f5bd0af94a430821721a73f763ac4e4aa3df3333685d2984fddb3671f47c46fe12d3cca0f8f9e7dfcf698e78ef67522c2adf7ef03ef260347123907240364f3500953abeccfb493318d5bd2da9fa1050cdd48aef436b1feed8dfb3e833768f1843cbc4ab44062954887f950f2635e2e559ffc77d3ddbb3b862056ab51d017ce4328d19fde3e9d2a61da5420dac5ebdba300efd9a098800203c3cdc5e90b7582cf6e640b6f6fe8aa2909999497070b0bd86c016418684b86edf95f3a29ab6e08b5cfbb52dd787d7e5e5c5cb5d2e3b7efc78ae8bf3aecfffe0ae02a6219ceddab5aba8b3204491faf192b5b0dfa3472feeac510afaf6775aae9acef2c63363f870d9064e5fcea47cf5460c18339331bdea01d98fcd7df581564cf86413474f9fe1ab5e8d18bee11493ff3ecc2395234839fd2e551b3e43f9166fb2e3fb7ef94ad317b6ede68fe9cda405cbb86428cff0594b79b66b15a7e50015cac670eedc3900cc198799fae8e37cf6d35f5c25825bdbf7e38db727502d3820fe9409e1919403b2791b07a0e9bd4ff1ddbd4fb9dcc6b14c95b37ca50fa9ce9477bf614a8eed2a7518c32f1dc6d8e7bd3eca751a9da77d4ce71cfb0b5401f1ab59a142054e9f3e6d6fe6a3288afd0ebf6300602bf4db6a09344da352a54af6ea989c0140a054d3dce8e2e2e2d8b46953beb715e27a30a64919a6fd7196feb7d7a66c6c0312db77e7b1a71fa5564410004b877462fa8ae3dcfbe632a6f7a8c3a639ff63c0f0764435ddcf5087b6b273529af3f2cc7600b49b710fc4bfcea2e97ff3c83badd839f37d007abddc21df69e6c56b276b3076540fc64cf992771e1fc5b35dbf0260fefcf93cfcf0c3f6f7369ff7bf9b777e3945b3e153e9a17ccff839ef70f7a55a6c5fd2df65fa420412299364730c00e4bc148e800800aa57af4e4a4a0ac9c9c9f68bc11600d8dedb0aff2693c95e3350a244096263635dd600b89a164288e26ae4b7eba9b0602ecbd76e62f3af5bf97cde3facfa3989fdbf4e0560e21aeb88d85f8cba8b2f4601587f13bffcf6044347d4b1a7b3e8b531d40ab5fef497acf534ad4bcee1d71f9e23ddb286894b8f628c6ac184b8e87ca799171fbef2043707653266ca9798ae6407f93d7bf6b407003d7bf6b4cf9fb6d95ac3b070c2c394517a317e4e3dce6c7e01900040043e299364bb1e3bdd163701110044444450bf7e7df6eddbc7f9f3e7494d4db517f25555b5d700984c26323232080909a16cd9b2d4a85183b0b0309f9a0089e26bcf9e3d0c1d3a345fdb2e58b080f8f8783fe748886b2f4d17cd3d8f3cc73d8f80e9d25f54aad989cb073f00ac0180ad99fcc46f56d1a684d1be5d50e4cd4ee93817d4f53c3fbc366d66fcc3d81f9e61eb5513f59f98666f739fbf347d5735580f589b746a9ac5ebfaf667a82980fde73b209e652184575226c9e6ad099028b880080000a2a2a268d0a0014949499c3b778eb367cf72f5ea55d2d2d2501485e0e060c2c2c2a856ad9afd891346a3f50f960400d70777cffd77f7ffd5ab578b3acb42f84dbd5b3b706fbf1e34aa51912bfb5700101673b77df90b1d2b33e4fba3cc9e349f8807db10947e9ebf7e59c1bf755f60c5d8fa6ed3ad35742a412fddcd97c33e4251f44c7ab44e81d32c2c53da5764d8f2e33c38ed5dba6bdf0250b1fd142f5b091118a44c924d0280c2171001405a5a9afd7da952a52855aa14b56ad5f2b88dc56271da2e275ba73221840804f7c65760c31773f9f0f479545d1871cdbaf0d4ec17eccbbbcf5fcdd4c9cff0c137ab1937f24b82224b53ab5e13fab4f4fcf84d63d4ed3c1b578ac9bb2f50aad6b3243adce9cf6f9a85e5ee77577278ec48de5d34992944d1f6bea779f395bbbd6f284400f05466b9514959adf0044400601b76d91f6c9d42fd99a6104214b617dffed0e3729d219ae153e7317caaebe59efe908e58bf97117e4ed3d37adea6ddcdd3059565cc1b9f33e60d9f762b4440917289b3b8b8b8803d270f3df4505167c1ab800800468c70f5a7a960dab76feff7348b03c7aa3245b93e1e9efdd65b6fd9dffffdf7df00d4af6f6d7eb077ef5e0062636301ebe3ba00fbe8cf420821442078e491e1b99e7893f3efb8ed31e8ee786a32e34b531adbfe1cf7eb9c07d77d6eec23edfab9dc91bbac967d7ef253ded1b4dcc7e79896bff21f08b53901d57b2a3d29894b7bf69079f12258bc771813d7a7e6cd9be7695a08218428ee5c15d06d057adbcbd751745dad9f332d5f5eeef29593a228d7eca6635ef39f735bc7fff3baafeb4940d400d8645ebdcac1c58b09552d4435b995e8468d08ab5e1d740115c7142a45518acd45ea2d1ff9f9b1b8e5965b9c22ebdab56b939494649fae52a58abd164008218408188a8ac3e3ad5cb2ddc176bfdc7da11740d179493f7bcddcff6b3a8aba6181ab719d5c4d83737928bbbc619d97b3fc615bb7b8949fae85800a0042a2a3d11bf49cfde043ce2dff01f3ff8de0a69b6e42171c9ce7b4aa56ad4a8d1a3568d5aa159191913e7fe88aa2909c9ccc860d1b3870e000478e1cc9f3be6d0aa3805c90ed8410420851741cff7e7b2bcc17347d571cef90e7bea168c98a10744556cef0f50e7ecebc67bff77cc33867bad773792a6002004b46061777ef2665df5ed4f45494b3e99cfd652d259ade4689060dd00505e529bdf3e7cf73f4e8519a3469425c5c9cd77675f67c582cfcf5d75fac59b386f0f0f0fc1cca0da330be38d207400821c4f548d354fbdf4dd777b815bcfd5575b5bdf3df620dcfb50cae07e0b2be55d0ebf4f665c5b170ec2a4fcec7a1dad773d5dfc136b6946dbee37116c7e32d88800800524e9ee4bf0deb39f1d55798b76c41976946d50791fcebafec79713a95efe94b4cab0442ca95c5d7fa2983c17ae81b376ec4683412e46300919999c9c68d1b01d039343db2a41f6458d7bbf9fd3c50a639dffe308fd810cf4145412fa6c2ea7453dc356fde9c949414a769c72786346fde9ca3478f1645d6841042887cf176c75fd334747a0d34efcd9e5d06128a0a5e4388e2cdb150eeaed98f8d6319c9f65e55cd59ebe8b17628d6650d42a8c33ad2b902a8288a1e4db3a0287afbf4f526200280ada39f2073fb36387b1e4d079aa2a0d3542c6969a4fdb486fddbb671bc450b6a3d3c8ce8a64dd18584f89cf6e6cd9b3979f2a43d20f0c66c3673ecd831fb7b9b5f1ee9c2be6e1fb3e389dbf8f3b504ba3cba9e3defb5c9db81e653718dc40b83f401104208713dd2a1cb7d73deb1fc0ea06a80fb87a03816fc6d2f7bf940c36bf95fa7780e2e1c9f5294f3ceb82fe5106f8576afdb691a0ab6bbf82ed653cdb967927dd806bded9d46f61385b2ff57146b20603def591da751b19d73bd217b9c148ff90c0001110064ae5d0b9966d4e020344d439f69c2a2d7a32a0a5a8811435212e92b57b1e7cc59aa8e1841850e1dd07b0902b600e1584f80eed831743e16a055cd7a2998810b0e1ff4cbdf1c63f26b0d006830f8798e567f19ae5100208410420801ce8f02cd6bf3156f05582dab0951ce3bf1399bcbb84bcf5d2d87bbfc39afaf66ddadf787dc857f5ffecfae2dc8e6fe91a9c55b400400aa45c5121e4a507a06bacc4c30e8301b0ce8333250743a2c61a1e8324c98fedecab18f16115eb52aa51a36f498a6ad022828eb7f9da6a1e03e38b6b59ab3c5811ad81ac501b0e98a891691d6cec8c6a896982e6f2cd031fba2385e68853d0e81f401104208215cf37487dd97a7047abd836dad8640d36ce9392dc8ba83eedc59d775675ce7bcd966bbcba3630d80c7ec1572b9c862b100961c8155f12b8bf922209e9f6936ea09ba928ca25ab0848660d1eb40a7a01a8d68aa86e1ca552c3a1d9aa290fedb164e7dfaa9d73415ac076f0b028c59af20372fc7e5faac6dddd51a04e6a51038641c0021841022b79c77fff35303e0eb73f5738e15e038ee80edbdaf69386eef691bdb31b97b5d2b8ec7ed9867dbf1078280a801084ecb40331ab11883d0679840a78102facc4c2cc14614bd8ea0f40c32a222d19b4d5cf9f34faf692a28e850ec4180ad50ef89ed23b5550039f6c78f8f32f25b72066d4a049391fc1bc61277e4eb58039d3fc72170552d287d0084104208cff2fbe41aafeb2bb90bb78e7ff15dfef97748d29abcfb476d7a7dbca7975bac85dd06df791c052dd73bcdcb380ec5494004001683018b3108634a1ae8142cc620eb45a4691852d3304786a3ea14144d03bd8eccd414af69f27119080d410906c5003abde27d3c3115548b8662063240bb98dd2bfcc9ee373169e14eda8cba951def4fe2a61ecf17e088039b3fa3f040ea502384104214254f057f5f47f4f5c45b0aee9e4ee8eef1a6aeb67797074551bc67e01a733f6e4031cba80b011100a8c6200c26338aa6610e0d456732a1a49b31878710949c823e23037358088aa68062405fbbb6f74453b07e3e994a564f605d561580adb77cd6ff4a765c870aa8aab50770a606a9d9c9b59efb3dd5bbf4a2c142052dfa36962d4ff0cfc10b21841042f8c8559b7f7fdd4c732c9bbbee6f605fea343fe70063ae96d9b673d79750d3b4ecb25911b18d23703d088800006310582c683a054da7a0645a50541514054d676d8c030a4a901e224b5226de7bf31bcd9c09992aaaa643557558146bdad68b2be705a681a2a1aa1aaaa6a09a5530ab2896ec2a0343682d16aedde9cfa32ef6aec53804c5b1a3b3104208511cb97a34a7a7c2b73ff6e5b1c04eeec2bfa78785e45c56dcc63bcaf918d49ce73b7b79f1c8af27011100682146ccc6200c172e5b1ffda9d7a1a0a119f4687a1de6b010d4b010949008cadcdd932a5dbb7a4dd3443497d32f6350546b875e14ebf36fb5ec9eecd60bcf7ac1aa9a05ebd36035cc160b19168d4b69791b7df87a5558e31038a6b96bd72ebfa7ef4d4c4c0c0035efff925f5f4b749ae738f05871306bf8bd7cf1eb1f1c3c7d3957de26ddd389b5ffa5a3d7ab64a8251938690ec3da56f2b84cb35ca54dbb6ef63454d329f61f2fc1e9e37f00f0fd73f7f2fc2fa728137d3babbe7bd1e33ebcc96f1e8410e27ae2aa23aba727e878e2aa698a3ffae8e9701e6700b26ec1da8201d5a1006fffdfd6a242717147df39bf7a77e310383c25c871fd9cfc35c0aa3bb9f2676f24e29c7fb33401f20f63ad3aa45cbc40667028868c0ccc862014b3194b7030aa3118ca942638a62ce53a74e2e61e771156ae9cd734ebdeb7f51ae45cf8435c5c1c9b366dcaf7b60575e8f361ec7861270dc28a6fc017dfef317a4f6dc46d756fceb5ecf105df31b98475f092e443df51bb752f861dffdde332451fc1ba75ebec69fc3db935c34e3e6f9f1ef9decffc73f23fa2b20655f1b40f4766b386c1a0384de7370f4208713df1a5b05f1cfac515240fdec605f0da09d84bf9be389c9f4011100140fd099348dab183f33b779072f020a6e42b68280445451151b90a651a3726ba51234ad5ad4b5078785167f78671adaae462636369dfbe3de7cf9fa74c993279fedff1a941f95141778547a6fdc986e92d732d3bbeec51ba3ff51369668db4d44c2ad56dc1d837e6d03bae24905d6330e7ff3af2f4fb6b89aad381775eebc6cc4726b3f9e0156ebb7b2cdfbc3dc23a08b9e92c6f3c33860f976de0f4e54cca576fc480313319d3ab9e535aae6a1f9a27e6ce9b4d7489ec910bd3af5e21b8cc2d3e2db3d3cc4cf8f00043d637056050e7f6a458547ab46b438556aff1e9d45b3ca6131313c3fc913d98bbe13031fde7b1eac9db9da6170faa99e73c0821c4f5c6d563321de577a4ddbca6911fbeb604f0f88c7f0aff0e7e71694a541c04440010d3b429314de50fff8d2a363636df857f93c954e0fd2f181647b7b943d937615bae651155bbf1d9cf33892b1746faf9bf69dcb03363fe3781de3bdf745aefad2b4d183bf01813e62fa367a7bf78eec571989e7f8acd5f4c66e6d30379aa4a244b877462fa8ae3dcfbe632a6f7a8c3a639ff63c0f0764435ddcfd02a91444747e7fb18deefdb9585478e70f86219dedbb8d2e7650017f7bdc83f411d59562902800f56fc444c4c8cd3dd796fe9ac6ef014ab26d60220e649e7e9fce4410821ae37ee0ac2c5a9d0eaa953717eefbe17c5f3fbdd29ec00a438098881c0c48dedd0a143f92afc9f3f7f1ea3d1e87d075e341e3b8fd29c67d8acedb99605972ac937af3fc3fdfdeea1ffb069a868a49efb3ad77aefcf788cfb1ffd1f00a51bce60c480fb1955bb14007f9fb23e4e6ae29a53007c31ea2e6ac4d662e0cc6d689a852fbf3d0158473db68d7c9c570f7efe031b7edfc9d2e71b30b2f74c9f9701fcf2dc12ea3f31ae40fb98debd86c7697fe54108210255ce01ad5cbd2fe8aba034cdd6dc5d717ad9e67b7b298aae40afbc9cc3c23c7e77afec7352fc05440d804d6a6a2a17ce5da05c85f20419032aeb01a9b854a515750d8021b4160b1ea849ef3943732d7bb0ed3dacb990ce983716d2b252244f6dd9ccc5ccdcfb8c0d3190aa0b0320acb2b5e0af33660d996ec9ee480530f19b55b47168521314696dd7dfbb776f00befaeaab7c1e89c26d7d677069741d60a24fcb2ca6933cbdf9029f7c105ba07d943238ff70e79cf66f1e841022f0b8fa9beaef81bc8ae31deabc0c049697b48467015503604a33f1dddeaf99b3eb0d367ff93ba7f6fe57d45912d74051d70000341dff0e91eac95cf3f75c35039072f50afb7efd884319e67cefe3858e9501983d693e7ffcf32fdbb6fcc27b339f66e467870058bf7e3debd7afcf539a6ae679769fcfb04f1f5c3d9d880afdbc2eb339f5e338b41acfd224c2fd79f4259d826ceb4b1e8410e27a90f38eb5ad5f80b7fe01d72c7faa864ec3e5cbd332c7751c5f39e779dbbea879cb5f71c9a72f02ea367a4444046543cbf34af804bea8b098a78f4fa542cdae28babc477c3bfaddc6f9be4bf8eb443811413a6ccf725281880a0a5dcd6b21f3226b4af4e2fc51cd215252b89aa652a76a0a377d3f8006ef6ff0d3d1153fc525922eea1a0080a0f006ccbf27963e1f1f709affe94b0f72ff940f7977caf3b47d6022f1512bd97839c34d2a9e759fbf9aa9939fe1836f56336ee497044596a656bd26f46919e375db0fbbc4f3ca8964001a366c4864e5b16c5afe00aaf93c4ff7ebc5c54c1d8a9681ae4c43de5ffe1a80c765368b26fd46bbd9af7adcb72fe914645b5ff2208410d79bfc3e02b438f3f69c7fefc759b01a8ec2ae2109a4cf29600280cccc4c4eeff98fc3270f125e330a4b890cb66efc9346ff34a14ae38a794ecf70d747c47ef2308d478c6557f9782eec57b00501e1310aa19618308751313c94508bed035588aca6d1e8f256aecc98496a9fb7fd7780c2ad43870e152808c8ef5380723e6d27f1f5cd9c7bdd799d3af7bfc05ff7bf903d63fafd6ed3082b3f8473e786d8a7db7cf30f8e7bd019a2193e751ec3a7fa961f470f2cdfc4032ee61b42e3f8f627d7b5069e96d98cfff3a0d7bc784b2767bef3b2ada73c0821c4f5c6dbf3eddd3597f1b5e0e9cb73f47376f4751a544c97738c5ffb8680e2cb733ab3df3ace764ac743fe5de4d3555eddefde7b80e0e9f8d17b3efff6fd5b8a7f2010104d80ae2425f3f70fffb0f0d83cd6b4f80e4daf129216c12f0dbfe78d2b2ff0cff29d68a9794bb3c70c05e5d577c93cb19c06bf7d49d3fa66f69eb5b077af992347cd988f1fc27c742f278f9bd9bbd7ccde13161ad535d364db2764ee7b1fe5adb7e8f66676fc64493fc890760d68d0a8010dda0de150baa55097dd488a430d80104208511cb86a0ee4af4eae0595b3c952716bc2e40fc5f9fce745400400f37e98c30b716359d6ee13540d42af86a1b3e8094b8be497e6cb191dfb1033964ce3df4dbbb064fa5648d652359a365378e8d238d26bb44337680803d585fc7dd9c4bc8519646cf8818c155f326b49066b4e981818f535218347905ea93963825fa0693385ccff32ede9fdf24817f6755bc88eed3b58d86d1f5d1e5d5fa8cb7c3a46afbdd53d6debfd8baad95faad34bc5828a25d7fcbcbec87a15873e0042082144512be8380179919f42edb50a00ae4501dcdbc8ccaed60f240111007cd5f75d2e943f47e5bd3588b81489c56046d17404998d54f9a716a6b2a92ce9fb1e73cebec6f64d3bc83479ef8859a5859e6af13ab6bcada7e5b210f45fcd4177ee38b3ab7dc6f2c53a74bb33d06d3ec9f237742c6eb61cddae75e8bf7e8d767f5660f5043d555beaa8dc22fbf4bdfccd31263fd8008006839fe7e8372f17ea329f79f8be590301d75f4a5f860cd75cfc03ebb0df8a1f1f8325350042082144e1df7df6f477df97027ce13f86b3706b12bc1dfff572f71f02a40f40785214650f54e262d5b36444a5634831126456b854e53cc6d4606efaab2649d5cef06be75544ad2c41b9fda3a954cf73bf80f9a98f12694ec758d3807e5d12ba6f62501ab646d9ff0d7cf11dec3e0c04c1fdfde174065a9d3668097dd91876164bbdd2985433e75200ac9d80375d31d12232180063544b4c9737daf75518cb7ce6744d3a5fb48e6dd634cd92eb0256d0b26ef167053a393b5babd691ff34a767f3faf34ba00245d7074008218410be0bc4c790dea802a206a0fcee9b39d6623f66a399d207cb62cc0826282584d207cb63315838d46e17254fc550f67815d635fa81cd0736794d5351ac07af5714825030ea7518757a822c0a413aebbc206cef2d18757a8c8660823415bda2a003746ece9ea7cbbf3096f9c6f55d7e45d1b015b4ddef5cb5be72aca7d3e9ac6938fc2b0c520320841042b86f96521805eb40bab37dad9a005dcbf35fd8022200381abf87528762883e54962be52f620eca449fa970e1e6b394385186b23b2a73a4e56ecaeead883e4ccffef3fbbda6f970d85cee322ea5f6be6f69d6730bfa6d2b30b448c530611086ef576268d80043582686ef7fc0f0c2380c750ea3ffeb5bda0eff8bdabbbfa58761290f87cdb3a7171f65e4b764ebe31f33927fc358e28e425de61bcde16593ddb65e51b4ec8b5951d1b0a06a66fb4bd32cf617a860fb3fc7cb793c408711ff28d8cb46fa00082184109eefb0fba3105ad0264085dd07c05d131c7ff176fc857dfeafa580080082cf851371be0467eb9f2033cc4cd4c96874997a149dc2b97a2708bd1841892365b8147b8190ab612473c96b9ac7365b38bc115a8c55d8da3e035d6c077425cbd1f1f7fba9d25887ae5c12ba1a1a55bae868f455377475dba1abda83f50d4ed1ed658523bfc2914dd97d0d9eec7e139316ee0460c7fb93b8a9c79385ba2cef72dfc1b7cdd7b0a0691aaaaada5f168b1955b5a0aa1634cd3a4fd334d02cd73cda2daa1a80989818626262724dc7c4c450a15255e2bb0ce0bb7d97bda6a359ae929898687f25dc5e8b0a559aba5cf7ad7eb738edb330d2019830a40fb7b7bc83d68909dcd1f13ebedb7bd9a7653131314e7918f1fd313fd6d2c30000200049444154bfa67f79ef57f44a6841629b44eeec3b8e1326f79dfa5fb9b321ab2fe46fcc85bcf0e779f7675a50f89f6341f69197cfb2a0bc9da7a24eef7a937161158dee743fd6477e7f2b7d91f377d9174757bc41e7db5bd03ab135cd6fefccec95d9d7bb25e308a37a2590d03a81845ea3389a61f169bb49f77422212191366d12b8bd750fe6fd9c7ba0c8c2723ddd850e44d7cbf90f883e006169615caa7c1e455328bbb70297aa5cc0a29829bbb312a76f39caa59bce1194114c70aa91d4521a31a1e5bda6a984ebd9b919423eef0b5314ce2cff89db46ead0f69ba9d3d60016231815dadc0c3f2f55a9f4cfbdac5bd9979b27dfc9ebb7273363c7721adfa9b7a7d77aeef754efd28b060b15b4e8db58b63ca15097f9c645815fc99e6751adefad176dee08dda2aae8156bd75e45d1a3da9f856b8d1bedc3a3657d0f6cf3f3312e9b47c5ad0fc0fcf9f339bbe363c6bfb992913dc7d3e3df373daeafe82358b76e9d7dfaefc9ad1976f2f95cebed7cf701bea83215185ca8e900dc72ef0426b56d884181ff36bf4ad31e23e8b1f723afcb00a73cf83bfd677b8d26e193ad8c6a549a53bf4ca3f7b8cd6c7e3d77cd57f2b139bcaf1fcbaee860af7929287f9e777fa60585ff3916641fbe7e968ecc660d8321309a1cb8e229fffe3eb69ce95dcb73171cdd91d1fa2778f7c45086548e70bb5e5e7f2b5dd2cca014aca8d26be80ca66cde4fd72a115c3dba8c9a77f4e2b1e37f02f0eb93fd38d8612eeb873766dbdceef41bb799cd6fdce175bbc7177cc7e412d61ae6e443df51bb752f861dffbd40f9f485b771027ce5cbfaf9b9d3ee6d9c8282dead77b5bd3f0bdeeef26f5be6fb380dc53f18088c1a80cb21289a8262d2a1a4e9490f4f2533c2848a8692a9a0eaaded4df44921849f88a249e9dbbca6b9e2390d460c40a51503bb2de1d68e16d47d99a81a98832c582c41582c06d20d16544d453d9d49eb8e167ac5ff805a72280c7b98d5a3b2ef2e1b426bb170ed4e766cdfc1ceb50ba9196a28d465f9a2380704168b058bc57a97dffabf9a1d04a81aa866875a01b3530d81b596c0627f59b72b58f6dc296e7d007af6ecc9c3cf7d0040daf9afedf37dba33a59999f0e101864c72beeb7bf9c027dc373f9c6533bafa968902a6d3ab9db5d00650f6d6fe98ae6cf66999aff29bfef749e90c6b100d408556a339fec36c97e9ff39f15d5a4cea689f36a7ede3d9c15d6976470289ad13b877fcdf80f533593675089dee6cc52d09f7b0ee5cba7d1bd3d51d3cd6a7236ddbb6e1f63bbaf3d9bf17bd1f98bf3e3f3fa555d89f6341f6e1eb67191313c3d2290fd1f1ceb60c5a7c808ca44d0cead8925609ad68d97110bf3ad4f2b8fb9c017e7e6d245d3bb5a749fde64c5f7edc3edfd3e7bcfe956134b9f576da24b6a2dbb05f005831a00780bd76c45b1a39f3efe9d8f29a176fe7cad3bedd9d2b4fe7372626869f5e7d944e77b6e7b646f1bcb2fa242b5f1d41b72e77d2a47e735e5a957d97bbd3a416cc7bfe2f97f9b471f75b69ce38cca4213da85db51295aad6a6c790491ccec8ae51b7fd967e38a6173757ace4343fe73aeea61dc55708e3c245eb773fedd20542ca649711de5c7182a7eeab0b40dd7bc7717cc59b3e6d175d22bb7969fad52b0497b9c5e3b910a2b809881a00437a30a58e8472a4de1e549d05bd494fa631137d868e0c7306252f9626e2743497cafdc7fd0746d0a49df72fa2e9bb01fcd2763163df3160be789660bd0e9da2234d0353bac239b311cd1c447ada59f40608d6544063fb6b2af58ded193faa15f597df0b03fff6baaf6b255764aa69d64ebeb68854c3a900ef18482be48e6cf57a7d56fb7f6b9ca868168774152caa6d7d154d55d029066bc7609d0e14c5fe5850771c472474559da628a061e1f0a123c5aa06e0c2850b9cdbb11080a0b0faf6f9d1d1d15eb7bdb8ef45fe09eac8b24ad977cd2c19c71872f72bbcbc6613517adfee8ef82b1d802db38750a1b5ebe1875d2deb74675b5253cd5469d281e7a68fa36ea4e77e167949bf4fb9305ef8e908d33a54e3f08fd33025bb2eb42edc7c9607df28659f5edcb7377bdabfcd9685d65ab2cb27b33ff3658d9e65e584580e7dff7f74e9fb3e7b7e7ec4bacd3dfd68f8d206663788e6eab1afa9d7e939faed7ac7e3b1f8f3bcfb332d28fccf31affbf0f5b30458dde029564dac05c03b6dbb631cb98c0d3d6b7060e950baf69acfde752301cf9ff30f359fe0872762b972f803ea76788267bb2cb16ee3e1731e32eb1b561e3a496c8881d4b3d6b43a7ff41dc4c438d59078bb561cf3efe9d8deef522f4f79f1965ecc93eef7edee5cbdd7e721b7e7176059f511acfcb10ec9473fa0e6ededb96fde32968da94ef2d10fa8d3fe099edaff0500a5ea3ec07f1b1602addde6d5dd6fe5e7fdefe69d5f4ed16cf8547a28df337ece3bdc7da916db97f477da7e4e4a735e9ed9ce3e3d7ffe7c1e7ef861fb7b479e7e7f5f5ef52e9d9adfc21b31e5f8ef4c08f336adb62fdb929cc96d11d66b3f28b22999577ef7693b80f7fb7665e191231cbe5886f736ae74bbff1b5161b6d317fe1110014005ad1296132aba343d663288de590e5378265ab042a5ddd5a8742096e09b0ddc7b7e302ddbb420b274a4d734eb7eb499ba40ef87ddadf10d00cb3c25f268f129fcbb62fdc269680e77f66d2f4551d0e914b79d74344d43e762c86b77c3886b5ad64800b6f4c1a927afbb6a3bc7749cd7b1065c9aa615bb1a80dab56b03a0d38773ef94ecbb457bf7eef5baed2fcf2da1fe139f3bcd9b3ba807e59fff9a4ee5427dce83bfd2d9f7f578ee5f1cc90f9bfbf8b46cfdf683d4a91885a6a6b1eaada1f4ec3293bd1b9ef35bfacf7ffb3623460c22e1a560e21206a0b8f989da70d9c4dcc820fbf48c3fcfb16649bc7dba44a5ec7330ad735500aa769acaa5e1ad006b0030737b12e546f66271d67a113aef7d87fc75defd9d56617f8ef9d987af9f25c0f4ee35ecef67efb9c4c66eb100c4769bcea547e3016b01d5e3e7dca51a0051d50660bafc8c7dbea7cff981c6313c34fc6906f7ec46af6eee0bb2deae15c7fc7b3a367fe425e7bedceddbddb9f2747e01a6f7880320f2a6fbb0989e645a9758fbb4e3790d8a6c86e9ca836ef309ee7f2ba76d3e03c0c2090f5346e9c5f839f538b3f905c0390058f4da186a39d47cf7ecd9d31e00f4ecd9d3695d4fbfbfb37a0ea7e59beb78b153750ead7e8ece7d5ea3ab8beb3de75f296fdb3df8f90f3c88c61f9f8ca47fef99ecdb30d1fdc928260abb9d7aa0b583f7b7403afe8008001e2bfb24872d87d899f20f878cfb48bd9c8ad99c49c9cc52c4a6d6a4569dbad42a538b8ab1153186dc784f7df1dc6b5d4155355455cbba9bef588887ace7f6e4989f7d475eb18d0190b50b05d0b27e2575b6995a565f02c5da5c0a4d878282ce717c006b4702a7bca996ec2a5f6bad41f6fa59a10b9aa671e870f1ea03b064c912f441a1dc14d7989ba2b3afb7debd7b03f0d5575fb9dcce623ac9d39b2ff0c907b14ef35ffbe32a517bff4793e9d9f39a3469c2bc5f7ea3a98bbbb2fe4ae7e07753e93a69375f6cfc94da399a97b95b56a76214008a2e948e8fbec3c517ea01ae0b8ef9493fb26a17162deb0240dab98f59f579379769e7e4f3cd25c73e2e9ac647abd750c5a8775ae5c8578f30e8cd5d00b49cf3352fd6b1de59cccf798f593daad0d3f2e7e7e8eed80bfbb32c65c8feeeab4e3587ce8f17f6f43987da3b1fe9d1b4ecdf16779f33c0f81ffee6ae5f7f62f9d237b96df61af6ac715dbbe1298d9cf9f7b4cc1f79c9b92f77fb7677ae3c9d5f8030db79548cb9a61dcfab2fdcfd56da8f3efbcf0fae5a24d7ca43b3574fbfbf73f75e624f07eb77ad5afbe7b8f4401cb6dfad669141fc79d5c41d51464c57ff2428aab94fdb6553b8adef0c2e8dae0314ff0040089b800800aac555a35a5c35dad2cefbca0ebc4562815e25e5edf86c6dfa9ddaf6e7580ece7f287459831be8c0da0f003577471e37a7cd1a6028a8aefa1e2b8abde950eefd2bd9b506d91bd89b2a15b71a80d6ad5ddf9d5bbf7ebdc7ed4efd380eadc6b33489702e8c1f3890bbddf0d6ad5b0b359d43df4fa3d3d37ff2c9c62f6852c2e8f3b2fd1732a899d5f176df8a17082fdfcbafe9679c3d4f70d932a099583cf6559a8ffdcc65faad4a18f9233993d659db3fdbac2c8fcdfb95af46b602accd1d6c773c27ad3ac6dbddaa7274d5444ad41a614fe3c9466518b3682b5f0cb5b6c13fbc751fd59ad4a26aef7758d73bf73ef375de0b392d7f7f8eae8ebdb03fcb9c1e8f2bc5f8154798db239623cbc75332ee31fb324f9fb33bee3e673413bbcfab3488ef4c9d26d579adc6dd80b5d01d1da4e78c49a59c51e7398d3cca4f5ef2cbddb9f2747ef32233f90f82a3dcd75480fbdfca29ed2b326cf9711e9cf62eddb56f01a8d87e8a4ffbad6c3470c26466d6e22fa8191d4bf72ed676f99e7e7f3b940c66ce5f498c695a86f37fbd4d70c94ef665233a56e6a54f7773c7b046ecfae4252a771ce7753b35f33c7b2f4752a78cf53b7470f574222af4f329ff372a77ad0744d10988004078e7aab7bd6ac97e9c99f5cba7775aae696a56e13b7b1d7b32b69b3eaa82963350ca1a01d85e01a058dfe8ac89da975bc82ee0bbfa3f7bf4e1ec3e0ad9fd15b20397e2f614a0fc5a34e937dacd7e35cfdb2526263ab547f6473aad87cec650a9164ff6caee48bb6ccd5a22f48ac765a3ffd79ecb163d8a9a0ed1f559b0ec0dbfa67f6cf953dcffee7e82b50c6ab41fcda70fba2e640d6a1ec387ffcfde79c74751b471fc3bbb776990008180f40e2208d2a5834a915e5e15458a0882024a130b4d8a952aa0082808280a0ad214b1d10414a5a988f40ed20949487277bbf3feb1777b2577970208d1fb7d3ecbe5f69979a6ececf13c334ff9eb328d6a1700e0d1454bf9b3cf73d4a8379c682b146af0361f8f337c815a6c1f438ba9073993929f994bddf3d6e3b3c5ece9f91cb5163888c041919a43591444a8cbeabcdf4c5e37e339dea836823d4bdf35ed895e9fcfa36f97c76938c98223aa34f33eef65d2823de74008f49ca59ec2a8c7db72de26b027a5d07dec22b3cea4ae0d68d6a011792255d6af5f9fa9b5126c6c59e94b307ec1da0e3457c1e63733b8fcd7020ad4ef91a5baeddfff9a234307f0fefc318c2586fb1e7b91e913db67a8ee3b035bd37be61a5e1fd48fa87cff33158060786bf16b74eff7202bd44892f53cbcf1d93c935677e2c794e8dc83868b04324f15167d5a27dd7abae3022f76eec865bb8290a928f92a33f7abc06151ff4bf017ed27bb6fb6fe5b218ade3b4cee5895b5f8f2b366cd62f0e0c124252565aa4e9f3e7d325cb656ad5a346dda1480948b1749397f9e1c050a608d8901d5ff71ec7f059ef6faae4fcf9d7e5db3fb094de509f7567d1afb7f6984f35424e82278082f19f0a8d91d1ad45f5d4f9e8aa29899855d82bf268dcff0b01cd77502a0691a93274f66c48811009c3f7f3ed8b486900d70f5e80cea3c939b3d5f3d1eb45c5c5c5ce8798710c24dc0c2072b923cfb679e2a1a380c680819832b7a91c37ef337ab6eb665447a0ac0bffd04c0353ebb03264f9e9c297937a3650176eedcc9b66ddb3255c713d5da4cc85e2700f6c4440e7df41191ba464cb5eac456a94254e9d2a0648b68a6371c9e31697d4d7da49428a828ae774dba935798d3a558cdb4bd461dcd34f131927e190a82e2ccecaba7f95df09758cc130a527a2a19014762f07746157299feb83afa6f390108e1c621a6447fbadbaaf0eda58768fa0fe40208218410dc48bdf42d13ed4fb03b24fcdf50b836c05c7f7be266c6d1cf0c3d2b0a447612fa6fdcf86fff31672b0520223616d5a272eec3059cffea4b1c4ff7a758b16228e19917006a565d48f1e271d4a95b981cd1e148cd70449528e83ad8b1d0dafe190e04ba548c709a180fd79190c8851f3771e9d0213a3a6d76256e7fa65b71d825bd847881941aaaa27adc17e60e3b8a626cef4bccac5d86218e05d04d49dd9192eadefd170267ba30f702d7a5bbbe9f1f2b05d011e62982efa7d0a5fb3b1215e769834347933a8a5361b9dd7c0042b83d30ecbbdde99609edfe8710c28d47786c53767fd7f45677e35f87ec2428ff5b71bdcf203b3dc36ca30068a9a95cfa732f49fbf7a1a75c439c4be1dc8675c4d4ac41aebbef46b15acdb8f3ae6837aa087c32907855f2fb6f57a97d6f618a158d4228863991a1810b521d82424d9ec496eae9046b6c8527255cc556af1ed6d41434a9033a5208a7c0eb8e65a0f8d8dcbbe012968d58fc69534abbeb8874a29b18b1fc0d99de505c345d4373e8483454aba7539ee294f20548fff3a2bbd41767a36a584e63375eb33b9500e7589df36cb1a8e6a9802e258a93af717aa020848a8a4bb9009c4a819020a4c4a25890c2f82e9df7150c454c15a00b1da18ad00940082184104208ff7a6427e1f1bf8a7fd333ca160a40d2a953fcbd692327972ec5b16d1b8add81ae5a49d8b2857dafbf46e1871f21ae4143220ae40721bcecce0341c38a2d157efee91c8aa2a0aace645742a04941628a85da7f7f853d329f53e0352edde1e0caae5d5cd9b387d4b00894071f04c09e72883ead3af2f305205f2d967f399332118602a0a71ea64fabf64e5a6d567c398b52112a8aa2a0a51cf24b13427066e34c1eee3b99f8b01cc8543bd57b2f61dea08a4c695e8f05e70cbf8bddbb7753a54a154092a34057367cd51fd5028ef89f09cbd19cea9376b0f5b98a2074a6b468c4fcb3d77cea418e02ddd9b47620aa50b0e91a081d452a6cfe602443a72e21498d40b7dba8d0e4313e9e3a0821c1917c98a73b3dc6b60b40de1a2c5d3195d2e1c61c6ac94779a663678396af165f2c9b4e49274d4f3eccd31d1f61db4537ad54846ae856607eba2294de8e790042082184104208e146c35f52cc5bd187ff326edc09c0edeff89c2d14801d830761dfbd0bce5d402a18bbed52474b4e26f9bbef39b86b1727efbd97b24f3d459e9a355123d24fa2a328e18487a9fcbe3b910b174ea15a14a40455081cbae0dc150b7dc6c411fff735af8cb7ba2ed1f31525aa6171349bb1230eb0e999d61c68bd90df0655e7d7298d69dd6f137f7d60842dddf04c4bf6b7fe98df07d5e0d7290d69d96f237f7dd0c44d6bf511bb0756e7d7a98d69d96f037f7d701f008fb71b4cef9fced0ad7c6ed093f9edf7148480416b7f64a033cbafa258d8b9d348c76e2e3c010767bf4c899ecff1dbebe360a091b971d09acd0cf230d9d9b97397b39e6eda1d4acd0ec0d1d5fd68372585f5eb7673676e15f46bacfd6038aa5090e86c1af83f0e3cf83ebb9eadcaf6690fd2f6d92dec99d50829251b0776e440cb0fd8d9bf1adba737a7f5a08dfc31d3c846b97150070eb49acbae01d5d83ebd19ad076d62cf7b0d033e2729433e00218410420821fcfb71ab85ff10fe5bc816deb3f675ebe0ec79f4300b525551751d89401782dcf7dd87b87811e5f0610ebcf92667bef906474ab269a612080e5b38d7522249b14571f8b0e0e001387440e7e0419d830735f61f92242cf98ca49fff2469db9f246ddb4bd2b6fd246e3b40eafeb3a4ee3b4bf281bf4d27dab7961fe795278c54e7957b8ce6d8f209a6fdbd8b26a5a4528fd11c5bfe9629acbfb5fc38aff4bc1b2104959f30eab9f05b929d727744185f94482a57c903b8a3e678c2b573e0caf03b6ad21e5e7b7d1c8f5bbe61caf10463573dc86f8bf00805aa2098d86f11c3564da752be702c16056b440e5af79b8caa1a271793579d6474f7bb00a8d4ed258eaf9a6a8e69d2ca938cea7617129d4add5fe4f8ca2920348402135df58446c56e2f717ce564243a1287d7a7866e181b854e00420821841042f80f20a400dc7ab8e4a8405746eb6707640b0540d774ec3922511c1ad69454100287c5826ab3613f79022d2a9282ddbba11d3cc88985f349d8bf1fc0c37027ed7521decae9bfa3387d3a9a536762387e3a9ae367f270ea542e4e9ec985e35a1451153a1059b026e1f96b139ebf1661f96b125ea006d6fcd5b1e4af82125bd6ece396ab36eac484a12009cf551b5bfc668cd3019dcd4e9a1092f05cf7628bff11e334c11190063af39e6948a3a2e579f0e19e4cfc6039899ac3e9e4ab61d8ffbb1699616f6f3c4e85ab4726b03ee2493ae5cbc1c031d578e7859f9c348f78fbe0e53fa03a43aa5a550b168b8545e7aef1748968c35f5855118a82100a8a50508560eb551bb5728621a5242c674d6cf15b115247489d2d09366a475b011d4b4c0d6c57b7a20b1d5de86cb96aa3668c155de858626a7ad13c2f843ba2d1e1c387b324fc5fb87081b0b0ebcb0c7df9cf350ceede8ebbcb95e08e0205295ba9268f3cf5d275f1cc2ce2e2e2cc307137bb9d8cdc4bafeef5f43550ddf33fcfa375bd5a346cdc988675eb3360e65f596aef9f98c7104208218410fe9db85e05e17642b630012a377102673f988b23358542bd9ee4d49c5914edda832b9b3753fce967383a762c714deec7922b0f17376ce0cc279f92a77295a03c07bf5f8af8e4187246876355ad243b546272081c1a2439202a0c1cebf7a14a0ba8aec455462a77898e9012c5e96be0fbc8cdefcee839fe68524a3467a22e57c84bcf92128dd653bfe1d4d3bfb066dd0656cee9cb3bcb477164555f779900b66a1b87cca6dad8af91024a3d3a85bf073ecc656d3f7954efbeb832f6ba9ca6c1481ee67652b6a39b09bf74148ce842a6b9909448e95f8b14422015ddf01b36fbeb6ac719e6cc0c23eaefd3cdf5569d005cdefb0135ef7f990472f0d0d38368705741124e1f64edd205c0eb59e67b53201d206eddebbc6eddba9bcabf4f979174fd7a0f8f94c9057a0a7fee4db9a9ed8510420821fc1771b3f304dcee088501bdcd60898c24a2c29d9cfbfa2b127ede46f1fecf9270603ff1ebd7c133fd88ffe377ae6edfcefe096fa19d3e458e4a9531e27a064e14f6f0caa7c82d938950c1aa48c254e1341b125884c426a33822ee0553c075c5aa7706c3d140b7d90d215697d48b09e3a7cbd768922b9c942b5b08cb551787c3861082ba31616cbd9248e35ce1a45cf991b05c75d01c36a494d471d29ae48ec09eb085b05cf540ba85f07ce56bf078f9ea74eede8188985a68fa93ee4cba1e81f94da1dd7e817e6b4e61dbde8c52ceccea56fd24cf6efe9b050d0b39476240d70c45434877a423ddee00741e8b8b64f6914b0c2e96d3e42f8511b2474a499de830b625a4d238269c94846d84c5b8b327d68d0ee3e784541ae60e2725710761b9ea209db35827268c9faeda68942b9cd484ed5eb440b8553e00b3babf4ebc43a7c307eb98d1b6b879bfd70077aa7847ea11c6f57b8e4fbfdb4e2239a9fe4067de7e672425c38d57cbb5e3ec0a4719e8fbec219d183d6735572c77d077f217bcdcaaa8173d58dd49dd1a3072d1668e9d39cbd486e579edaf783eda778c6679c2b9b07330159a2da4fc13abf9f1adda697864067171712c7eb93393d6eee5ccc904fef7d6e7bcdcd2e86793264d387ffe3c6bbab6058c8ca400ebd7afc796f83b439f18ca1f176da4d872f2ecac0574ae6898b3a59c5f4fb74e833863c94fb9fb07046c7bcf3507a5f33b7d7b9408eeaa6898c6f96beff0c7cff3f482ddd852524896b10c7c6f1e9defca93e9be6d9cd887819ffc4eae68951ce5c7b37a56a34ccf59082184104266e069deeb4fd874d13d69c184d240510803e1bf20e0079aaf60b47f23b285027074da74922f5f424dbc864c4e21a25469ceffb809a9e9085d470b0f430bb31a9bedaa82fd5a9211875e04d6c12e5678985455126951b05a8461db2e1477f81904d1e0dcc1972024ba73d7deee90581c1ac9492986edbd940c6d559451f37e675dff7bd83d772c455bbe846e772015c1a09645183df737be1f50955d73c752b4d54b381c0e14456170cb22bcf2e1ef34e85f955d1f8ca1589b91ce1e4a3e5ebb9b871fa888d4752eee594358ce6aa4a6a6e012e1ad1623ff8167e480d31bfa9154ea552eec198aee8cb77f6a5d676a0cf814760ff69a0355c588beaf63eeeabbf80d9dfa3f6a751c468b6f27513e260c45687c3b7704cd9f7a0b8021ad8a3076c13e1af7afcc1ff35fa768ab17cdfa435a1561cc82bd7c3fa01a7fcc7f8da2ad5f46082327c1a0964518b7601f0dfb5761cffcd729daea258259a2ddca3c00734f2600f0ea83457d3ae57e6d167769cfbb1b4e53abef38da8a558c98f92eedaf9463f7e75d32d5d6945365183ab02d43c67ec6bbcf0de4e5564b01983d7b364f3df594f9b73fcc4caacd5b130c87f3ae331ee1d5fb6732f6cddd347ba316eb477d8b1082175f344ec462636333d52f5f7c5976105f0e2ac5d5231f7257b341bcdcf2732ffa830b57425c1cebd7af37ef7df470672abfb9896977c792787c19155b0ca7f39fef0230f791bee41bb68625ad4b7278451f5606687746cfbab4ab722f0dee6f48c3fb1ea447e7664429c26f7b859bbec8da2e7901b87a681977b77d85ce7bdece74df7a4d5eced7874f512ac2c2b5732147f2104208e1d623a3827f0821a4876ca10044dd5501b16327a27011a2ebd5e5d08b2f52a8776f928f1d472a0a6a6a2a097bfe20ff7df77365e70ef42245d1342321960bbe365ac99bd722eca93854052b0aaa504d3b7a293dece5910857fc7ba9a1490d3b3aa99a4eb22671a4f64220a9fff6624a77e8c23d0b04324f55562eaf8fe234b969347d099fb4ef4235276dc5f27a581443b170d1aa3b69cb97d7c29e9a820efc387330af3c7781a87041b2cccba4651f9ab90d8c58fb86498dc39e6a8e71c180efa8f7e6eb381c0e548b050114aaff36eafe12fc94d09f7ba3c3cc9109676a00848ae2f40170e51328d666064b2f8ee1a9fbeb92648904cd4185c65d68e6d4131a4e5f42e9f65da8fa9173bc5f34c0f04510349eb18445ed9ce38dadceca2f1b9bb6f80fcc59c1e2960f5173a173bc2b1b02c2cc622c84301d8d1567c4a25b7502e011542920c66f3d0bc0bc914f914f7464c4cc8a9cddfa2a90390560c1c44114b7da1932f6336c57379bf73b74e8602a001d3a74f05b77fe9421948b345ee5bc955fa175de0f59bb6810975f59ca88ede789293990d6b1c68ef9be7dfb32d52f5f8c6f59128098925db1c567cc1762c2ee8b1418d0918f9cdf732a574cdab4bfaef06373e374a544cb5781657e79341dbf8cdf7bece0fb1fb7b066c120defff205767cdcdd6fd984a35ff3e493733916ef405504c9170e006f67ba6fddee89e3c9be2ff24487d6746c1ddafd0f218410fe39a4973f28b3f54230e04f8132ad2a6e8042959d94b26ca100e8524777d8213585bf57af24f9cfbd9c9afa365aee688e4f7b1b109cf9fc7372d7aa89c8134bde3a7590ba8e4337767f0dc15ef7fa8c7ef66962724663b58661b584a3aa61ce5d6a41da1d691d218c2cbb9a66c3ee48c56eb7a15dbee4145ac11259860fd66ef3a9e54c98155986f7d7feec776c81680af0f692d5c03a328d00002000494441545ef7fc99fcd852939c81880cd39ca1bb4e1a6deb0e34bb035405d59a8f5329c95ea392521ae64cc248ca05201d7653ead590d4edf90a9b7a8e76bf24ba7b71abe16598f3f5361012215d39905d632ac7dcef7e45470557c42269285fd6c83b99f7c36fe6185cfd7629008099b1d838e9bc7551807a168d66f2917846ac3dc97bad8b795034702679338dccbca6c03dd3aa10685292a283d5712a605b25c255939ba74f4646e012fe5d6dbff2460356f7fe86ae937a72d1aed1ee8d1e26b553a74e002c5dba340d9fb8309513368da261463f34db09d4306fa7d948c5b50655a47464a87f9a942cfce67b936f56115ba61a0f95a946c747db52a84463c0bf02d0bdf330baaedc45e74a71e8f60b142854214b7d1bf1e54eda6df98eafbe984e8d69dff3d7f7e3aeabff2184104208e9212302a4679990809f35f82a02ffc579cc160ac0f9cd1b4197582ec7e3d8730dab22483e7a045b6c2e6c7bfec491230add96cc855f7710dba60d059b3745d7ddc289c415af5f43080968fcfdf4d39cbd7c19a14ba453f85484407326a25284407709bb4220a5d371550824e0903a496161d43e7904d71eb1f4b0dd77b57c7d486bebef0d693ae21aed7bfc2d9cd9797505a1aa288a0589f038157109a9c299fc578034968362311281d9ed762353afcb0b42514c815dba1b4575e64016422054f7498bd1a6a7dae1ca41e07147b82e4f25c05ba1b85527007de60d63ce0323f9a2f77d84f57b8e06150a9278f6305f7ffe218b7ff81380b10f14a2cf5727e839fe7ddac81500147a60acc9a36e4c189be25379e593d594dd3b3d4bfd281266e1a4cdc1e48f965036b6146d5ad6085abe68ebe9948bacc4cf537fc1125192890d0a9ab48d1b3706ac37a8522c2f7dfa1b1f75ab0ac06f9fbe446ca5c101cb0742ac55e5ac4da74098f1ec9faf928f21f377b0a4774d008eecd84fc96ae500e85f2e17a3d71ee79dd62538b67664409e4bd7efa563e30a0820fee0f75873560bd8dee9549d6285628c317cecddff0cf74ddad87b41e7ee7a0f52a15a69a694690f841480104208218410fe1dc8160a80b54c39aec55fc11e1e8925351587c58a7038d0c2c3d1c3c2215f5ec2f2e523ee810728d2b2251171f900b7662c741d5d80227523be8cd468b16737683a5211284e5b794592e6bb2fa494eea0f91ef73c8f906e9426995e46395fbb7db7e02c105222902034a46e28033a6e6542081555b53aeb791f83195f5454ab4133332bebc24b01d01c12a128280884509d82bf33f2916248f6028994c219bed4a528182731c60984f4389911188a9af3a853eadcca1380d88a4ff1ebda428c99308befe74fe4d3f85472c616a27afd366699f6ef7fcd91a103787ffe18c612c37d8fbdc8f489ed4dfadb539fa6c390592c1c3e8c66dd5e027664ba1fef0c6c4def996b787d503fa2f2fd2f5d0540b1c432a34f399a4ddd43898e93c96dc9d87aecbe7801bf3d3594dab3ed84938ab5502d162eee96e9fe4eeada80660d1a91275265fdfaf5f4f86c317b7a3e47ad050e227050a4e650163915802717cfe4f14eed6830f90eca341e007cee97e7b60f5fe2ad972f12192648917979ede33901db5b38be2bdd1ad4254fa158ca341d0aacc974dfa49ec2a8c7db72de26b027a5d07deca24ccf4308218410c28dc2cd9031feabf077caf25f9c5751f4de6172c7aae7b35479d6ac590c1e3c98a4a4a44cd5e9d3a74f86cbd6aa558bbbc2142eeffd8b4b7bff22f9c811ec89894804d6e86872142e4cdeca7793fbee4ae4ae501e6b549497290900ba349260e912148190c60eb930b6fa037e37a35206d8c9779d32b836d54d85c3b5883269cae10989828604a9045c945ef66b4207a9787fa23bc7a3384f330cdf0645589c66366a9a3ebbe6410add5020702916ae9300c56c57d324aef0a042916e01dea7bf5237e64a9a93aa9882bf1012a158ccfb9e9fd2f9008e1c3e79dd270093274f66c4881140d622e06427fcfcf3567e99d59fb1ab4f3367ef11dae58db8d55d0a218410420821005cd1d91cf6e43476e9be7f7b22b3e642c178fd5710cc07c0f7efeb81cd2e993c7972a6e4dd8c9605d8b97327dbb66dcb541d4f546b33217b9c00c456ad4ade6af79809ab5c262676bb21604be15f3b16d2e361eb1e9f42b837f17557f04fe1f51de9760255a4c49f158ec9db57e0f5308fc9329c790674bc176c9ac5290c815b089706e3fa941e83d0cdf109c582c5a2a0080b9eb6ea5e670dc2980f5d6ab8b521056373df395b0254d57ddf68cba82b75a34d6318ba69dae3badc4a87662822d2b5fbaf798cc3fd4c4299803387d6addb628d8ca5fdb04f42c27f08218410c2bf08fe649dece4781ac2ed836ca100a81849b284a2e20ad1a9ebd22366abee8ed82284db0edeb9672da57447be7185f5c4e7a5f1b0a37741111667b41d6f195f0b7022a0e17e21fd990f65164688518fec72427a19034997602f3d936ab9c72071fb24183515d0a533f198c3a90418a70d4eb5c7930b9ad491ba44e8c6cebd102a0215451128c6637096743b21eb9ac323429144c1eddc6b5671cdb52ed1759146fb561405a908338fc3d123b7c60720bbe2df7ec21142082184f06f84671cfa40e13e33bb439dd9f2376a873cd0c983bf31faa3a5c7e746e07aa229051b9fb3c4f577f026235b28002ea1d0e6709098748dc888701421b0582cce1d633f0bca69cea3e374e8c56d60a23abfbb0d529c96e752228530f7c54d9ec2fd5df7f85b78fd9d762149144330f735cdc9c86706e7c5fd294d131bc3354037a56d2114146998ee685243d334e39e620714d3d959fa0c4131b427a4d3f65f518433508d67a2129c76fe8662a16b9a73c75f338c9884fb054f636e245d8a9bef8e8682902a7667a6e4d00940082184104208ff7664c5a4e7bf867f62fc5e814e3c9011e5233b3d9f6ca1002856632758b7eb9c397b1e4dd389080f235fde3ce48ace89709e10a49d7805298cdd6f89341263210d9b7424aa509cd1723c845f01bacb5cc8f7590b61de137808b44eb20a5e4a9f30ed69940c7f1a0eb786806d11de4eb7788cd110a87d43173a4f1f14a74aa34beffea0a09a6332f6fd91ba1906d4576115ce49d10c4324a4ee30da14209c212b0dddc3d8f1d73507680e542150548b717ae0f9c248f7a7117549f5baef3a1dd01d1270a0aac6f2bc55518042082184104208e19fc2ed203c7aeec2fb0abc37da7fc0efc6692677de6f340209ff81e62450b9ec806ca100b826dc6ab512111ece854b97494e4921223c8c989c39023bc8b8ccfa5d263f4eeb1f2960c59d7793a76c59f2376880353a1a1121d192039bedbbcc578410d8131238b76913970f1ea0c3be3de9f45e49f7d315c147089052789d2c04d342bd69ae39f0e4efa7aef4fd5b9ae5d29c64b87c209cfc3574d3d45ff7b43fd475745d43913a52382df7a5ee9fa747bf83a5e376f54fca5b17052884104208218410fe29dc2e9168fc99e2dcf8e88699a3fd930836fe408a405ab9e6d63fc7f4904d140089a6e95c8ebf428247c4a14bf157c9111541ae986867d6d88c2c1e67998b17b97afc0405ab5527face0aa83955a41df400b98dcc47a9695cd9be9dc41f7e801c5164366953d09e99dd171ef7fc2dc28c09d0e92d407fb67ede3c9d3f46a6499b349c7a1d129c0ed9baae9b9733f2a7e1482ddd3f66c1b4e9b47d7643379c1b422700218410420821fcebe1692a1b827f5ceffc6454c9f82f3c876ca10024265de3ecf98b5cbe7215bbc32d70a7a6da3876ea6f6293ae1197370f11e1615ef5821dd908d542c93990abed8f247f14864cb6a2448223216dfb5e8eb7763b977efcd1f85b71dbc26b2947e8d7b10bdb2e00f96ab074d9144a46a84169524ba456dd07dd3c524fb1ef446e922eee082838fb1b9fd9cf2cc6090ed48ebf2847bed17c34a7cdbfab9c9128cddb64293d4dd93556cf7252b81d926fc509c0b8eaa59976fc2acf6e39c0c8b2b99d9db2d1a46449f6244bbe3c74949a39c38233c9027af7ee0dc09c3973d229797d78efe1967c7aee1a007bf6eca162c58a0044e5efcc574bfa6699af967a94218f7663c745206f35167e3289e2e169b3ec4eeefb284bb6fcc2a133f1419d9647f67a88eff79cc11aaea0851761d8b499b42d9f2bc3fca4964893fb5b9bdf75db690e9cc8c59913bff86defe0da398c9c3a9f9f7e3b440a1194babb36dd078ee3a91665cd3257fe5a4ebfe7de64d31f47708848ee285e9a36afcc674cd3c2e9ce4f5c5c9cdff106ba7fa3e1d98e6ebfc4c4417df8e497d3c484eb94ebb980393d8c711e5bf3367dc77dc2b5b070526c517419358b675b144bb75e0821849075dc4e42673053a01bd906dc3e3bff9e0826b7a4f5670c2cefdccec8160ac05f078ee2d034bf8bc46e7770eec2652e5db94aa10271e48dcd85ea14cc759f1d68cf076303140d1c8ead9c78fb1422ca82250fd8cea66ddfd3a75b3a1c241d3f8e0ea43a1c26ef8dcf3dc4fe16b3d93ea02adba7b7a2edc0cdfc36b341709a92836d3fb933b3fe3abc01dd4f1959643dcd7f82c5000e4abbce232823b3b162ce80e272f675fa36182e063a42ba1400c5798a619c14dc881741dea213806ea3aa33add73abe18fd132317b500e0f2fed7f823c9469eb2c3332ffc4b0788f45fb79b2df8bbd077c957b8c4fcb8b838d6af5f9f253e0e87c4e291686ccbf39d39d4ec3d36f6bd875defb5a1f3b0ad6c7dbb7e9a7af53a3f4ba77155a87157f1a0fcab3e3a92d1f755c622e0efad93a8d9b63f6df72dcc303fa1e6f41adbce318de873ea15bf6dfdbd691cf5bb4e47cd791783c74ca4a038cbacf19318d1ad017f7fbe8b510def006048fb67f9e662329d5f7a8346852338b06b33c72ea4061d477a58b76edd75d5cf4a3bcbfb34e3e3c4ee6cdb3a807005ce9d4d31691d7bbfc1d8ad076855342789c75653b67e479e3df16bbaf542082184ec8df47c00ae57584f576ec960b49d9b054fcb057f027e7ac84e518032166ee616c3ee2168fbe2975f7e414ac9c183873872fc2467cf5f42d3d286c4f4fd5b0087fac2aec270edc471b4e42324ee3a42ca91b457b2c775edf871c3061ed03cf84d5a759251ddef02a052b71738be6a5a8668eece391836f720cfbc5a2be85cf88ba77fbdf0cf47f773cfa78433bebfebd8d29fd2e2f7f4c58316ac9c8bdfad380128dcfc0da22d0a6736be4cbcc318d396512b00a837ee2163fcb6734c19d295aae54b70c71d85b9a75e4b262d73fb84c4c5c5111717c782211d295ec8bd3bfcdb87c3a97f4f79eec85f80a2a5efa471cb87d3d471c1917a84d1bdda52be44610a97284fdb5ea33992ea4853fe8b37fa52b974118a95afc16b5f9e08c82fa348bdb8991ecdebd0a06103ea34efc1964b6e01372e2e8e2fc63e49f3a6f7d1e3a3835ef5a6af39c90b8f196bfdae47877162cd74bffc6b37ae43f1b8a874fbd1f17e43f807c85fbd0bb6ab5bb3ce4f3a18b9e020bd46d7f44b9ed17f2e9a94f45eb69421bdbaf0d8938359baec49a4d49837608659eedb2bc65cb46ddb91ff3dd285975e7f97f71e2d65d2b332e74d9a34f1aaffc39401b46af100d52ad5e6b5afbc9fa7275cdf934eafa25299fbf9e39a1d802f9eab47d3d13f046c47b39d61d05727e83bb527e1ceff05f21770e78ca857308a4b970dc13ef9ca2522f2d5c850bd104208e1e6c25306b819d7ed8e9b3d3edfa02bfefe0e86ec64c6952d14806070fd07b862c50aae5e4de0dcf98b245e334c1b82696d3a6007539877c44bf4640952227c2e3c2f8ffa9a743fecad09766a47472084203ca636b6ab3f6588e65a2897f6bdcaaeb0e6f42f9213082e404b6984dcf4e4e1653e632e543de86564e395e6df9ef74c9e4207a981d49cfe0eee32c60981745f1865251a081d5f41df57e0f7d777af710af709405684ff0b172e10169635331d4b4429c6dd930f47ea0946edba80745c66f88f7fa386e5e3f5060501f8a2570b5e5bf0350dc62ce6e0e1bdbcd9d1c19b7def67ce096f3bb29949b5796bc228f3fba3c33fe084ad0153df7d97375e1e40ade2694d645c58dca53defaed84a99ae2319d5ad0c5b57bc4bfb2e8bd3949b72aa0c4307b625f9d231de7d6ea0793f363696d8d8d84c8fff83879e24acef42366ddcc4c2be569ee838db8bfecddd2fb0f6db1ff8c8c7f4635b829d1aced3116b744dec577fce74db81b06d5a2f0a361a97e5fa97f7bfce6fd6e63c5538a75ffa274e93a8672be531efc55632e6f2dab94fcd7b43aae503a04bddf254baf77efa8f98cafe44bbbb4e16e7dc135f961dc4975f7fc7fa554ff3ee7383d22d9fa3501b968d2dcd23ff9bc0f16f46f0fcb69aac18dd2460f9d42bdf724dd3897fab37f73569c4fd1d7af1dd49b77fd55b6bdfe7834e55a951b706553bce66c69ac919aa174208215c1f7cff6ff4bd1445b9ae2b3dfebef292a7f06c9afb5ee7f83c797b260af5d76e46e7c5dffcf89331d29b1f5555fdce932fcdb78fae32d909d9a2b713264c60fffefd1c3b768c69d3a671ecd831de79e71db66ddbc6db6fbfcd9e3d7bd8b2650b3366cce0dbefbee7dcf94b66dd808eb218613b55409520af18f650e95d2ac6a4296024c30ac03b10fcd18410fcf0fc67541ef692f9dd5f19d7783c17dc8dd436d3f011fe5f76df1f8a407df3cb93b42700fe7e803c9fdbad8a02d46c7c3300be1bf51de7778ce494cd4181daaf734798f1da8cfafe34004b06b6a34ca972749fb00b29353e5b71d28bcffc294378e4f17ee6f7ba7923488ddfc2d2156bf8fd58020d7bf9df250718bfd5b0499b37f2297a8f9c07c0d9adafa629b760e220baf6338434dbd5cde6fd7dfbf6b16fdfbe4c8f7dda5f5778adb5b1ab5daaf56b5cd9efddc7d7da944997c78ddc03d9bf6c048f7f14cde2790f6599c786e19f5369d0b0cc55f2089bebc280151b7967cc405a36aa81fdc41e16cf7a9556cdc69af4acceb927c6b72c09404cc9aed8e237a753da40b9c766d33fc7621af45cc19cd56f1015e8070a0c9334e04c9351fcb06e03b3fbc4f1541bf7182677e84b9de9ebf975cbaf6c9cd988c10f4dc950bd104208e1faf05fdfe1bf5ea437ee7f62feb2cb3c670b052039399913274e50a448112a56acc8c71f7f4c74ce9c54af5e1d808a152b72d75d77f1cc33cfd0b871631293929168582c0aaa2accdd6ae9b18bad0ab0625ce1402410e1bcc27dae081f9aab9e0ae6ce799d682b3f272423a5466ae236c262ee35dbaa136d655ba2414b49f899b0987b011d457146384a3dc1c0cd9798d0bdb8573f555560643976efb49bfd77d23c77f1a5d4d0758779dfa5a9bab46cd7e55a9c9edffd5d16a1a0e2dee157545054105203dd814501051d5d3ad0a5c3eca7227584ee7d6ce6fb020553207c35f95b71020090ef9e71948eb07261e748e63eff2d00ed5e6d68d25de2d5a8e56b59b76e1debd66d60e3c68dbcdbdedb0ebd5ca4b7edffbb9bbfe7ed317d2857308a5dcbdea54fa7c042ad7936e015e42aed6b5b225c45288629866764aa4e9d3ad1a953a7f4869a06ba97fda248e34f92c7e2ffa7a356b4955f130da5cb96f82bd698da996edb1787568ea3d5e8bd2cd9309ff29159735bd26ca77871eb25c6772915b0ccc34e13a2e97baf98f72eff6998eb45c5b9cdb49295581e7e66381f7ef615bfeff91280f8431f9af4acceb927224de15d454ab7c9972b892180d4bd7d5b74c725b61d48a4784432272e06b7cb0f8ba9831082171f2c0740a96623493cb3c8a4bfb7ef0a239b197355f281e15c39302b43f542082184ace3660bff993181f1fdfff8466d365e2ffff4c6e72be764b6fef5b69f5d847fc8260a40b76edda855ab1642082c8ac2c55f7fa5e4e1c3381212bc8448dfe3297f0fc2b5c05469ece8bb8479dfbf3daf4065540ff6835b1661ec82bd0821f863fe1b146d3dc0a40d695584b10bfe023069aefe4a2939b9f679283b9c5ad1e166bf7d1793bfbf7d056acf4fcff1fb7bc132b3d003cda16f19cffb597991038df3569d00083527afb7288cee8867d29f9708cb51991177ba4d3b5e6d5e048069a367f3cb6f7bd8b56d031f4c7891019f1e0ecab7cbf3b3b9acc651fdde06542f198d66bf18b0ecd8070a01d073fcfbcc19ff0400851ec8f88eebc68d1bd9b87163fa057df0dc9d7918b1e6280047bf1a41ee3b9fcd50bdfecd8bf0e6277b01f873d19b1469de3fd36d7be2f0aaf1b478f157166d5844b55c5957e64e7f3b0c59e665aa0571deee3fa533420866b7ff1f53e67ec22773a7f0508739082178748a7b1c15ab37e3a537a6f3e9e74bf970e64c00a2e2da9bf4acce7946d02057181f1dbd0ac0b16f4679d1560c69c3c9b6b359b97a38e3daf5e2a42d7088624b6405fa9488e1fd5f8d88401777ce242a5f3b93de2c773833b71bebf2c2f67708cfdd2243f542082184ebc3ad5600fe8df0676170b3e6273bcd73b6880274e4c811ac562b57af5e65ffb265ccbc7081a91b3792b7583134a78057b66c59366fde4ce5ca95b9bbd25d6978f8dab629b8cd797c7db6833d3ae153d7c5b3e1f44f28dda11bd5160a646c55562caf6bd66938fd534ab5ef4af5050299e71e962faf63b4e3d47edf7f692bcd664d49b313ee4fe0f73716d73d4551d2d4f3a4fbde4b0f46ff8cc83e420833899874ce8374c6fbf7dc1d1622f3b1877cfb2ba5c4990200b8b579006a8cea06cb0d81bb78c75709f3185c9bd9df306ecc4b7cb8fc1b860df80c6b745eca55acc64375823b80469cddc1b4f18bb898e82077e1b2f49d302b60d9f6ef7fcd91a103787ffe18c612c37d8fbdc8f489ed0396bf51e8f5f93cfa76799c86932c38a24a33eff35e19aa5777e2c794e8dc83868b04324f15167d5ac7a4356edcd88cc8b3a0653d269e347c252a57ae4c7491a16cfeaa5b9a728d7a4fc352b81ccf776c6ef259fdfd3a72aa22c3fc00e68ffe89fba74d0adaf7c2f7bfceba3985183dfd23a68e1c442ae114af50879103c630e07eb713f7a3f50ab269c97b2c3873015d89e2ce5a2d79615a5ab3ac40a85cb9b2f97764be4efcfcc3e80cd79d3cad3f0fb569ccfcc205b9f38181c087009cfa6e14cf6fabc16f9bef234a112ceabd82767d16b27d5e8f80bc5e5e3587de8f77a091dd8a43bd83192bdd11a8de5afc1addfb3dc80a3592643d0f6f7c362f43f542082184eb437671200d047f1b829ef76f76fd401b91c1cc9203d50fd6bf7f0344d17b87c91dab9ecf52e559b3663178f060929232ee04366bd62cfaf4e993e1b2b56ad562d7ae5d942b570edde1407ff34d3afcf20b8780dfebd5e348d3a6d469da94f8f8787efffd778a14294283ba3529903f16e174c8f0f7c056c7152532e99ae907104809f04da92501cd79c55bad74b87226e082f35dc8be475ec116baab5cb0c5a6ebba97b38bafe629b5b47e029eca44ba0e2bbac3e0abf8c4bcf568df6b8e9c74c5a93068d2ff8be42ae7e9c89c46c111a0a320054446c45cd70980a6694c9e3c9911234600fc23f1d6430821841042082123700533b1dbaedd7205c0dfe66256ea6754800f54ee462800feee5faf009fd1fa76074c9e3c3953f26e46cb02ecdcb9936ddbb665aa8e27aab599903d4e00ead5ab0780c36e27ac6a556cbb7651cae1203e776e62eb183b8cb972e5a261c386e4c99d93d83c3140f007a5e7cdcb3545014d035d473ab7b58dd8f6dec2b722847347dab8af6328004961e141fbed12e203f5c5b563ef49f7f424d734ed96ff1800085d9a42b9273cc70786e0ef494bcf0dd45331f11da71002a91bb90c429980430821841042f8b7e3b6f8ff3e1dc1fb7afb9855c1fe7ada0f64aa9c15fc9b4e08b28502101666c566b3a35a2c5cab5d9b233ffd84353e9ef8faf5098f321cf7ac560bf9627351202e0f56abc5aff90bb817429bbd3bbd857ce72ebab9ab2d842980fb0af1ae7bae1d6c7f6d78c2af890bde1aa9af30edfbb7e76eb9ab8e67382adff63ccb058bc4931998fd0fd0477c15800c36e17bd2619811091424825b1705288410420821841042c87ef0b286f0912f5c9b95ba1f19253d01fe7650d26e14b2850250ba4421ae265c23213189a40a7772f18517203595c832a5c9199d835c313989898e224754249979369e8267466cea3d1f7c30e1df9fa0efcf31c4d353dd57c9f035030aa47c789ad0a489d1eb0ce329f1d88d1778cc517a0b5d35ecfe5d11494c1f00b78194e91be0c94a7796c8c0b308a42c0128184a45e804208410420821847f3b026dd8f996f927915981f77a4d70d2abef8a502702b031eb3be516a90b2f5944e83a2e81c588a568c065e1203c4ca35d6d785a373802a64230086ed3eadbff24205b28003973449233472490d7b871cf9d80db44c677273cb32f88afa0ed6b37ef2becfb66c00dc4d35f3f3c5f70df1306177c4373faee907bdaf0fb531c029d2464093eb1c43d77f6d39e0038fbec5cf80ac62be1faf485d7bc0ba762e1fc14182657103a01082184104208e1bf81ec6442e20f37ddc63e8b228d140a42eae956f792b530940097d8e3561b3256ff7647b65000fc09c0e0d6b40209dbaac70ebedf9d7c290dfb7e3f02b3ae69a8aa8a94d28b0fd2299cbaa2ddf8f0141efc5c66449e7dd534cd2dbc7b3ae17af6dfd986c56231c7a7baca3a85668bb36fe6987cda36da77d7f764efd9577f73639e2a0899468735c78d3bfa8fc4197fd7c3444801908a1165497aeb11ba938f6af5783ec2f9920953bb301c32d0432700218410420821841042a6e0e98be812fe037b273a653fe923e64b050d8f53803495af3f3bf2ad42b650005cc2e9d5ab095c4d482436363711e1e1193a2a0be40b90919d714f931a7fa64219d1f4fcd5cbe8ae7c7a6da67b9496a1566e0e7440486968cfe0d40a7c4e69a4f1a90b3ffe058091e04c844e004208218410420821840cc1b044f0775f332c0da4d3e4c7299fb8fe0e067ffe02d91dd94a0148b5d958f7e72644aca49cb51c250b14275f5c9e80926ea093818cdaa26586eecf762f90094f4611c83fe17642a0f9354c85f43491838c3a2e532a6779d7cb88f7a314c238e5b8552700aed06c0096b01c94aad28017a6cea06db95c99aa1f28eca82fbd77efde00cc99937e5cf5f478671699e137b2d7437cbfe70cd670052dbc08c3a6cda46d79634eb4d4a30c79b41b3b2e0279abb1f09349140f5783d2a4964893fb5b9bfc75db690e9cc8c59913bff86d3f581bf1fb96f244ef095c5223b0e6afc5bc85af53244cf5cb6772df4759b2e5170e9d894f33ee636bdea6efb84fb816164e8a2d8a2ea366f16c8b62999a8b60b48c8e2718cd1371717154ac58d1fc5e69c80266b429962ecd970778af81eb5d679eef902fb2b2ee6f2432fa7c7c11171777d34309075b9b9e98d1b92a63be3f19b04cb0f5a3db2f3171501f3ef9e53431e13ae57a2e604e8fb299ea4b56e730186ec4fcfe13cfe866e176f301c82c6eba936c06e532b78f40daacc0de7289c7c6249e9b918a938ff42a2902391f6443640b05c0859c3973a0e48435915f44d6a13e0000200049444154f263d2461e3efd280df3d64555fd2f384fdb7df0367dd9fdc741626272111d1d8d102a8a0aba2b71a6225014c1990f3ff4ca03e032b3b12724706ed3262e1f3c40bb3f7704ec6fa0a83f9955083ccbdfc8972bd8a944664e37fc218d5f03a00a2384aa8be2ebf0ebab61bb14a85b7d02307bf66ccefdfe3123a67fcd800e2368bb67fa75f3f4877f5a00ca2aaa3e3a92d1f755c622e0efad93a8d9b63f6df72d0460cbf39d39d4ec3d36f6bd875defb5a1f3b0ad6c7dbb7e509a50739a09bd00768e69449f53af046c3f581b2f771c4cc3453b1858252fa7378ca7d3b0ad6c9d5adf2f9f7a9d9fa5d3b82ad4b8ab781a5ac7de6f3076eb015a15cd49e2b1d594addf91674ffc9aa9b90846cbe87882d17ce1398799a1dd4ccc9e3ddbfcfba9a79e4a730f6eddbacfe8f3b91508b6365df8e3fd6e2c293a0e7822609960eb67799f667c9cd89d6d5b0710aec0b9b32999eecbcd98c375ebd65d57fd1042f084b79ce21388c54f79b7ec223cfe75ddd2b3836f6f86914e26a8db03862dbdcea9b36738693fc1b51c499ccf7f969d493b397de64cdae8371e0824a45aac5624101e1146cee81c9c3963213a2607d1313988ca1145645414b94b94f0ba729528414c9122a8d7ae91f8c30f70f1621a8761dfc83cbea13bb32ac00773380e36765fa7e640118982d50f74a55b5f91e62554e33b9e17bad7a52251a48e2275842ed1a44047e1f0e1c35912fe2f5cb840585858a6e6cc1f3a74e8c053c33f0420f9c232f37e5c5c9cd70ea7ef771756bff624e58b15a6528387587fdeff7fb2feeafff6e170eadf539e3bf217a068e93b69dcf2e13475d64c194095d2452856be06af7d79c2bcafdbce31654857aa962fc11d7714e69e7a2d99b46c8f494fb9b081871b56a270b1f23cf9eaea74fbe2898ef71bffe103e4afde05dbd5ad266dfa9a93bcf0989189fbae47877162cdf40cd14c480723171ca4d7e89a7edb4e8fcfaa8b29f4b93b1680820d0673e2cb6901f9d46e5c87e271517e69f50a4671e9b2f1ac92af5c22225f0dbfe582cd45305a46c793a139fb07e15a175f8ced41f9a285d25dd31d3a74302fdf7bbe3c7dbf7f3eea71ca14294cb5a64ff0d31f4be9d4b032850a97a06dbf19e67fdce9adf3acae634fa49c5fcfc30dabd2e0bee669de95c31f3f4ff3e6cd68d2a821f7366ccfa77f5e06e0af592da9ffe236b35cf285a514bbb32712d838b10fd5aad7a549e306b4eeb3c16f9bc1d62640fcc1453c363b07abdf6815b00c045e3f9aed0c83be3a41dfa93d09774a01f90b4464ba2f199dc3b8b838be9bd48f164d1fa046957a4cfce6145f4fea4feb964da956a9366fae3d65966dd2a48957bd1fa60ca0558b07a856a936af7d75c28be6db06c09aae6d0123a378e3c68d01b025feceb30f35e7befb9a50b77e1b3edd73d9ac9791e711c2ed04efb08352382f14e312ee1d7e29cdbbcecb2d6fe869f84923d79379e9087443e8775d4e78f3342e935b06e5a3db01d94201b874f90a5b76fdc2a7c73f6377c11d3822ed68610eb617f8998fce7ccc2fbb7791109f185433f3dd7d172858ac0a070f5c65e5cad37cf1c57156ae3acbf1e349e80e070e8783843d7b48dcb38724e767e29e3d24fcfe3b977efc1130bcca5d3cf5d4a3f46dd580aab5ea53b5e5731c49d13c68c7e8dbaa21d5ef6d48b55603399aea8cf2a32552f3de46e655ad6a5972f8081a27d62fa453d34654abdd981a35eb734ffd0e0c9fb9d9683f93027a588e3c5edf6fb482e0cbc7744a76294090466182c0ca8dd1855bef0370e9d225f6ff380b006b54a54cd77f27a906837adcc3d9bfd6d3f7917919aef7e8f00f38616bc0d477dfe58d970750ab785ad38fd70f1767c8c0b6245f3ac6bbcf0d34ef7fd1ab05af2df89a06631673f0f05edeece8e0cdbef733e7440200f31ee9c3babd67b9a7c7606aa6ce4cc337363696d8d8d874fbb86d5a2f0a361ae7fe9e60a7464e43e9b246d7c47ef5e70cd15cb8bcff757eb336e7a9c23903b71984cf4305a278f5bba3001cf9763cb604ff02497a786bedfb7cd0a92a35ead6a06ac7d9cc583339dd3abe73118ce6124c20eb73e6c903a045d3fb6858af215d068ce7cf045b866959c1ecd4da0c7aa26aa6d7746630e36a3586762fcd895dabe9d0620c4d7a0fa37a849dad4bc630c1b98ed35be7595dc79e98fb485ff20d5bc6a61fd632bcd22a2f5ae1a62fb276ed37acdbb0916fe675e385875e01a04cb7a95c5c32987887f13bfaf3e8b7a8316a3802e83579399f6fdec8baf59b5832ae56a6e7454b3d4eaff613796bd56462fc9c7e67646da55ef9966b9a4efc5bbdb9af4923eeefd08bef4e26f9e59151049b4380d5a5fbf3f5b7dfb16e656f263ef100df941fc4eaafbe65c3974f33bdffa080f5be2c3b882fbffe8ef5ab9ee6dde7029773e1c1852b01e3d4cb75f2f5d1c39da93cea137ef8611ddf2c7a82171e1a6e96bfdee771a371bd1b6fb71ad7bd717883c66f9475957709fe6e284ee15e710afae625715e6ec5c08cff23bd85fdec8e6c610234fb9779fc55e8772e97380f9a82e254f1522293f82976137f9dddcb3ddbabd3aac483942a561c8bc5bfcd2f789c0808812e05858ba88c1e718c7d87ce53286f2ccbbeacc8b5941450144e2d586044b171d505a4c341d2f1e3e840aae630f96e1cf808071e9ccdce01f7b07d7a6bda0cdaca6fefd4455114360c7a84030fbec7f6fef7b0f39db6264da839f9e527f78ec3afc31bd1cdc3f4e1e2ee19d4eab9814fbe5945e3324676e3c453bb993e710b52d6cdd41c3a1cfffca2d5a544176e332c452a5e2fb0a90ce0e3972115745c614ed55b1e05a87cf9f246ffd51c3c3a36f33bb01f8eee431c9d1839b32257f64d039ece50bdba79235875710b4b5740e9926568d82b6ddb0b260ea2b8d5ce90b19f61bbbad9bc3feafbd3002c19d88e2503c16507f9d98a93f4ee5f81697f5d0160dec8dee4931d1839b3a217df7dfbf6a5dbbffdcb46f0f847d17cb9f521bff460e75581681b867f4ea5418bd36d3b109f5756bc43fffe3d68f866387736ec8ac8e24fdce40e7da9337d3dafb728cde16f86f3e0435368b56978c0f2c1e6c21f2d90494e66e6cc93c7c6dd87a8502806a927b376466f3ab49cc03e677f83d132027fca7956d7746630f78d67c97fc9c2c8d9e3c85bf90dfa776d49854fdea0f32f67d979fa1a148d4e779ddf88753cedaf2bfcd8dc307f29d1f255c07d0a9870f46b9e7c722ec7e21da88a20f9c201e06d2c91e59850e71a43379d66567d2b83bf4c64f9e4120074bb278e27fbbec8131d5ad3b175a34ccfcb7b3dda72c72bcb685120d22f3d436b4b1aff779d69328a1fa6dec9a1af5fa2699bb11cdef966501e8190de1c02bcd6d608df1d5dec3134dbf38c6f59cafc6e8b7f2960bdf12d4b021053b26bd072c13061f7450a0ce8c847ceef39952b26ed7a9fc78d44a070e6fecc75fd45efcb6c1b81e89ee6cb9e960bfecc977dbf5faf0f83e2111dd1df1cb86cf2a53966ef7c4d8ad3a45b28e070d871381c2848545545b1083487c30c1fafaa2a08810aa0eb485d27d5964a787838c21985d16eb7e1703810a8a81681aa5ad05dd11d5515a983c3e10045c16ab562b7bbe5c2db1dd94201d8567123f6703bd6646327430b731882b9a67269dd2568046b2f7cc985e317e894dc91cae5eec2623594005ff31cd722b15a55c2ac1654d542a56a7968f7707ef61db0a1280a16c5585449478ea0e2ad00e852a2031ae0f0784926ae3cc9a8b72a0050a9db0b1cbf6b1ae2dd7a08210cda1b7779d1e48c3ade2f8a74306cee019ef9c56dfaf07ef7b77964c9661a958e36fb9da350655e9874b7f9521e9cff3c4fccdb8d2d25856b7a2c2fcc9dc7e3958c9dfef09cb12c1cd48e691b8e90bffbfb007c31b22793d6efe54c4a4166adfe98fbf31bc7be07e70fa6fb5c4f3ef3e9eae49374e65b3ab519ccd9f002dc79ff732c9bdc9dd4c44b00d8127fa3ff6383d97dd14e726a4e9efff063badd9d07e9715ce6f96312c827c3f39e515c414580a2dcf21380cf3fff1cd51a49b13befa158acdba44815024d4a5274b03a4e05ac9f55af8d77377fcf038b57f3dbfe436c5ff62e0b17ace5d4516ffbd812e12a183f5f48a999f75d6d8e5abe9626b9dc7db6467bdbf10af00a1deb42a74e9d0058ba74a9dfbe1d5a398e56a3f7b2e4c74f281fe9fe19a9156de5d7441bf563c2b025fe8a35a6768668009aed142f6ebdc4a20f4b99f78e2e7d861ed3ff04a0cecc65bc5e2136289fe8122d99bfba2500c9e73f66ede2d601f904c37bfbaef05733a31f251f18ce956e7702fe85e64073911eed46cc990b150a191b044289a479bf77b9fc6a45b3bfc1689e281161e1688a839d4976aae6b0624b34fc9bd4f01269cafe1301314a4558b8a618a62751458cdf2225cc19fa59f30ed517689d67751d6714dd3b0fa3ebca5d74ae14876ebf408142154c5ae3b79ee1b976ef7372f47e683891624ee7db115feea4dd96eff8ea8be9d498f63d7f7d1f78d7dc1fa6fc9248ccbeff51ed35f7bd6ad5aa316bc34fd48cf636790cb47ec2628cff7f5e7cb01c00a59a8d24b14779e0cd4ccf4146e730ca15054e84a5f92e6560a129d28c1ea77a9573f9942980d4836ff26852b2f09bef29ea2720c0f53e8f1b89eb3113ce4c1b992d773dc14c328b40c14f4c05c0e79ebf783f86d02fb05aad60b5003a381ce8b654d4702bf6e464e21313b976ed1a76bbdd3015122a8aa250b45429a466c79192028ac0aa86610d0f43d7341c0e3b9a74e76a52a544512ca8aa8a43d7b1d96c08912d0c6b806ca20038ac1ae18991d82353d1ac1a8a430109f6a854c28aa884c747b27fd1012c037e25e7c51ce4fb3b0f450a1732b43b0f78fa0a58540b61d670ac562bc35f2a6a26d512c22df28749890de70f0cee4324093800bb740baf5b13ecd4ca1186aeeb587254c776f527c088fbbf25c1ce92e87084006bce1ad8aefe94e625bfb4ef357686b5e087226ed38759c7afb2f99e38731cbe2f86a228146ff5325b7ae6434a49fc81a594683686ae87df36797c55e565368f377ee4c39e832faa0ee7c771a539b4bc0f0d3b7cc0c9cdfd0028d2e2653677cf07c095039f53b2f928ba1d9e01c0bbed9ea6d0c86f59dbbe1407bfe8c332dce39ed7fe61aa4edeca9c2ab1241c5d4ab1262fd2fde86ce38445d7bdde56a9082f2f7b453a7323486f47698ba260b158410903a70fc0ad3c0168d4c8ffae50dd983036c5a7f2ca27ab29bb37f0c9408f717368270cd381dce50764b8dd2ecfcfe6beda55a87e6f21d8fb3dbb765ccc70dd579b17a1d7aa634c1b3d9b9c3d9b604db9c0f60d6bd873d7abac195a8967efcccda8df2ed2f3d5f769c3aa34f5376edc1890f7e155e369f1e2af2cfa7109d572790b1cfd9b17e1cd4ff652bf4f15fe5cf426459a0fcb100de0f4b7c390655ea65a4e37cf129dde657d27eff683f1493d7781f0fcf940daf868e8246a0ffd34209f6068963b9c99db2f32a4663e2e6c7f87f0dc2d323d17c168191d4f7a73e6c2814ba9948d0d0760ff9a57c97147c70cd13c31bc51417aaf3d4197879ea1c77d6539f0c38700146c9c5659c8ea9abed1486f9d67751d7ba27fb95c8c5e7b9c775a97e0d8da915eb4d3a93ac59c0ad66f1f0ff6a2e52cdc8bff6925e933c846bf0d4ec7676963ef059dbbeb3d48856aa59952a63d903981f3e0c1835edfe3e2e2d8b1c37f308a40ebc71259813e256278ffd7f38cac5b808b3b671295af5da6fa01199fc39b8106b9c2f8e8e855ba9588e1d837a3bc68b15695b3369d024e85f1f92af918327f074b7a1b1b6c4776eca764b57237e479dc480412b003e542f23d31c888f29079339acc0522b95e2521904fa7db7ac3fbbb4b017099644b299d023ac666aeae919a9c447252220ecd8edd9e8a43b3e1b0ebdec964551048ce9e388ac3e140d7212c229ce8e8682273e440b1580853ada0832204ba26409748a1a1280a56a11a27016694a0db3f6e68b65000fe7ce930059f88c51a66e5ccdc8b147be20e4e7c7292bcf7e6e6d0bce3947cc9cedf3f9ec31e6fe35a2d072529cd2345da07e559b3e641e2af4600568c6990b8457d0944929a9a8a8e21ec4b002971681a9add8e2d3595f3e7cf65faf82b10f5fba19f53f9f9255ef72eda75f25adc6633039b35e5c7781b7f9f3dcbf1c3c66e66fca13574eef201472e6b5854c1b5f3fb01b70230b97d69af3e4e6c5d022925255a8ee3d213f5014301b87a780d8f76fd8023971d4e3e0700430178fb403cbb5a9500a054ebf180d14f2925e3765ca4609f76cc75f28f562e3bcd789cfe04a4fdd1f2fceeeb13a0280a8a6a0545c195b5e3569f0004c2db539fa6c390592c1c3e8c66dd5e02fcff27fc74f84f0c99b583b8f28d786771e0881dbe8838bb8369e3177131d141eec265e93b615686ebb699fd0de3c6bcc487cbbf61d880cfb046e7a55cc56a3c54c770947b62f17bfcd0a11f9bdf7f8b98275e037eca30ef46bda761295c8ee73b3637efadfe7e1d395541dd891f53a2730f1a2e12c83c5558f4691db34c301ac0fcd13f71ffb449e9b61f8ccff1af5ee0f1f70f102e5329f3c0603ee9592e209f052deb31f1a4612b5eb97265a28b0c65f357dd00786bf16b74eff7202bd44892f53cbcf1997f3bf76073118cd6b87163d3cc22ab73e6c963f0ff1e205e53117a0ac45662ce6af76f40309a27dacc5dc1a021cfb3e49b6f99f4eb4a22f314e4fece839830a9759ab2595dd3371ae9adf36008f67c3cf1e4e2993cdea91d0d26df4199c60380cf4ddac2f15de9d6a02e790ac552a6e950608d57dd67c6dc43e3916578b2700e00a49ec2a8c7db72de26b027a5d07dec22bf7d0bb636d34346d7d6cbabe6d0fbf10e34b25b71a8773063e51cbf3c82f525a373783330795a7f1e6ad398f9850b72e70303810f4ddaa4ae0d68d6a011792255d6af5f4f8fcf16b3a7e773d45ae0200207456a0e6551b572197e1eb7033212befc469f20dcf4909e9980db62c0dbfcc9943184535171467fb40a05dd6127392981f8cb97b0a5a6a028a0e9a90805544525c2624171267ad5750ddd6127e95a82c1475171d89349fe3f7be71d275755fefff739b7ccccf6f4463a21a105127a2084a64012a4f9b5200451202048ef4d290a080405014105114511101110c4af281d022152430890904248db3eed96737e7fdc32b39399dd0de08f24dff9bc5eb33373cf39cf293b77e6e94fa61dcbb6492693d87692644d3d969dc49006be1bb81899a61964939472932a0b2686ef7e9e7eed91733fd5e0db6fbf9db3ce3a8b743add73e7a231b367cfee75df5d77dd95e36efb1683f71ec8900306b0ece98f697ebe8d86310d0cffce00e6cd5ac06e774de4b50bdf66d2eced308649767867172e9d715eb7ccf9e0c1cfd1d69e087d848b3dfdc14303797cffcbf8f8f8184860e54f7e4bff33bf49de71c8a433ac59bd8a6db71c06c0cc61c33877c162a635d8e4db9f63e03637d3b6fcbe0a6d37d1baecbe783d7e7e052387ecc6434b3f649722ede7b1a386b3d78bef72e2d08255406b4da2b63fb9ce354829d967f050bef3e4eb1cb37d7f94bb9654d304f2e9b50041bf8e75f1b854437f9635af61802551ee5aea07ed49a6e53d8410ec337830df79f20d664d1c88efac26d5673c4e3ac89430aca93fff59b33a1cb78664d35638e91694520ced3b80973f59159bb7bb202c9db77e018d5052572296be0b1618819446e89622f9bc2c0073e6cce1924b2e013ebfdcf95554f17f0d9f77fd89cd1df77d63128f1ff3577e3363f817bd942a366244f795eb647aecdb9386fdb332ed1baae1ff3429c47b43bfd23a241aad7d7c1d24678ff2f5238d608cf241286c61003e4e364d475b2bf95c168987c643290fdff741e9424c41f86c480bc330d052e0791e8ee7e2a3b14c1b2b91c4b26aa96fea434d6d2d5a291c3770bd358c607e15aec7f32573e6ccd9207eb7b77d01e6cf9fcfdcb97337684c31261f72dda6910568ec492318b45b7ff24d59a8d16496e4a9eb9f0203b4a131b31656368167f9085f9211e91e3fc406790c7298e430c963e262e2850f1f08cc3a1241eead857c74f2597c74e1712c39e10c32afbc11fca33d2f9644cf9ebe0557fc76014208defeedb50c9f59308b476d006fdd7d0dc3679cda652dcbff7e2e7adc455d987f80cb6ffc2a3f38ec42e67f922d44c17b85f4655a6b96e57d460eab0760fedd3d674838fff18f0058fcb74be933a1b0c6658ecfa82d1acbd2396dcb462e786229004b1e2f985a85105c32a93fdfbb735e7ced8357df5b2f1390acf07d1005e1048f201ea394f9878dd7025045155554510e4edb334cdb7b57ae4f1fc0ad076ff1452fa78a4d081b92ede6d3a407df10fcb7e9f776ce023f01a890510fdf974bb5aeb50edc7100bba686c6a60652098b7c3e4b3e9bc1c9a7f13d07948321823081946d91b42d9497239febc4c9a4515e0e530a52b6856d0ab4efd1dcb28ed6d65672d96ce0b26c9ab19bf6866451dc18b049b8006516e41093c15be9d2f1429609578c64d99daba81d56034ae0d63a344ca863d5bfd63270bbfe0cb206f582aa83e8924f56163d0471ca280db513b766d94bcfe1029927ffc2905baf23dbd1d1c59d67ea4df732e6f06399748f40f7dd91871fda63bdb6c9f708749f1d79e8cf5d5d1f7e79d14b7cf9b6f5d30c8e3c6c0e8ffa3771d1570f6065de20615bd8563de75c7b67fc817ff0da63f89f9da7d077581fb63ae85c4a4dd0c5f5080066cebd9cbdaf5fc48aec20ee7af4c6b8df9faf9dc55777de8dbec3fa8674fe167f884ff9cbcf39fc9019ec78f520c64d9b8d341e8edb4efcebfdbc79f4696c73a7470a9711bb9fcf5f7609b2e688f8742552176e4e45a0ed0f187e89302482429c439017a8209b7ed131005554514580aae6bf77b01bf7e6e967e6f6dcb18a2a2aa052d28ca8c0e9fac933f4e7e20254ceefbff87a4ff8ac3102bddd43944130f2de88a816840085e77a982698a1ab8feffb98261822e0390c0912195804dc3caef23185c4d5417c003ab010f8f8785ae32b89d026b97427ad52d2d0d040329944ca20abe4a6864d4200b05512539a084b33fcc02158db0ab6386d00c66a83d127052e3823be3294b6573b69e86864fb71dbf748d3f3f344d953c0406312c40318680460e0fb3eaeefa310d41e7a12634f1f80b3f06dfc305d54f187d44c8de5974f3c57368d57d4567a3dc2556f7d58719d93bf7a3a7ffbeae915d383ed70c275bc7742a1ff3d9714024523179e0851e69eaf96f125dce1841b58744281fe6f2f6a8edb528376e589d7de4202cbff75194ffdf95b407003daf513b9fde17f7799a7208d874294a24be96d4308741c785360fe0bfb0b4487884ed50250451555545145159510e4a7f7c3e7e097b798212d76f6e8de4bbd588b5e1a7750b8a64be8af0fa903f7dfd2e7ca059b0a2ac380770835fe046b31102040851906159110a0515a20427e432b856519084be0391ebeab3024d835291adc06b2d936940f5ab938ca0b17a5104ae0a3d14206eb95019f82f6114a631a06b66de2fb064e3e4ba79b472a0fd9d884615b684cb414088c60dc26804d420018b1d316f8d2a3b3b18dc45649b25e9ada9129ea12b5984d92e4ba1a125e0d03270f645a7e5f761eb7435929b298e1eddb4f20a587f2f328157dd87d943630002534ab57afc6f53c3c47c149d383f15f9ac49a65cbf07c8ff6b63660f87a737cde26b372e6b0d2fd94eba37579697b43d79859752fd38efc1352e5e8308671cbc3bfe976fe38cb0f123fcedd1b5c1152229010655cd202840c6d313afc5a2996ebab16802aaaa8a28a2a367f2815309e1030cca298c9d6519fc0ed441802edfb386e1ea53c12b6899db0c1d3010d618022286fe57755c20959543f407765f0a53483670d5a45b9f5230142210d49a4d5534a1572e287b17c71161f2de28438f1339a529fe0ae59015590c03f1630a244af800ef8032903065da0c34d05e938e3f51b12cf719186401826028dab5c306dfa8f18cd076fbc868926994cd1996ec732ed2066c04cd0d2da8a595383ef79386e96868606f2f93ca69438f93c358681f41cea5209b279977cdb5a56b4373372cc38aca445ce0d2a0c4b615059d0d978b0490800a35a46d3ee74607726f1930e66ce42598a444792546b2d7d56f5a7c96a62e77e93d97dfb5d6868a8ef91c97d6741502ebc5c8d80c8941614a448ac3fb87f1094abd4b02e34227c5efe5f9518ffd279ca99094bd751da7743d65837ec54e6bd74ea7ad72b990a23f8713f8116051d84081cf7e25b5ca302e63ffa8612bacb175fd502504515555451c5e68ee0773472e729ff1b6ed909d01adf75713d07cfc9a3f1517e1ec3c961590984120819243811da408601b2c290e49d34f845d92a431467d929452135a72250c0476e485dad044aa92e7445c9731145582f0455957d8e34fb517f9f22fe40049a7b04e830ebb8560a434a94566160ae4662605a16cac9934824c17302c5a09674767662db3668495d5d1d4a296a6a6ab07d132104aeebc679ff9593c796925c471b9e165835b5985ab06ae5c7d4f5ed47439f01680c5cb750936763c6262100ccdaea683e5ab982c56b16b3b27d15d95c0e04d4d8350ca8edc79643c6306af070b6183a9444a210485b29476e3966b852f189d26bc5af8b2bd615a31c135eaa2d2f279cf4c637aef8b95cc5bce2bd989619df94c4b47599f94b8356c2f3a172456508a2decb05bcc4f4a511a7045582c0846784197fe2b56b342ab89d75a4f98f6eeee0f9c30f97542d005554514515556cd6b08d40832e2864cf2bcd7f8f14789e8fe7bab89e1bf8a9cbc05d4629453e9f450803219cc00a80046920a5895412531a68ad90a284e7882c0c6ea034f364241018a1c53ecc5ae8fb41966e618441b8aa90a444eb50fb5d015a84567f404729cec3d886687b658674791f5a024458474887021302840a2afe0a2971f3c1ef7edecba394424af864e912fc4c1a8b20ff7f5363232d2d2d185292cb66314d13a53c0c4998f6dd4568b08c8055d64a04b43d1f61d9b1bb726bcb3a8465d3d8d4442e970d85af8d9fbddef857088c1d398ab1234721c45e5daef7c4acf7e67a772837a69cd010bddf10b79ad2fedd69eb37648da5742aadb13767d75b81a41c1461f08c06d0a0414911845857da57543d386e0fbe48aa16802aaaa8a28a2a3677942b8255fa7ba9948a35d291355d14f9d60734427f782dd02a50c645956e5335c9608c062d8bf999807ea4582c4ddf1df409925c96e32dcabd2e8f704d655c6422e6be12829d0902cf7fddc5daa0b5460b709c3c49cbc6f7149665611a364642609a169e52244d0bed0741bee9743aae046c5916966591cb796432197cdfc7308c808669a25410549c550a615a48cb269d4e63265308e5a3bd1c9d2d2d5889245280b709b0d71bff0a3f034a6fa6deb8ea94ba025562564bfb55ead35d7b6f19ee4a8c7b4f375db154de833215470000200049444154d35acbd1e949fce8d66a4210c813b5742bcc84927cdc231e143c556300aaa8a28a2aaad8dca17c0f6144156dbb16c914a1665d698d90123361a35df05d1fdff3d0da0f525a5a56383eac888b466945a08893e4b399a072ad6140547f07d051e0afd155075fca4704d6864281d288cf8ad6aad797614ae8d12548b638060144c112508e550987291db91213f30f91e8a0428f033f0e862e1a1ec63204d9804cb2d92ca629114263db268e93c7b6ed90675008219112b2d974b84689f4409816c275c9e532d4276c4c43e26632ac73563272d418b450781b7f08c0a62500e49b5bc8ad5d47edc00198f5f5eb9986360495fcd6a336e82ae596f3b32fc7c09746cf976b2f7edf5b6c88b523427463565a673974b9dec3f2ba156c827b65bdebb19fa0084c6951d86f77a85a00aaa8a28a2aaad8dc619a26beef075e323ae66d4304bfb79eef639802434a843471b58b270452058cacd605ff73210568308546e02385c0c967310c0b4c330c262eb8f8082170f20ec8204b1f71914e235e830af3ebc77314c5510a21e84e87af04ebfddc7fda98c9c0eda7102d18ad239148200c0a5a7bcfc3f57ca47430a52097cb81f248269398a6492261e1384e6c11a8ad0daa762793c960cd4a91c964b02c8b542a85e36af0fdb802b06d1a28e592cf7460da36ab572ca5a16f3f48d67caa7dfdffc4262500b89d6916fff1016a94a26ec71d68dc7602a9d123a1822f7e844a41b29f15e598fde29b01d6d7926f88ab50777d7b43a7a71babe7757c56fa3acca804419c01285510aa2ccb2a4afc0565bcff80aa05a08a2aaaa8a28acd1f4268a48cfcdebbfac6478cbdc6070c84900844108b8711080442e3396e21cb8f96a1ca9d305036f06947f9284fe3a9c0cd451801931f68e6553c77908f4777510606bc870e6300ba16be0a98f250135f897fd05d6317c57afdc2349fe1e5729680e078a20ea5bc9687f20a59896a53a9784d63c68c61f97b399c9c4f3e9f45299f8e8e5c3c3e954a910f6307a4b4711c277689324c89223833db4ea25d17cbb2829808ede1e5332413066b56ae0034f5437b538fea8bc526250024fa366198066beef9236bfffe77b638fe78860ddf0299e83e58b518e5dc691ede66327db61cc7c0a953b1eaebcb06b5ba1d1dac7ef6595ade5fc4610be677692bc586bafe54a2159bdc3620cb504f16869e98feaee3bbeddab38052f29ef8062d5826ba0a4ce5d75eb500545145155554b1b92397e924595b1fbe0b2ce44205ee2c01349665069a7e7c7cdfc5572ebeebe22b0fad35b665c4ae2e5050ba69145a490c69a095c6f73ddc302948c42c2305c986a6702a0d3ad0a0e7fd3c9ee7a194a23699426b19a41a95121168f6d68b0be809e5fb56f01f1241321119ca22511c31b1c012b9f704c28bef7b1842a27d175f4bb4f2f07d9f448d4ddec9a243ef88a6a6265a5a5af03c2fcc0664c6c94d7cdf279fcfc7960280743a4dde8144aa162104be72c9663c2ccb40fb2eda75a8ab4d90696fa17e68af8fe20bc3262300f87987d6858bc82c5a84ca6510ab73ac7dee391a76da81fa6db6465a3d6fa5a2cffaba75742e5dc6909d76a261ebadc130babaa1fb3eadf3e6d1f9d453505b13d3d8104d7e77e8298d674fc1bba5e3a2f7eb33d8ddaf6b7db7a8deedaf928012692c84eeeadfaf8bb204046b24d00a5498ae6a01a8a28a2aaaa8627387e739643bdb71950f5a62da16c9644de0d71f32a58880c1751d07d7cda37d17a1358620647a5517c65817c5420a0106065a045577a414b12fbdd63ecad7e43bdaf07418684c212858688dd41ad70934e6ca0fdc634cd30caae11a618c42c83d459a7b15cf1d28f9625e8682d02044c0dcc73c48517a5121033f01a145e09a24449038bc2806c1f7fd9036d8b68d691aa43bdbb1a4c0b29260d9b47efc31cd9f64300c03a582eabff97c967c3e1b32f9320efc55da279de9a4a6a606cff3a8a94d85f10226966dd3d1d1818926954c604a81ef3aa41209b45698429373f2ff95cfc7e78dee7d673612643efe84658ffe8df76efc39f917e7225c0fe5693a5f9acba2eb7fc6278f3d81b37a2d82821f5aa91f7fb9478c30c553f373cfd1f1e69b64dfff0073ec569863b722fbe18774bcf926cdcf3d17f72de753ef651773d2f4a94cde6d2a93a69fcee25cc10fefeaef7c93edb7da9264dd802ee34ad371762750cc397c4712b5fdbb5c6b7df7410edc753776d9631ff638f45c96e5fd98e683e77e9dad77d987a9075e18ace1b86fb0ddb8b15d6844e7d0b2e0010edc753776de7d6ff638f41c96e5fd8a6767d7f6296b99b8e1f0edb16bfb14f62223ad838fd69a3987ed40a2a64f9731d228536301d07e0793264d62c71d27b3e38e93ab16802aaaa8a28a2a367b1842624a81250d0ca1519e4f2e9326d3d146676b0b1d6d2d64339de4b2693ccf41681f43084c293144a0c5ef31f987080382d188c83a106516f215ca73c1f7c24264c4967b014821f07d3f60b89587d21ecaf3c8e5336433193a3b3b03859f101886c0308360632175e88fefa2b55f500e86d607431014ee9281ab8d948140e2790eb95c866ca69374a68dce8e96204c58fba07da4d05846e0c79f48d8241336e9ce763c374f7d7d1db6658050381ded74b436d3d6b206941fc722baae1befc7f7fd50e809cec2b22c5cd7052093c9c4e72925588640488de7e471f3393ccf03a1e2ff416431d8d8b149acf28d0b2fc37bf30d58bd0e2d830872a9157e364beea97ff3e11b6fb062d75d187bdc2c9a76da11230cde80ee83778d4862158194baeec517c9ac5841aab68109dffd0e002beffd03999666b24b971225d78a24e2e200e1e7cefc068b0ebe9dd7bebf23f36e9ec92167bcc09bb705694ba71d733adfbc7607268c1ed195012e93c7bf942ec0ebbf3886df8fb80af876973d9c35fd4cf67f703ee74deac7f2a7aee4e0339ee7cd5ba70270fc6dff6471eb6a1a0d5158c34f7664fca8e1ebadffec1967b1ff9fe773fea4feac78ea4a0e3cf345deba752f0cc30825eb42ceff685cf1fbd77ff12d7e3fe2c7c0ac2efb885294bdfe8b63f8fdc82b81e3821ba854ce89b415b16f603df35e7915c30a4c7a550b401555545145159b3b340a5f792815f9f083f67d94027c85d68a7c26f0f1174260440a4f08187555acdc8c7885e0b542217590c5478b4256a0b8bf0eac029eaf829800c2da3d5ae36b1d6be8833a0041bb29080a75f9c1ba5de5937764ccd88b3080580a1d0715fbbeb77eaca4f25145428bd25ecca42ba510aaa0504d77b40581d23ac8866418165a06158c0d43505f5f877272b8e92ccb3e5a826908b29d6994ef62c9c01d48683f765db20c0323b2820889723d7ccf23914890cd6649242c72b92c89440205f89e13142b561a5ff9684d781e461c302ccd423daa8d199b8405c07bfa1958b516659b68c3c0500a8d400941d37efb21d635632c59ca0737deccaa7f3e8d97cdf58a6ee1c31654adb5eb9b50ed59b4518f96125f4a34b5f8ed19ecc6bef854f450e3fa479673d9b1db00b0ddacf359fac8cd71db9efbedc1e881eb47842ba578efaeb39832757f76d9752adbeefc157efb6673bc3680d645bfe7b05b6b796ace8c2e6385103cb436c7a93bf40560e8b4b358faf04d007c6ddffde9f415fb4f99c657ce7f0dad357bee3f255e43a986e0a1b5394e9dd817ad3543a69dc5d2bffc346ecbaefe3733769dc8c4ddf7e31b97fdb5cbd905ebfb1d87de5acbbfe6cc2c39dce0a3d5fadebd1c764b2d4fddd875fd11ee3fff2876db797b466e7f10ff581530ea42168433b457b500545145155554b1d943797e90975ef904a56d7d845618684c29485a66c04c43fc1021e3afbc20334d395f7c2dc234a252e05354a55674e568e2949c4a238b736efa817540fb61a55f1d84f81a52202548449082540a7c274f3e9f259bcd9249a7c9663ac9e7f3f87ea0fdb76c13d332302d13c334300c89610aa401d250e49d348e93c3cbe7505e1ea13d840c2c048629c17310ca476a85561eae93c1cd67515e90dda76ddd6a3e5ebe8c15cb96d2d1de4ab6b303818f2504865401831f2a369552d8b61d663a0ab320394e9039c875638b4a4159ab705d07e57988307ec2300c4cd30c6a10786e6c35d814b049580094aff06b5358b93cd275c19478a68991cfe32e5f865f9362c8b1b3583ae74696ffe13e6a460ea771dbad7ba61bfac629c00346defa08430ed91ea444e57d0c609b671f472ac5aa27df65fed776af98e0eac50e975deb02a9cfaedf05a7fda51ee7d75a33ecc00b7876563f8410b42dfa33a30ffc21c77cf8b340d2ce7dc45107ddc0cdcf3f1f6bf28b71d4e01a2efbfb12ae3f78341f3c7115f98e1701f8d3bffe49a2b63fafbcf47497b92aa1121da514bf38fc44065cf4047f3b7c2cef3f783c0f168d0bd6771d3f7ffea5b2eb53b98ff8d6813770f30b2fd028cb076a3fb4e3c53c7bd5567cf897e3d9fbe09b5935efac824f228ae60597d1963ca96a01a8a28a2aaaa862b386d67e58e62a2c76a5402b815261d12b29b04d83581519a5faf655c1730023c8ac53640810458cbed61a858a63ee44e8971fe7e9501a19d4d70dfb2bd00a1d24df8fe783c80b40a244e8f613a60f155aa17c85a715beaff17d17cf0dac018ed31af42d8a0750ca8bdd6f52a954982824b000047183859a42521b58d2444a89af158ee706e763491286cd8a352bc9e772184ad1589bc277f3d8a641b6a31324f8ca859079f73c3f4cbdeac52e404a794829719c5c1c03904824701c072104a62910422143af0521836c484a691ccf27914875f1eed898b149ac72abebafa3efa831a4468f66f44faec51a3d8a2d2fb8803e071cc096d75c4b9f71e319b0effe8cb9fc0aea070de593fb1fda20fa51fe19430655df0cdb8eabc259e16bc332e27e3d06f5f6765e21e85cfc04471eb83f937699c601c7dc4466cd03b1f9eca6a3bec2b01f3fc0ccc1a9b2e3af7ee2563e9af36d76daf34b5cf1c236881279ae52547ea905e0c74fdcc247371ccb4e7b7e89cb9f9f80c08cdbae7fa7859f4c1f89d69a315fb91a28b82efdeca8190cfdd183cc1894ece2b6143d7ef6cd4318fae3072bae1fe0faaf8c0160d48cab697ee7fa58f2765d17cff3f8fb69f7562d005554514515556cf628f5e1476940050cb90819f3a8d296d2f173f1ef6e17dfff9019d1481041befff85a19de2076dd1105edbfd6858abb5afb5846107320a40e2d103edaf742a180303e40634841c232499856bc2fdf77036b8600c31098a6c4b20cec84452269934858012de5a1f111d207a10a7103ca0fb2edf879501e68378c460eac0268174382140a81c694904b77e2663328dfc5b6028b836916b2fd98a6d9c5ddc8308cd803414a19d72df23c0f5fb9246d135302281081c090f75c1ccf03248ee304b50636016c121600339522b9f504563ff1373a5e9ecbc8534fa363d17bb4fdfb5ff0bd53687beb4ddae7cde3bdeb7e82fff10a6ab6dd6e83e81b4002f8f8fb47b0fa9c24f5c3c632e1e527015838e520da972ec277f2a48028b6bbf4e6d9a3de626ea7c3b4069b7ce7abd80dbbf738afd69aaf1d7e1ec73df93ab3260e407beb48368e8fdbae79a99386054732ee878531e3b69ec46fe7becc9486040d63a673ff3fa6039059fd3b1ebb776699597a46c3e8e9fc29a6f3fb984ee45b284aa4d9e8cb2158df118cbbbcd0b6e5d613b967eeabec516f17da8bd73f6122f7bc329f3d1a0a3e7242abe0260ebf2022f8b9159cfe5c33bb576300aaa8a28a2aaaf83f00516c052862c88510f8683ce54121dd3e10baa984fefc2aac21a0456845d05169aed0ef1e1d080191bb8ff0a3ab68adb1a41506067ba0354658dc4b87b57c24a25063578a30cda81fae49e07b1e481132d1026918a16b51f0f0bcc09a50a8500c441981f0438126146a6410781c55294680294468885008a1b14c8981812143e5a6f2c967d224131602416d3281141a3369614a8192065a4094ea333adf2044a1101361595610dc0be4f3f9c0454982efb98195405808c340f9e0e45d40629876a0c0f47a2887bc916093b0002cb9e966563ff71c4667069dcd911c3396dcaa55813f9a52f8091bdfb6820f8521f132995ed18d6e2a03b000bff913dc954bc8bff5220929494889f3cecbb82b97e0ad5b8945202c94c3d9d3b7e08adf2e00e0adbbaf61f88c537b9c5f6bcd3247316a58507b60de5d6700c492e8272bdee7bd775ee3bd775e6351587b60d182f94c6908b2e7643f59131272b8ebb4394cb9f0b4b2fbabb4efe8915fbd2e64f65d7e737a40271a77f684262e787c29001f3e767197b57fb2fc4316bdf37afc00787fc11bec516f238460f5c74b787fc11bf10360d1bb6f7461fecf7b74314a29163f76314d134eefb2bea58f9f89deead2aa05603347c7b29b1930600003060c60cad93dbbce7d5a44730c183080c143873369cf83b9e191c500cc3d630f060c18c037fff53100f9e6271830600083068f609d1b7c99bf71f5be0c183080c3fffad17f6d8d95d6fc59f1fde3bec694c9db306cc820868d1ccf81df388de7571509c6dae39e1f7c87896387337cec44be7bf9efbb96b2efa1bdf86c8b1fdda2079a4efb1b9cf3ad03193b7c28c3c76ec7ac0bef20d7c3efea778f3a9c5db61b5b71fe8ffef63366ec35892d860c62e8f0b14c3bf4bbfcefc7957f2f7a3ab79ee6ab84274edbbdec980d3dc7f917cf62a7edc63374f040866e319a5df63d8c9b1e5bf2a9e955f1c522d0405b5d34f9519acbc832ae7d156bff8b9382f8cac5f39d709c1f32dd7e6849f02bce59acfd8edca2a36b11331cd5091042e0fa0eaeefc57d2148f919add7b22c4c1968d795e7e3e673b86e1edff5505e503ccb34237a81854329156414522ac81e146ae18bad115a6bb417ecc7755d72b91c6e2ea84fe0bb1ef9bc4ba633cda871e3e8d3a71f093b4526eba20d939ca7f1b4a42393c751e0fae0789a9ce3e2298daf01c34498163e22aef21b150273dc5c58f5d722db99c6cb0781cc09cb0e0aa985e76548a8afabc1323709d67ad310006ab6d99a9a540dc9615b50bfe7143eb8e002faef3995d4e449682931f2793ade7e8b81fbed4fcdd6db20b7dab2d739fa213804237c9880515bc7daa79e67edbf9f43a452c1b5f051e9c0a6de742f631e3d85c9bb4de5f8c746f3979fee11b7fd6aff298c1eb73d00a3c76dcf0efbff16086ede07ae3d86e37799c21e7b7f899b567f0ba8ecba138d89f0d123e7b3ed4e7bb3d34e7bf1dc98b3f8ebecf115f7f8eba2358cda723b26ee7777793aa3cfe4e113b78adb4e7ef8763ebe620693f63c808b5f9919afaff88ba2f21a65c923ac4c588499737fc0d4bd76e74b577ec25d7f3d3194ec831465775ef8025fbee1483efcf0c34fc5fcaf5dbb16dbde34a2f1ff2fe3d52b82fbc196828f1ebc18a7f7b5643e15eeb8e30e6eb8f42896bff72a377cef9b008cfdce640016deb11080b5afff26f0ebf4b3fc62652700cffc791900ffb3c7c0ffee02ff0b7878ee6af63cf224e6dc7413277e6900affdf30f1c7dd08571fb82dbfe87b36e7d84be479ecf05ffd39fbffefc0cbef1cb85bd6ebfe38e3be2c70d17ef0940fdf0ef76bba69e68de7ad8d7b8fbc9d7d8fd942bf8c1093bf0f8af2ee6889fbed52dcd16d19f19c79c51b1fdc8d9d7f0da12c985d7ddcc8fcf3e84775ef82bdf3ffa918afd7b3ab79ee62b87f4f2fb38fec1d6b26d1b7a8e89a671cc3afd626ebae5562e3e697f96bcf53c57cf3ee253d3abe28b86c4d722a895234d90265a18f1438ac0f7dd083dfda5064304ae2e862102771a53621902436844e83e248506cf437b6ea061d705a6bed8c22084c0552e3e3e5a6a30400985a7bdf89a300da465228cc0f75f4b115c3340690fcf7750da431030c4b6656099417a53438221829c4442abd05d4783f6d1be0aac0b5aa01441ec8017c41068050289306c3412214d4cd30e84258c20c0d917f8be06693370f030cc641d22514b6bce278b8551d70f59db04761d6d1917178bc6fe4368ebcc63d8295c4f6398099486444d2d9dd90ca9ba5a5c2f4f2291c0362d3c4f619949a448e0e515b9740e37ef6108812540bb0e49d3006fd3080416c3773f4fbff6c8b99f6af0edb7dfce59679d453a9ddea031b367cfee75df5d77dd957e7fbc97ec2baf42368b317634d9975ea166e448dca67a6afb0da0e5d967114387d0b4eb2ee4dada69da7f1fb69c75544526baf4fa638346924a67ba30f991bc1c85dbf8e1235b5bc3ccd54b29cd83ff6950aeb857e9ebd27459c57346be69e568758d5cef79de72507e211b4f9476abf87da5b515e857389f300f6844a3d852e1ebc0afd0d71ac33051689289bacf6401f07d9f3973e670c9259700b066cd9a6ef75dc5ff3f68bf933d466dc532398e5f1f90e698bf7ec4c9cf2ce48aadfbf2e0113b70d2b31f73f9fcc57c6f8b3ad22b7fc5a889173278f79b79f3916f905bfb34b38e3885e797b81c74d21cfe7ae3b781caffdf48f3b970e14232ab5e62d2dec76237ecce8a0f1ec1cdbcc9b051fb93ec3393a50befe4a9af4fe2bb0b0ea27fcb6f683cfb7ff9dfd3c7b1dd162358c710962e9f8f55e6a31dd18fe6aff4fe8eefcfe0825f3e89356a4f7efee77bd86740727d6245fd8b11d1f2f28bb9f294d3f9e3ffcea3933a763ae01bfcec964b199d28efd5d9ee6b1ac2407de5ae63d0d00948a396559f2c01e0c4092378685d96c717af60226f326cf441a4fa1fc9d205bfe8557b31ee9eb11de7cc5dc5d71f7c839fef3da4ec7a7a4373d4e041a47dc547ab569322cbc0412349f69dceb2857757a4597a76a59f85a3278ce0dfdece3cfabfb750bbfa19a6cc38951133ffc0bcbb0ef854e7d6d37ceb5fd7fc70ea78e61e761faf5cf3e5b26322943bc772f3b81dad74b82e2bde7a9cfd8e3c9bc6b1dfe2fd977eda2b7a556c1c88feaf1dab1677c93813a14b0a6ed13d5fd353d14f2dd7f70c28553a76973ebd9c674169dd81d2dff5d2f1d16f7f2136c08ff99d9e02686571ea52025ea1cbfe042493492c2b81effbac59b716cff31838702089d02de8dd77de025fe1790ec944829696666a92369665d0d1de4a63633dcdebd6e2fb2e8d75f518a6c0773d92c92406068ee3c55602dbb6e33df9be4f369b4508c1d83d8f64ce9c391bc4eff6b62fc0fcf9f3993b77ee068d29c6e443aedb342c006b9e7f86ce5c9a5c4b0b6d6fbf8d9682ec92c564967e44cb334fe3d524c93b59d6be3a0f7bfc560c3b30f832afe402532af5aa7efdc83534906b6820dbd040a6a1817cf8c884d7a276d5af5ffc21ede9d11d4a6fb6e8514aa3dc4d542848d1b5bdd20d5c1af45b7ab3175f2b360516072445eb297ddfdd1a892b27747d081d4aff824250930a027c64a419103aeca7ab1680cd186bff73291fe45cb6987115532e0bb4f10f5ff20c00fb5ff33500eefe71e0fef6d675770270c44f02c6e9ceafcde65f0b56b1e3b167b273fae7bd9e73fcf8f14cdafb58a451c32977fd1200ab667b0e684a906b798c45398fdffc672d83f73b9c534735f0d11f9f27b3fa77ac727cea869f5c96f9df10dc91df8d338f9bc4aa77ffcd495fbfab72bf3beee8f2baf8fd7ddf3a8c5b1f7e912d8fb994cb666dc98b0fdfca61dfbaaf22ad86a22c5d4b9fbc16807e3b9e1d5f7bb235886e9a586b63d70696c27ccb13bd6e8fe0b4fe8b8b5e5d8ddd30851bf62a3099cdcdcdf1a3b734b7ad0984993b5ffa800f5e0ece29dff654b7347bc2ed4fddce08ef65beb4cb44a6cc3895a60987f2e8edfb56ecdfd3b9f584be7dfbd2b76fdff8fdf27f9cc9af566dcfbda7efd8edb84ae7584a0fe085e3f765fcf86dd8efc8b349f69fc4af1ebba6d7f4aad8f810fc9e06bef781ed5c85bf8b3e42175c797af37b5e362568c9f5720ac89e9483bde12922d7a5889f88fa44cc7ef1f50d41b9f516f31fa66992cd66696e5e8be7390c1cd89fa1430763db26adadad64d269868f1cc184493b326ec278468f1943bf7efda8a9a961cd9a35d4d6d6e2791e4d4d4d34d6d5934a26519e1f2b13f3f93c8e93c3717261bad334d96c9a7c3e8be739d8b64932b969f01d9b4410b0356e3c99d616dc440a339fc7332d84e7e12712283b01fdfb62f7efcf80fdf663f8f483480ee8df33d1227c25f4afef2d36f4035b0e9fd57ab039a06c7c42f8278c51424235066033c6939704c1f6071cd39f367924e35337f0fe4b17f289f315066f7501d39a6ee385c72e26e7ff93cb1efa08bb61772e9d103040372f0cdc28eebaf444fa731897ddb17dafe67ce08107687dff218ebfe0f7fc62f60fb868c1ed001c37b11fff787a0537bdfd124fb4e4f9ea7163d86d9bd1745e7e2b4bff3d1c80915fdbf333eff9373f98cd008ee4d2dbb6a575e14dc0c965fb1d7ef8e19c78e289f1eb625cf5e22a20dcbb38824b6edb96552ffe08f856b773bff49b0bf8da0577533fe2cb3cf0e0499f792fa578f98a8b7194668f0b7f42a24807327e7cc13db1b716b85fdc7412fb9ff8732e3f740fae90167d2d83360af5543e0dcddb8f3b9b0f9d7a7efccb9b685afe00dfbbfc21be33e7341ebf6062b7e33eedb92d5cb8b0cbfb1367dfcf977efc173a562e8faf2d5bb68c81c3867739af4ae7584a0f60e2a5bfe0fed9adbcfee42d5cf5eb173961e68f58f4e2955dfa54a257c5c60645c45e94e332ca69de4bdb8a3d03ba1b13c51944d78a5f476dc57d2acd5bfc3e520ef6c4a417b775e7f2bc2188e87b5ea1d098e338e4dd20afbf94924c26434e64696c6ca47deddac09dca128c18390a15a6023504bcbbf01d860e1c40226193eecce27a0ea669d1d99921615a18469031329acff7fdd81a1009389b0236090160ebf3cfa6f9ed7759f7ce02328b97e07476a21198f575d40e1b46dfedb7a569bb6d689c300eaba6264875d5c387f7f360c08b8360caa1a7393eeb87a4747c4fa6bfe26b95cea6d2f5cfb2beeebe807a836a25e0cd135eee432efdcf5a00eef8cade14f4db6bb9f0d995dcb5ff307e78d278f6bde60dce79ec425eeb74d8eeccab304b3e362292167b8969d3a6c1d4dd38fe82df936b7e34bebef5ecade0e915fcf3caf3d05a73f2968d6cd1ff40bc8b7fcc65d7b60130f588e115e91a42e06b4d4e81e5ada8d8eff310fde364045df6de0d67a772dc75e1d739efce1718b4dbb13cfac0358c4a16befebfdc27c1436bb3bc9176984810b09fe87360afdb017c6719a7dcf721a63d945b666dd9a5ed81071e586f493dd11c3ef352de7ae7dbcc7f7b2975c346f1dda9bbe0f6fb7ab7347bc28dff594bcd90d338e1b02fa3fd297ceff28758f4c00b504900e8e1dc7ac291471e09c0830f0615545ee970e0fbd379b4a8cfe4c993f9f3fb2b98da18680dbb3bc7527a007db6db8d7d80bdf7de85ab7e3d9eb6c5bf010a024077f4aad8c82014840c7c9cc65f87a9ca43d71fdd8b6f90621ea71cbfb3a1bfc1ddcd530eddb919177b0c443c546fdd928be157e8ebbb1ea954aa10b4ecbaf8ae8761dbd4d7d605998bd074a62f8c5e4f0000200049444154b3a49236ca75504ad1d4d8c096db6e0bca279de920691ae47201ef505f538f6118b4b5b5c4eb8de8175b32a2e74838d8d8b1490800fd26ef48bfc93b32aee47a6f7dfc3f6d9fff367a5ac37febe6eca9edf3b64e5412b87afc1f8443aa1680cd132bfe7e011d9e62d457afe2f24302c6daed9ccff1a7fc94e72fbb1ff63f83ad4eb812ebdac3b87ff63d0861f083530a05fe4e9bd0c4656face33b57dece41dec3bd9ef7a1871e22b7ee6500124d05dfeffe3b1d0dfc8b35cf2f22d9677fb6afb5d0c9e36932afe15fcb3a1132c1c943eb2ad29dd260f36c5b9e1ffee151c62db8b962bf6f5ff94b0e1541e069d3f8ef77bbd62d6c93e58ec79cdffd89717dc770c8f49d01b8e280a1ccfedb32be73d5af3844077b1f7ac01515e95c70e46efcfab98f49f6dd89f3bf3d85f98f3fc27c0a968533bfbf130ffde039cebdf2971ca9ef0760e7d30ac1ad3db5037cf0fb5359e9f86c75ecad0cb7bbe64b9b366dda7a6bea89e6f2277ec4bd1f0e63ec009bb9b79cce073997e3ae9fdd2dcddffdee7765df1f7df4d100ecdb94e0efabeee2babbb6a471c55f0068dcbe72f2849eceada7f99e79e6992eed77df5d885f38f6d863e36b91bb13747f8ea5f4a61e7922471e3495e17d2ddef9672042378cfc76973eddd1ab62e342a00d2f89ffa384392efa29ad94e5af1cddee0482eeda8ae78ee200bb5320f6442bead79dd5a03bf4d4cfb22c9452a4d3696cdba6aeae8e64cac67315f97c9e4c2e4b229120994ca2f0495a16adadadf89e8b213435c91413b6da9ab6e6752cfef07d0c04281564600aff37b95c2e3e8be83ca2cc444d4d4d1b057fd91b6c1202c0e781cf4be2fd3473969bf7f3d4b46fc85a3664ffbdb1307c96f97b1480c220a8aa0560f3c46faf9807c0d72f3a8ae9c3ebc3ab07f38b0b6e65defb3fe195ceefb14bc3142e9ad087cb1734d367ab8bd8a7b1e05b79dc7dbfe0a9c34fe1f93be7d06ff6b5c06ca459bffe442538f1c41391668251dbefc3d93fbd31be9eec3b9371298b455997bedb7d070061d473c2903aae5bd64ecdc0a3186857d6b2ffeca72773f8d9b773cfc5e7f1e5591702af95ed7772e225cebefd35068c9fc62df71dd7ed5a6f39632627dcf638579f790a35fdbf1a0b0087fdea09169ff37d7e75f7e55c4103fb1d7501375f7f58453abf7e2e486f9a6b9ec759271798e88891ddfae4fbb9e19313b8ee7757730d7d9879f20dfcf2a482b0d5533bdae1821fcd43489bab2fdda5db3df596a656adfcf1e65fb3625d863ec3b7e1b41b1ee5d20386754bf3cc33cf2cfb3e62c87f7adfb59c70c60dfcf4c2d351661d3bee771437fe7caf8af47a3ab79ee62bc5f4e9d3bbbfb681e738c2fd80dbaf7d82e6f63ca9a6c1ec7de8895c72dda59f9a5e155f2cb40e72f207af892d015d98e53011476fb5fabdf5eb8fc6761720dc9df74034bed26f7df4a814b71815ddea09710fd1b56f44339bcd525353836d1948a171435ffd204fbfa44f9f3e28a5f0dc3c524a52b5b5a4faf5c3696906e5d1deda46ff218348a43be9d3a70f5ede4168b04d8b9a9a1a3a331df8be8bef7b188640caa0de4190f44490cda6715d974d21d26693c802346dcf20455f3697675d733ba954828465924c25304af2c496fb007e5a46f6b36ae82b0900a5e6af4f4bbfa7fe956efc7251fd655192b27343d7d39379b04784d982ac6463350b5015ebc1e97c85f73ab665bb21352c79ea87ecf2f55be8bfe30f58f08f9e6b707c11a89429a68a2aaaf8bf8de8bba175e53b58b260a5d13a70f82966a04d2ba803543ef146cfd9055538ac38f94829835f8cd2405fdbb6cbfaee97f261a5eb2bad2b0061d56082c0ddc89da627fe202e69504100705d979a9a1a32990c42681289048ee32044505f2093cb63db41c1aea6867a16bdbb10430a3adbda993c65773025b4b5b2e4830f905ad1b2ae198d0ad3803a20357e58c0ac38d98b9432de87108211bb1eb1d16701da242c00d13fd6b22c32d91c9fac6ec6340d860dee4fff7e8d719f72812bffcd18804f83ee82733e0b2da8bcd772d74a6fce72ebfaac068acf1e0350b5005451196ee77ff8f6978ea6c371e9746df698793c3fbee9c42f7a5955545145159f0a4a29a41914028bd24a9aa1c65f2985699af1eb62663ae279b4d6719f08a53c51b9f6e83972c729be5e8c88492fc75f9532f7c50acee2df7cc330caae259abb38c578e9582104d208026f95afba04e3baae8be7795896413e9fc592827cde41587658732038c79a64022104f5b58d7cb0e83dda5a5ba8ab49a2f17977fe3c3adadb69a8adc1b62c72b95c70be14f69d4c2462a577329902209d4e234c939aba14994c26b6d26cecd824048008428065054bf63c9f6c2e8fd21ab3480a2b1602bac394298f326ae440f698328cdafa04da0721251a8952e06232d3bd1f0f81d251c5ba80bed7d1c9dae79e65dd07ef33f38db915e7f822058d4d013dbb0005a8c60054510eb5834fe0d5b74ef8a297d16b5435ff5554514577b02c0bcff3300c236684bd30ab4c329140c8803f2966f88b036923063d42b9df58d775bb68ffa380d6ee98fa62f444bfd2f852fae53c13a2fd94ba09155b158410589615ef3597cb8515840d12090bc77148241218083a3adb21a36341c1751d6cdba6bdbd8db675eb70f3396a53096cd3c07705ca7769aaafc3f71cda9adb71f2390c214926ed401090925c2e876ddb28a5422b8320994c2284a0bdbd1ddbb6e37a491b3b360901406b8deb7aac6d6ea3adade06ed4dcd2816d5bf4ebd3100b06a5a8e4ee92ee8037dfec60b73d042346d42264c1af4e2941de130cddf7789c7c719e5a0d5a93ee68c7d96b2fac7c763d69b9d82c661449eec5376934a6786cb91b291a5fcedc56bab7e29b246aeb490029ee5b8cc2facd8af3967ed154f2e92b4569e04fb7ed2268af5a00aaa8a28a2aaaf8bf003311b8d8387945229100adf15c17cfd7b4b7b4d0d8d85896df88eaf2f4e45a2c8de077b5f837bb384f7f7705442bf12ac5286defee7d315f56499828bd1ef153112f954c26836bae433e9325954a910f037d1b1b1b9152d2d1d1464d32416ae000c86659d5d1cac7cb57a0b4477d7d3d5a29929640a251be83c4279134318da00680af5c2441b563edfb81865f80e3bac1b91b365a2bf24e16844253cd02f4b9a1b9a583b5cd6d74a6332855f83078becfca55ebe8e8cc30a05f138d0db5bdce36e36b0b270f2fbfb43ac8055b7453f85ad09933d9ed93bfe1a6faa383301c40a33c8fd6fffc87d6b7df266f27609fdd037ab9259c72c431cc5d07f49bcc030fdec0d89ac0d4d5faee837ce3d8eb683692588376e5befbae61443260ae173ffa53665d722f9944926c3ec57157ddce393346824a33798f19e106c0cfaf60e1b246d26b5f0560f1a33fe3d8cbee2563771da7fd4e76dd7306517e403fff71977189dafe4cdc7edbf81c269eff5b7e7df848841065d6f22bce9d3112e575b0eb5e8540b5602d4da4d7cc0bce2bb798ef1df1ad70ef3bf3e73fdfc8a830d974dbc207f9faac6b5917edfd8fd7323c6114e6bbf4f764128978be73a68f00a0f5dd07f8e6713f619d4cf1faeb6f562d005554514515556cd6887eaf2286d8308c58bb9dacad21efb9714efbe27e11ca31d2a58a3e51c4e0172b0f4b8b72950b088ec694a35b09ddb92a97e3cd8a8b8b968b3388ce0582f3721c2710042c93dada5ad299ce382b4f261304f20e183c182f9be383d7e7e3e4b3685fd1509b20956ac2711c5a9bd7611926a94460599002129609b6c4cd3b388e8fefbb486992b413b8be87d69a542a15af238a8f80426cc3c68e4d4200f868f927f87e79a9d6f7156ded693ad359faf56d64e8a07e986641735e8ce20fac940912b6c99baf77b276ed0a0c53a27590cbdb5382d5ad26b32f1f40db2719fc58e85028a551fd8753b3f7487ca750f0e1d933becea2836fe7b5efefc8bc9b6772e8592ff1e66d417689b3679cc5fe0fcee7bc49fd58f1af2b39e8cc1779f3d6a0edc05957f393d7dee7d09175742c7e94c1bb1cc1b9eb5e03a38e792f3f13df00af5e3c8d59cb7f10cf77d0b1eb8f3b67ed3c8451c7ab2f3f13efffd58ba7316bc50fbb9cc32b2f3dbddef968ade3b57c65442d1d8b1f65c8ae8771ce9ad740d632f785a7e3bef32edd9b59cbaf88c73d73c6ffb0e8e05f32fffb9378f5e6e91c72e6f3bc79eb5400ce9c7e3afb3df01fce9f3c8015ffba9c03cf7a91b76e9d1acc77ec8fb8eeb5c5e11e1e61d02ee17cc05933cf64bf3fbfce7993fa572d005554514515556cf6d09e26ebe7492412086992773c5cd7c5755da461615a093c378fa90a8c7297f115acf5d16be8ea0254cc6c474285e779ebd128a55dec8e536efeee84824aae46c5eb2c5d73392b821002dbb6e3aabbbee3d2d9d9497d431dedededa41236f50306e2ba2e1fbef72eb95c8e7c264d7d3281a73cd2990cf95ce05162a249252c6cd3082a09673a4977e610026cd3c432245a6a94560821018d9402cb32f13c0fd70d828c6b6a6a3628a5e9178d4d4200a8c4fc97f659bbae15b466e890fe71e04c25784e82bc6b23a5e0c30fa362420a29059e824fda0c3afe743fe9c4e8b0e04490e2c957a0b5c05392ace7c5ffe8eb1f59ce653fd90680ed669dcfd26d6f46dfba2742081e5a9b63c50e41f5d2a1d3ce66e9d1c7a26f09daf61e52c3dae62c7a442dd9d66652fd778ed7184bbfdae3dc3b1771f2dc421ab7e2719996755dc61508789c77e722bef74af7e9dfa29b69dad0802665d6d295e6fb7c6fee2ef1b8eb1f59ce65d76e8dd69aed8e399fa5dbdd84be25107082bdf70bf77e2e4b8f3e066e9d5a98af250b23ebc8b476ddc35fd6e6b8251c578d01a8a28a2aaaa8627387699a38be176bfd0dc3a0aeae0ed7f7e8ecec44fb0adb32e2da00a52865d2cba1d87a503cae98312f17845bdcd61df35f8e46f19a2ab91195062b17afab58b0705d9744221167dc9132d893364ca4118cefd7af1fc232f978c9123e59f531beefd3d0d0800072990c9e93c144629a0635c9148629487766696d6ba3aea616dff710027ce5e2ba3e86110806d290387907d3b69052c6c259f4bf8adc937a93ce7463c02621001443299fba556f21b447db8089984515d794d2ac6b6ea7beae863e4df515fdca00d6b65974b4d720315171c6798985c6054050b3f5e1e4b316ae174aa180d21a5f014a2173ed31bd173b5c76ad0b24d144c3ae38ed2fc56d470daee1b2bf2fe1fa8347f3c1135791ef7831a0a7353ffbf7af98b6c324ae1b3888959f24f9ed6bff88c7456b5ff7ee8ff98f7d204f6d512842d49b71cd0b7fcc7cfba02ee300a64edd9774da63e4ce5fe6f2ebcf63fb7a3ba4f96bf69e584473de3f839328ba91039ac15aa27982bd07a9c9ecfa727b5fcc0dd3c7f2c1135790ef78216ebbe9df773175e2447e3270302b3f4970cf6b4fc56ddf1c5cc3657fff88eb0f1e53b500545145155554b1d923994c224286d3b04c724e1e3399c2344d323987a6be75e43369f015beefaf5749374277ae3b510c4074ad3406a0d2d8d2f6d2d7a53104e5ac01ddf9fc97d3f6978b7f8c34ff00ab57af66eddad5d8b6cd882d86513770203a9de6fdf7df23ddd1493e9f47c860ac724385adf2b04c49435d23e96c27ad2deb300c891092c10307b26ae54a6a6a92a46a53388e209fcfe3fb0a2134421828ed2165c0ef785e20ac4581bf4a293ccf5bcf8ab2b162931100b4d6782d2ba87be751862c7e8cbc12307a3f5ab73e0ca3df88425e59a558bdb62516008ac7174b9867fd6a0c6db946eaea13588645d63368a815783ea43da8b1c1fbf7420c6d8251488be96b8d46218a82544b11cd1acd7ff513b7f2ddd9df66a7ab6cb6d9671602336ebb76c649ec75fbbf9933632cef3f7e317b1f3287435fbda4cbbaff79ee036c7fee7d5de6281d37addcb8731e60e2b97fea32eeb5f73e64db610d6895e5d11b8fe7c0fdae636538ee9ae9b3d9eb8ea799337d4c40f32b3770d8ab977519ffd4b9f733f1dc07bbec2f7a5dfcbd51d8fb6d7cf7c46399fca344bcf7687dd74c3f81a9773ccb8d33b6e4fdc72f64ea21d7f39557822236573f7e1bc79f74343b5d99e0cdf9f3aa16802aaaa8a28a2a366b244c492265836581567cf4d122962df900c330c8e572f49b3c99a465e2e2e2fb0aa502463370e591f8804412a4d05e3f9da71002df71d1526020d05220352025426994047c85162035f1b30f413beb5b098a99f49e82848331a1ba556b9400a9254a28a436c26781160aa9c3fd84f347eb49256b49776669695d475b5b1bdaf35052b074c962bc0f1662db36b97427c9641289818e62281216f94e8f54c2a6adb503c74e60084143433d524a56af5e8d523e8944a0dd779c5c5cf137aa7d90cd6448a56abb04229ba619bb52492949a5529b8cd271931000b4d6e457bccbc8f9b733bc793eedcac25549b6fef0cf2c5df71e4b76389ec4c81de2c0904c260fac5f98a2f8c3f9b5bf9e48133992065852631b220cf6159842e3e81a168bdd4147b791406b82145c0af04185c52500f6a8b798dbe930adc126d7f10a76c3eef19cf5a30fe64f4f1e1cac6df5ef79ecde9971db4d0b5a5976f01800c61e7831addf9880d617c7eb57cec79cf942330ffd614c973d158fdbf2a04b68f9c678e092787f5e6e7930ee8f63ba9ce5b6c31a023a32c5cc336ea3e587db00972084e0a605ad2c3f780c4288229a97c5f3faf9159cf142337f29a22984604abdc5cb9d79f66948e0a45fc56ed83d6e6f1c339307fe7766b8f77b78ecde43e235fe6c412b2b0e1e1beefd525abebe251008000da3a7f3c03f0f05aa5980aaa8a28a2aaad8fcf1dedbaf76d59c4b81a535ca55a484e0bdd7e76225eb19316a0c894103e958bd0a2144e0368446298d655868a1212c56851f68f7a51020049669c4a945b50261181808104196c340c119fae0ab5053af355aa9b0389088157e42440acfa062314280a60b730c81a65c6b8d90904858b1f542028604434a501aad155248341a29822268c86069a0512ae0c1b4168c99b02d6fce7d81acebd05897209febc444233c8f3e754932990cb82e35c924f97c96752bdba8ab49a2b4879d3049a73b91462133639fbe414da96c368bf2823809c34e041692d0e52991482185493693c5344d12b64dde8d02910d1cc721555b83a8a601fdfc905bbb9c61f37ec9a8d6796494499b4aa185a653db8c6e7f03efb53b589e3c87d490b15d8259a0b25969ddd65f236f42ca945866509c420a49f8290604f501014083d081fb8fefe37a1ad3f3c9a60b8ce5d9d3b7e08adf2ee09fa7eec05b775fc3f019e7c7f3673f594362603fd00e779d7e037b5ef4a7b86d7a9f0437bddacc85bbf663cd2bb790ec735097bd2ffffbb9e87117b14be85e14617a9f043f7b651d17ef3e80d5737fde659cd69a657f3fafecb885ebf28cef1798afde7de42aea861c199fd1f43e097ef66a3317edda8f35affc9c649f83bb084fcb9e380b3dee1276aeb5ba9ced59d38773c53defb2efa93bf2d6dd57337cc605715b6ed51a92830681ce71e769d733e5c23fc56b9cde27c14fff1f7be71d674575fefff739536ed9beb0204813916a015434a2b185d835768d1a63945812358a2d6a7ec9d79ad88d898698d8626fc492d8d1a888bd176c340129bbcb96dba79cdf1f7367f6eeddbb85a2c0329f7dcd6b664e9fe7cedefb3ce7696fd573d10e752c7feb26a235fbb47de6cbea291b3410542ef401081122448810bd1f4e1ac7b6d1751dc3f076a26ddbc676bcdc009ad450769685f3e792cbe5183172245a5525f58b17118b9561d936995c8668348aa6c97cc22c27b051078f191779ee5d403b3322811725a8433871a57001d14d049f6294b4f5775cef50ca8bac2edd40d0100a14ae572e5cbc8dd7bc00a294277f38791bfb5c868869e2e4d264332994eb60680aa904a964335636eb2509736cec6c065c175d9758198f3ea9548a6cd6a2accc8b1e99c9643c3e50ca205999657906e1914824c8cde0f3143e3d7da7ea582c4e5959192dadc9203ad0fa8e0d42003056cea366e5a7b8c00a374e7f2d8186cb7ca79a98b0d8a4f54b96d57f81dac4dbbd8e46cd92e1b10aafd3b39e41d8396c4d6220d18486101a20514ad266c8a310c2055c9472709483854bd671493b0a71fef100ecf2e77b197ef0f14cfc9740d56cc3a38fece0f5568a054f9ccfa17ffb92a8ca3272afb3f9f7d42d82b5fcf9b12b39e2c4bd79588f91766ab8feb1db833aa514b75ef83a7bdd725d07bbbc1bff7d05479eb40f8fe831d24e2d373c7147bbd059b75dfc06536eb9ae831dde6907ec4993a3239c34a26e6bee9d7953d0c71b73affc5a6ab9e1f1bbdacd7beb85b3f9f12d377458cb0fff7c1fc30f3e8ef1770954cd041e9bb153be46b2e089f338f8962f89aa0c23f73a87c7a68e4679f2157f7efc4f1c71e25e3cac47bdf99ebc1391179cbff9ef791c72cb57445486c7fef36ca801081122448810bd1a769ef9f799cfe26838ae6bb37c452383066f86a55cbe59300f69e8d4f6e943594d150ddf7e8ba1eb5ede807c3fdf59d6f5ad031c85a6c9808175f2da0021688b60a3f2737abc77fef0ac20a470f1592ba568b7c6406010f9b0e94104459537111658b6e39778cfa4f203014214e431500a2164c1fc796b905c9ab2580c379b63e4b8b12cfcf233a470a85fb11ca32077516154232925a629715c8b743a8d619663db36d96c96b232cfa4279bcd629a26b99c972ccc7f169f267ec8d168241ef84c482983fe9665914c26919ad16514a4f5091b8400908bf52513ad2597c9001017160285446123496965d8d16af4fc0b585d551ea8a04a412945c599a752595e896198187a044d3311424329816ff4d306cf01442907c7c961d9592c2b87b3b23168a1c736e7d6a75f2d29f18e3ae99f7c7c52db7de1aafa4e388e17de39b6ddda0a71e9475f977c8ebe138ee3f9b78fedd45bffd28fbe2ef9ec2fbcf66ad0c77fb1fdc35bcb716d8d952c1a737ec9356ad1cdb9f5a9d7da95f95f28a34eba934f4ff2b4284194817c9b3ee38be6a32d0ef1c8936ee3d393bc2f283d56156a00428408112244af86528a4824423a9d2693c9040eaffe8eb49bb318bce940962e5d443c5e4e79459cfa867a5a5a5a882e5dca882d4691b32d9a9b5bc9e572c4e3f120bb7061fe007faee2683ec5597e3b0ba4d299036f77edfc39bc7935bcdf7ccf2fc0bb570446d745c28f8f68d4c0756dea1b1ae9535d4d369dc1caa5900a4cd324d99ac0307434c3209d4e63e5729e3f8094245b5b884422815dbfbfe3af9417d3dfdfe9f7e10b02fe61184620a0f9ced35a3eec7c269326954a5151591d46015a9b303719c1dcc17b53fee53de49446ca35884a1b07414ee92ce8b7136ac038344d525b53496d7505d0b98a4a08c1d2534f6559e34a44deb6cdb7917354fe152c9098352150aa4d4da6005bb924cd083b7cf34587b17b8a52ebeb2a7251576374162fb7d49a0ac37d15fa4574fca75e8397584994f29361784e49c13f74d0a6a84b9153b5bfb6d007204488102142f4760805d97406c7b2c155484da21c9760235d6824132d94c7639495c5686a6ca0b9a9914183879249a7f8f8c3f7d97cc40822ba862ea2688836fb7b7f775ed77001376f6f2f34199802f9e1477de4b98bfc8db767ef2ac7f331286855c8242b544197a248400a5c0402e1392be78dfc3dcf028f4f50791f83c2a8222aff2785b7d38e72e85b5383ac2c63c416c399fbd597e852906c4d60677368c2404a0de5b8a01c042ecaf1b40165b1188944c2b3e18f44bcf0aa7901c0719cc089d74f30069e96c46fef6b691cc72193c9782bce0b077dfbf625914c7ba6471b00360801205e5646d3f843f834db8ab6f04d32b681e138348a729aeb26b272c2b1d4d5f6a16f6d15fdfa5663186d91660a51c808eff3d15b419b625321dfa3bb588a2b3623f25567c575a5da76d6ae14ba62e6bb6abfaa73154bfbc5e86efe2ec7172e289fa12f2d4874183fefe5ef7fb7f8b5a10f408810214284e8edc8e5722493494cd30c76a32dcb229bcda2eb3aa6a991c9a431a2119a9b1ad0749db2788ce6a6460cc32095cab07cd9b7d4d5f5a7bcbc9c542a43369bc1342218861198151587f52cd404f484efe86ac7df75dd4e4381baae0b4ac7731a5608f2fe064a6b734a16a543880673e36298068d2bebe92b1ce67ef52542b9a492ad188686909ef994838d611898a6e9391d3b2e656565019da594388e432291404a896118e47239229148c0f01b8681eb7a21572dcb422985a147021abaae8b66e84114269f8e6118d0b588e1430790e85b4d7de569342ddc8325cb97625b167dfa6d42d5e0118c1b34848af238f1581429bb8e87db99c94c291486ba2a55d7194afd2375b60bbf262866fcfd717baa8558d33574378f2a66fc3bb4f739fd02a76d4510c4cc47a801081122448810bd1d2a9f8cd4fba95479cb03efecba0eaeeb2085c2cd6591ae679910330c5a130988c5a9ac28a3a9be015333917d25ba9438ba8eab1c70553b5f804226d64771b4c4c2f2f6d71df919df46df753d4d81c7d8fb3bff6d734951e04f20057e665dd775701c1729292994786b72716c8bcaea0a84938398493a9da6ae4f2d8d0d2bd050e8520b9ca75dd72512897836fbd8c4a2715cdba6a2a22210ae22914890582c9bcd625916f1789c582c1630f3be1995ef14ecafc98b0ce4055549a73364b3590c2312fa00ac4d9497c5282f8bb149bf5ad86a7450ded1ceaad0e98476f66ed039c35a6c7653ca24a6b0cdda60de0bc759d397a5330d4077f3961aa32ba1e5bb862cbaf63fdd50031022448810217a3ba2d168b0139dcb8719975206e1342dcb221689d2d2d242dfbe7d696c6aa2b22c8aae57b2a2be9168348a95f5b4008e63d16fc0402acc382d895632990ca61905c7054de67d1e1d1c07c0454a1d293de6dc73e26dcb275078ef0549f16df6bd7aa5ec3c53efdbf453d44fe5dbb920daf3583e63efedb45b80b78b2f9406c245a0a17050ae006c2acbe390cb12ada964fea79f60e7b22c5eb4908a780cdbb6711c8b582c86ebbaa4d3e97682846d5ba49329caca63e472395a5b5b03d31e5fd3e2fb0bd8b6977dd9b66d62312f199bebbae472390cc340d3b44063e37d4e1a151515a4d2d9300ad0fa88ae6cee8b35038565a5b406a51c68ba9aa7bb7575b69bdfd3fea5506a9ce2ebe267682f4074e703d0b580504c1adf8f422a3fb342d7f0d7176a004284081122446f87a1e964d35ef2294dc86097dab22c4cd3a4acac0c4d282aca62385696f2789c746b02dd34e9575b436b6b0b86662051d42ff32c25361d3408d3d0a8288fd3d4dc0a480ccda02c1645e1a29755002e481d322988c6c1ced1dab0124d9764d259a2b108b6e5d9bee72c9b783c4e329946d7bd888951234a2291f29268e93ae0e2380ad7514829300cdd8be1af5ccc02fbf9caca4a32990cb95c06c388505b5d4932990c788558344273732b959547067ce90000200049444154e51846044d2a84a9f1f97b6f51555545a2a5192925113346a2b585aa8a4a72ae4336ed85fd8c1806b80a4dd770358d442241c4300333ab783c8eaeeb249349745da7a2a22230f7f14d99344d0b9ca8bd4de7f666d6bea3b61032300bcfe403d6acefd8a004806ce34a32f50d94f5ab43afa840c89eef501733c98561a24a31ff403b6798620d4067cc7ff11cab6342d45394daad5f951dfcae4c88bcb32fe1773f7f77e3af2e9452a106204488102142f47a343535a194cac7f1d702bb73df8ca571653d6551cf46dd34a3018fe2da3652070d4545451989641a3b97c5b52de6cdfd8ae19b6f8126057d36e9077a04522972d92c0b172e0ce6f0799a442241656525c3860dc3acac24de4783548aacc8904ca6d0f40896e5e4fd20557ef75fe5d722db8da7eb66ded6de0bb4a2eb3a762e8ba669d4f5a965f9f2e5545757133125524a967ebb98418336f56cebf3a635d158145c974c26c3d2e54b696da9279968f5a2405a598f5e7a848861d2d4d4442c6ae66df2c99bed64bc6cbdbae6d1d1690bafea87f3d434ad9de3aee33801c3af691aa66962185e78cf958dcd389edac4d304187ade54c8eb138944d79a95c8778d0d4200f05f4c279566fe038f10775dcac76f43cd5663896d3614d5899d7fb1436c31735cca2ebfb0bc3347969e32b65db5f3557b9dd9dbad8ab37067658eed3f8f2c28efe8fc230bea15be4da093b715ecc2a7a2c8d3bfb88d5ba4452994d794525e0af2c281fcbbbc33b0ccf70d35006b17a79f7004ef7cf0310bbe6d00b39a2d7fb017ffefc63f31b97f7bb5e5d367ecc871f779e16457ac58d1e978757575ddb6d91870e24f0fe6c30f3f64feb216a0233d7a4a771f215ddbf0c65d9771e14df7f2e9c246caeb0673e83533f8e3de834ab60de9d67374f7ce1623a4ed770b336f87ae1c0725047ade39d5b74117caf19853270739bc90948ec2763574c0d025e9d62694a3e8535bc38ae5cbd874d34d99fff55724d32962657132e91cae0be5e5e5343737a3691a85414faa2b2bb0ac2c0be67d4d32990ccc92860c1942ede04dc15690b1704c83542a8565db58b615d8cc0b25b02cdbfbfd572e8e5241e49c68344a22d58a23259a50f41f3a085229a8e8038966068fde02b7b999c58b16914cb6924aa5a8acacccefac3b3436aca0baaa125d4032d1422c16c1ca64c9653c27e9eaaa0aa4f218ff5c2e8363db485d47d735cf7c279b05e106cfec384e70f677f97dc6df8fec23a5249bcd924ea7514a91cb797e009e80a3077ca2943238c230a06b113e31f5aa0aa4265971dffdd43ffd0cd649273260407fa4699664d23b73f8554ab1d5b8c718b1c54076de65201515511c2570819fffbc6f3e1c16081c900229054befb80381c794e65a5b59feca2b347df505077ef26ea7ebee69149e9ec6d45d551886d961fc6201c7719c202db7af15d1340d5d8be0e29494647bea63d02640e5c3a82a89c22968d9bd0605421f80b58dc7de5cce913f3d853347f667ce3337f197c7eee3d8bd25f3debb2168935cf400273dd2b4f6275736880de26b6795b152f465bfe37ec35fafb9a4647d4fe8bedae8c5745dfcfc79ec3fed76faffe068ae3ae78758cb3fe7ebec5afa81edc574eb09ba7b67d7081b396d57079aa6118bc5c866b37987d2367f00cf24052a2bcb41b82857e57fbb41294f60d0749d4834c6cae626d289562a2b622c983f97aaea6aa480546b2b288f71cda513283b8b9426aee352595181ebba34352c271a8de25a82cab2182d2d2dd8bace9c4f3e245e5e4132691389c7193162041503fa790b4f26b12c8b952b5752515181c2cf609cf37ec705281c1c2b43dffe7d71d219b4588c859f7c4c2aed45e149245a9052e6cd8b92e8bac4908a4473234d4d4d44a226e565310c4de1682eb98c85704d72194f0b605b596a6a6ab032d920a4a910a25dc2b35c2e07c20decfc8b378b2dcb221a8d06d9924dd3d326e472b920b24f9f3e7d002f9290e33841c850d755188641241adf609c808b335ead97d0340d6c87d62fe792feea6bdc4c0a77c5321a66bd46facbb948452025fba19b745d0fd25f6b9a86aeeb4199aeeb3436c24b33eb49a51403079531745839c38695118fc7292bf38e78fe88c5e3540f1b46f5b061540e1a849e4a919c39131a1a83714b1d85f3973a7c69b1abeb35397cdbc15c2e177ca1e472b976e5be045c987adcff47f0be588467bb57e2f03327fb67ff10f9acca0ec23b94777683f46ddee106876f6894cfb82cda4ac0d300ac0ef35f5f5f8f699adffbfbbabee3e30f5fe4ea8bcee0c8c38fe477b73c0640eadb7f17b4505c7df4efd8faecfb5669dca7ae3f9d6d361fc49051db71c57fbe09caebeaeaa8ababe3ae69873074e0a641f987775cc4cee347b149bffe0cde7c34bbed7bc41a3dd7bac6a3f7dcca1fce3fbdd3faeee95e1a1b3b5da79ff3109a59c7d30f5dc341fbecc32f4ebf88cb0f1ad26dbf8d9d6e3d4177ef6c675855da86e8295c4c5327123188464d4c5347d725a6a9138f47a9acac2c48a4e53199ba26d024b8b685722c1aeb57505355859dcd205d87410336c1d025563a85c4c6cea589470d74a9a8a92aa7a22c8a9d4ba39c1c8df5cb88457474a9504e0e5c0b5d2a34e162e7d2245a9ba8a989934935f3d927eff3ce4bcff1f1ec9799f7f51c0c5dd16fe8406271838af208f1a886266c2206d4569751d3a792b28a1856aa856f172f60d1577358be7411762e852e5d0c0d4c5d6068a04b45b2b5898821e9dba78251238751591ec5caa659d9500fcaa5aaa20ccbcee2b8165595e528db21d9d21a68fce3f138a6696265b3a4128980b92fe4bf0a79c34824422c160b1c7cbddd7e8f77f2a309555656d2d2d24232990cf8272925d1a8f7d9f4eddbb75d78f8f51d1b8478def2cd2256cc7e836f1f7b12e7ed7791968dab19245e7f83cfafce31f0e083a8dd694722757d4a849a2c0d5d3301c9ac5797639a126968285c7efce32a947271f2d18484944821487cf20902509645e3abaf025ee22a5f2a7432f3f9f5613fe3ad06a0cfb63cf4f0350c8bacb97cf5c6bffec8f9373d4e428ba2ac1c63763b82bbaf3903e818e5a818a619e910b94808811eabc2c9b4904ea7db091cbe1ad0d706a81ea8b14a39517be55abe7fdeb4c895b8c24bfee17d7929707bf64f126a00d62e2ab5b6cf6ae1b37f02a0cff86941d9a2e7cee21fcbb6e2e333c7b3c51f7b3eee95738732ed370732ed9287b8f9ccdf70e17e8fb4abbf25b903575dbd67707ff445ff2451b53f37dcbc0f4ef3523e78fbd5d57ca20d03ddd1bd336cec74bd7f790aa9f5e3a71336e7b31519aa866ccf6577decd515bd676d96f63a7db778955a56d889e414ac9ca952b831c00bed9896f7fee6de26588440d04deceb69e8f559fcbdad8e90c757dfad2dcd282502eadcdcda4d3295a9309860c19cab2bce95626dd4aaa35852b5c62660cd7c9521631513515285b91ce2488e81112ad2b298f9593caa6288f46c8ba368d8d2bb05d17c38c515e11c5755d5636ada0e9bdfa8017e8d7af1f75757554f7ab01d304c7a165f972be5dbc848a589c15cbbf25934a51d3a70fd9741a4b17649309060c1a40fdb2e554f7a925aa0bd299040dcb975056598e7015951571924995b7561008a58845a200ed36338176e63c4a79895ea5949e23759eeff1fbd9b61d94a5d3e9a04f315fe3ba2ee5e5e5417e00cbb27051792d8d1745c830a3ddf266eb0b360801e0938bff0feb830f61793d4a821202a95c9c749aecccff31efc38ff976c7498c9cfa0b6ab7df1619c9effab6b3572f120c440485e48dd92d2c596c23748183c569a70dc4752d2c2bcf30eb9eb4b8f8aebb0050b64d72e1425c20eb3844f38925669e710c5f1f781b1f9f3591b7afff31079fff3e73fef1c3ae1fac1b6165e1e36770c85fd2bc3aeb6dc6d698e066786afaef889597f7a8bf9bb5dba9b98a118fc7db25b9f0861481549cb39d0e7e0fa51da63b3a13bb80a647dafc0dfcf6b85ef47fd566e35fb8ff5f0841e803f05de2f53b2ee0880beea462c88f79f8915382f25f9efc1053aef837addf2e0acabef9e61bfa6d3a98ae64dabbae398ba186c5b44b1e22d732ab43fd9dd74f6364aced2b67a73e519e68788d471e83cd371bc10f4fba69ed3cd87a8ecee8de193676baa65d8565cd65e21ffec1345ee4a40beee1bcc3a671d49cdbbbecb7b1d3edbbc4aad23644cf90cd7a662c86610426b9b99c6746e333b496eb608a28ca713ddbfafcefb5509ed3efd2258ba8acae26914d53d3a716dbb6a9aa1e407dfd0a6211d3637405f4efd797542685a11918a6a4696503e96c9aa81905d701e580eb605b59ec5c16e92a1ce5122933d195249d6a0decdd95f2cc91e2f138e9749afa154b59d9e8091bbe83ade33864d269b28916cae35106f6ab63f1b74b8845a2649209fad454d3bcb201d3d070ed2c281b5d2a6a6b2a71952267e5c8241344f366514d2b1b008899711a1aea114a815098bae9593c5859804078b2f3213c353d12ecdcfb1b98c51b85be16a0b84d269309042f3faf811131f3a65a5620848426406b11d68bff83652b704d1da56968ae972eda1502276a221a1ac83cfd1c9f5d72250b9efc2fad0d0da41209922d2d6d477333c9e666522d2da45a5a502a0a94a12867e142c9bc798a79f3545b4637d976482949cf9b476ade3c520b17e245ad0547b9a41309d2890457ce58c885470e239d4830e288b35930e3eaa04ec8321efffd89ec346927860edc8a0bee9f433a9120d5d242d392591cbfc764c68f9fc4e8317bf0f7d7be09d678f929f771f683ffc76646ce1b2b65b3db71bf0fc66d9cfb34076db71563b79cc0c8ed0ee399792b82be8d739fe6e0c9131937613b46fde0489e5fd242369b0dc25365325ea8b15ceb87fcf2a029fc6097dd193fe900fef57113aeeb069a8d620d42a16a2bd01494746296184604dd8c60183174dd44d30c105adeaca8e72ab25003b096e166b8fdfc8338e0dc7f52b9dd71cc9c752763cbda2220bcd59ae3c9d3f765e2c48941d9c4891379b3b56b5a0e8b6808e9edc628e574a82f66086e9ef50237fedfc98c1c10e7fd476fe6e4430f5f93a75affd10ddd3bc3c64ed7ddabbc6820579e7020079e70050099a6e7bbedb7b1d3edbbc4aad23644cfe0380ed96c96c6c6461a1b1b835c003e63595151119838bbae1b24ae524aa1a4c0159e8d7a3a9da6aaaa8ad6a66632990ca94412d3d0d035412c1225954862db160d2bea59b9b2115d6ad8b64575651542403c1a43299778344632994022c86633189a249749a1dc1ccaca61e810d53522a6443836029bb869208583706c1c3b432e95a4b9a99e544b33ae9dc3caa4b1b219962e5d42457914a51ca21103cbcea24b0dd33458d9d048537323562e47797939e954824c268314826422413c164322b07316a6ae138b44a8ababc3ce59a4d3299472899a5e822f8997cc4b390e9a10b4b4b490c89b04699a16685bfccd4fffda7324f67c2ffc8cc2ba66a2094ff3e0e4bcc460ca51e8ba673e6d5b1eef646f1816401b8600e03a2e56590c693b18992c0881adeb68b91c9a65e3c46380c2fae00316dfff20c9afe7036d3bd4854c6a704f0c45395005d4a0545f94aa231a8d128946899831ef884431a35150ca3bfc35014e41249dd75b2d76a8f032c0452ab727d7f246bb67786cd499bc30f359de7cfa146e3cedac602d771c720cdb5c722fb35f7981971ffa39671f7c515077ff8a34530795774a97e9074fc53ced4ede9af5120f9e6670cc81b706cf37fde0a9447e7537efbe3e9b877e6572d4017fc74bd0e17baceba4d359fe7ec0a14cb8f461de7963366f3ef64b7e73d0459ef98e125e9a6ea417924709940baea3706c17c77691426b77685247d70cefd04d4f4321245213484d47d34da46e20a40429686fe9efa50a510175db10fa00ac5d5c70e80e9c77db6b446bb7e5fc9fefc47b4f3dc18c193382fa3befbc33380acbc6c5d7ee8ffa31e7fe9d955a1ddbeeb80bdb6e56816335acd5f1bf6fdc7df7dddc7df7dd9dde7747f7b585de46d773a66e05c069d7ddc11dd7fd0a809a2d4e5bebf3f436baf504ddbdb321be5f689a40d7259a26d0348169ea98a68e617821b96d3b47448fe0e41c74dda4aaaa0684e685fd7414ba11216b59945594b7e50e88c610aec2b16c2402c7b2a9aaa80ccebad4482753e852c3cae6d0a58663d928c7259bce10352398ba11e428884a0db23934c74165b2b4d4d7a3d90e35656548cb46da366473a86c16c3559880a9405816e4724423062807d7b148b6b6a249b0b2595a9a9a482793d8392fd959cc8c6348934473124de818d244283090241b9b3185464c37a95fbe0c3b97c5ca6688181aa62e89450c0c4d80eb6068024393e852103174caa231a2d16860fa934c26839d7e2925ae0311338640a3b9a915d38862e51c72591b53d79148a29a09ae40ba90684e78ebd32318912846a40c6944d7f5abd4236c1062ba6d6a982dad085dc3894511aeed3190a689cc59e82d09ac5814a914b937df65f9c3ffa6fce273bbc904eca7b3967864f0ea0cc340f889eb00614834dd0bb1e5effc93ef250b426781b723ee7a171de6bbfa80e10821a8dafc38b2cd17062fdb15ef3530e0b4c3f059ad72d9d45e85d4853ae9bacf9a78e7279b23a5648b9f5cceca537646cad383ba770f1a8e520ec30fb88c9527ef8ceb16fe68ba28e570f97b0d6cf2cbfdf9677ebd15b209236280d47173b9c04cbf3074a8520a5778e651fe736ae4d7e9e5f1ce27c5509e1020f3270152e838281402a720ad7629845180be1bfcf3d52500641adfe1ec534f0eca0f3ef86000f6dd77df0e7d4a95ad29a2cbdee5cf97dd4b43c2a67ad32d38e5eae96b7d8eef13679d7556c9fb638f3d16e89eee6b0bbd8dae5b9f3d832b1a7ec99f6ff97f3c9d3518bfc74ff9e3dfbaf79d5855f436baf504ddbdb321be5f8c3fe04ce6ce9dcb98e1c303d3d7b571ee6cbc719d946fd1cd782357b15f77cf33aa9bfad1abf1dcf5f5f5bcfffefbcc9933a780c276fe5ca8b5d20aaebdf2d1a3874014e634cde193a64451bd0364db7f704b960797a3470f66fc56e3d7f85df83eb0410800917416659a38a68196cd81f4c24a6996851331119ac4c864c95656a0d93912ef7f809e67380be16797039064f222800dc83cfbefc5aa15c26d739acdc7908de209000e60e5af35c0901e43fc830a83b75b33ec5a69924bbc8d5939098d368d41192ecaf1b51136ae9543d3341ca57864e6b30c8deaf9357afbe04a298eee1be3b6854d9c35a4a2245d5c1452b95e3c7da51078be117e9d500e1209c2136f3451100e5439444d1d472966fc6f26838d36675e2bed49c4cad5d02326e83a0870b216b672310c13a9e5b504c5c289ca3bf72a85a6492faf80e3e68531cff957008eedb4533ff966431e7d242885941a92d007606d63556278f7a46d719beeee7ddc35e3b91eaf63434077b45ad5d8e9215df39011a65e792753afec59f3906e3dc7f7f54e86e819eaebeb83dfbaf0bc66679ff99f3a75ea2a7f0eb7de7a2bc01af59d3c79f22af7fdbeb141980039ba8e651a68c934b82e8eae7bfeaf4aa1a7d23811133b6a7a4e209ac44ea5da25f12a65a7ee49706904690419200764db42700687b7536fe0494b46fed001ad60ecb3f6de944beff124cd8fff753583f73dad53fb78ffac94e2a2f17d39edb67782e83b5fbdfd45d0efec6b0fe2ea237fcfe72df99d7265f1dc6dff2f18ebdc31359cfb9ff900cc7df2f7d48c39bda86e2ee032f7c9dfe5eb0a8d6e5c5cd7e6e2f17d39ed9f6f05755fbd3d07d7b583fc00e974866c32859dc921748d48348a903a4e3e59975b90580ce5eff8eb908fbd2b1448a110b820bcb9354d04768c859f53a136c5a74f98093844881021426c0c585d53d7f0dcf13c67ce1c4e3cf1c48097e9e9d1d8d8187c1e7e909455390e3becb022adc3fa8b0d4203e09a067ace4628851d8b21733944c6c62e8b62b426d1b259ec7814a104081db9c5e6ed32dbf968cf8ce7100556e76d2641f9b6c1956877ef1b0df991ef7d2675971bee62f86127b2dddd0255b30d8f3ebc4349e6bf3861d9d419f7f0d1f16733ee769b28364376389b47278e0060c87ed7f070fd954c9db23b29cdf3cc1fbdebe14cc98f77eabfffc1cf8f3c9e6dafd2b1e3c3b9ffb15f04737555e7c3711ca6fefb5e3efad9598cbddd2186c5e049defc4ab9684614fc5d7e4d476a46600665392e7ade0428d0b4e4c9195051b828bc28410af25efa0284406a5a4055cf29d8cd7f7ef910a179da3ac08250031022448810217a39d635d3dc9bced07163b127286cbfa6fdd7776c100200a6018e8392022505c272105e262a54deb40404c2d0a0bc8a9a1db60fbce6a174e65adbced266fba5e19142cfa7d976716c9f51774078fa011fbef5982c8864a34787f3f7275f2cb9fc4cf3b7c1b510a2ddbd513e8e9b1f7eba431f5f58d8e9f8dff2f2f1bf2d396eb4cf8edcfffc2bab5c5738bf5e36965b1e7db68370a28481d40c34cdf09875e1453d524aa184c0d08d3c73df16ae3310937ccd88684b58127c06ca9712da76f8bb4b9a116a004284081122446fc7ba669a7bd31908c29396427575354d4d1db3dd170b00c5fd3beb57aafffa8e0d4200505113db34d01b9b71854069128142e91a4a93d8f1286e3c8a889451b3df3e0c9cb27bb763d6f601296d5c278bab045239e842b27cf9326cc7c6b2f236f186c430341a22a6b7fb2fbce8350e9034bdf0749d39e91632b6a5da14c7d4f7cb3a30cddf110a9da4fdb9fcec784233b1f198fbbcb515caf542af6af9755b96e579cf4b891405f9067c6761ef8182b33f8fc8b7f1730fe00aa49081899070054ede074089d007204488102142f47eac6ba6b9379da1f31dfcda5a2f8960a9ba9e6800aaababdb990a15a23381637dc4062100182346926a6ac28ac4d0b3596cdd40d8364e24826b46a06f2d669fbef4dd7d3706ed3d85b2fefd10f9041540494dc0c71fedd3d58c1d4a0e5c36bfcb351633f8dd31ffc57d572771447702c2aa8ce93b00fbd189901243377111f9683eae27180028cf2ececee5901294a6a1cbb6f8b9be678928e1622284081405fee7e3bb60170a3d9e06c16b176a004284081122446fc7ba669a7bd3194aefe0d7d5d505d7a598f5ee34003e6a6b6b4b3abd871a80b58c51e79cc9ca4f3fa771cee7a4e62f249748a000bdbc9cf8c081d46e3596ea7163a81eb5057a3c16ec3617efa277c5a4af0eda99cc14a48d2eb6f3efae7f61db5209b7be2ff8d2aeebba202c24261289d43c332bafdec2b1bc8c84288542e128c74bcca66918520be2fc23346cdc2061982e3c076b3f03b0d0f4bc0990e72b2055de0fc3d720b8e00a156a00428408112244afc7ba669a7bd3193aeee0f7efdfbf1dbd575703e0a3aeae8e65cb96753be6fa8a0d4200a81dbf35b5e3b766733a46d181f6ccb3ff81159ad2f858db4c7531035f785f281074d6a7b06f776dbe0b14d2a9706e8fb9876c6a2566344624ea25b5b072d9bcd98ef22224092fa3afeb58b84aa11c81d2340c4d47693a52f73218fa990ad1f47ce41f6f3e5df77c2e70f38287af85c8d3c446815a771a007fa7a050ca2f55b621e1d1ba3aaac68d0beeaba7ddc5b6070ce9d06ece2947b3f0b5b7487cdbcc215d3ceba3757541bdb3e23566ed763cd5bf7f9cad8f18d36e2e27a918386d3a5b1e35ba5dffe48c43786bd9e5ec76ca98b5f178df1bbaa28fcacee7bda37fc6ca06a0cf4476bcef5aca22da2a8d5188de4ee3aee8d0531a259fba91b72ebd0fdb8ce0e6e20cfd7fd319b577c7f77a63a6654fdfcb9e7e47f4765aae0bac6ba6b9379da12d8a8f8f254b963070e0c0e07e4d3400fe78c5f5a109d05a866fab5ecc281733ae85f7aeebb60b3159d8a794495067cc7a29f31c5fd0d0b48e5f9ec5f314efe817aeb338515971e6e2c2fac23574e5dc5c88e2e72f16980cc3e8306fd0ceb6307513d7ce924e78492f8402dd17c0948be3589ec9507ee3de0bcdeae0da2e8e6363e572b8a2ed19fc7f0ca14b34a9a1e9ba17adc9c21320bc5a84ae61681aa66162d9d95003b096b1e74b2f75dba6eea833187ce9363c3376688fc6b417cfe4d53d4ea5eedaa719b7ffe61de6721a5ee189ad8f66cba3de6bd7efdb6b3e66f3c737ebf1dad71774459ffa738fa2f5c77f63cf53c6b3f26f07f0da79b39972e3ceab344629f4561a7745879ed2e895a97f64ebd95f32707039f682277972e74318f5cddb9db6df1869d9d3f7127af61de1a3b7d2725d605d33cdbde90ca577f0172d5ac4a041838035d3002c5ab4a8dbfeeb3b360801c047a66125d9c646caeaead02bca41931d76ddbb3a17a394d98e8f62ad424f99eee2f18bfb7426b4ac8acf4067da85cee62f755d1867bfb3b54a657961fd95c40bfe2941b94834142e1a0a5514bbdfcba3e065615368b8526bf32d50e4536e17cc2125322f080463685a60c6253563bdf601f035027f3f7d3f2eb8f5598c6193f9cba3ff62b7ba0d23157867e8b3db0f7adcd69af71f5efef13406ddf23ca37e34b8641bb7a90162ed7fec55ee5b3e6f98c87e7d3c5a2dbfe664debdef238c0a0d7dd465ec3a7d57af6fe223de3be11c9a1b7238b972464dbf8b21e36abcbaf4177c74da592cfdb2155d83d82e37b2d3651356e79157095dd1e7f3a71631f6b2b100541d7d1ec9ed6f82128c5648630f5dd1a1a734aa1b1027b7320383cb719a1a917db7ebb4edc64acb9ebe97ab82de4ccb758175cd34f7a63374be83bf60c102860e1dbada1a80050b1674bad31f0a00df11ac6492f90f3e4acc75a9d8666baac68d26366c08aa13e6bc2bc6bfd4752973a1ce84885589d2536a8e4206bc7877bf14835f5cd693b9bb13408a5ff452fd05f9ccbec24bf42524a09c7c74a07c2605a540faf902244233d0a50e4884d4bd083f908f26e4af29ffac288426d134dd5f60dbfcf92cc61b8206e0efd91d38eb8415fcee969738e5c8db9933f3d4ef7cced5c54b53f6c049d9c426fe982daf388fca0a73cdc6db752a9bdef536a3761bd8a1ee85dd76035c328bbea1ff2ffe84e5280ccdfb8c731f5d86b9d75941db37affb37bbcd5d4c7954c759def699cd3fe228aafff40adb6e558bbdf051feb3f7450cf9f466afeec84369f9d15fd9ebf61f02602d5ef7da9ec6568bda728fa6b2627b54cb1b6b3c6648e3ae31fe997ff0d20e13f8bcae3fe9655126cd7ab6d3b61b2b2d57e5bdece977c4c64acbef0aeb9a69ee4d67e87a077fdebc79aba501e8ac9f8fd004e83b42a4a61aa949eaef7f9086679e63d3134f60e0a6031046fba83d9d39e116de8fda6a1223b6d8825d76d9858a8a8ac2cc5f1da068cf40275a13bcf2ca2b7cf9e5177cfed19b9df7eb8449ef6ed7bf33e1a2332dc5aaceefc3f701e8742ca13cbe1f374f1f05aa2d2ca817f147f39c7a35198404155207a1e5c385cab62c01f97fa6e2e7f6b4021de77750a875e803d0194aadf58edf9f4c1d87f2bb5bc6d1f4f98533d8a700002000494441549f81f55300d8f383afa91a58096e9a6fff329557f6bd9afd5eb9688dc6dc6c9fe17c75f31d8cdce5b7e85a7bdab49912281a1f3a9be78f68669f47bcf4ea0d7f9cc5c0abae681b677c1d6f9c7201c30fde9fc1fbef1a947ff64103d1d30f617efede906d31983f7d7b057b3cdc9672ddd834b646cfb2be22a471d79873f029f4bde925b6d97b7312cf5ec4ff0ebf9e819dbcd7212dbbc6aa7c4784b45cbb58d74c736f3a43f736fca5b02a3e00ddf55fdfb14108004a295ccba2f98baf487ff5356e2685c865a89ff51ae5e3b7a262ec28a4def1514ad9cdfb68686864e1372fb2edb6db3166ccd82eedf90be1380eefbcf30e2fcc9c49593cbe5a0ebb85263885c2404f8480d599ab78cccea22395d230b8f94cbe6d10b80ac833fa424aa46e80f40400f279123cb7008fa62aef88e3471852b467fc85c86700c69733bc10a00a81cbba8b02342caa333f63f35ed2624299412ef12e005a645887b6ab1ec475dda06a60a57721630cf8d5cd642f1f07ac990030e26f33714efc21cf1f6f30e5ae73d064296a086a0fbd9ccce96381a9a0727cf6418cdd8656062dc6fde73d367ded7996ccb889a7fffc02fbbf7029e0bd8b3f78f605e266c7ffd1d5889efb9da3b6c2a03191a3aed2c44dbc8da8dc618dc70c69dc35befabc89fd7f3c1c80f21f5d44ee67a3e9ecbdde5869d9d3f77255be2336565a7e5758d74c736f3a43f7517c4a6163ca04dc3150fb7a88d4b7cbf8e6c9a7f8f2cfb7907dfd2d8465e3da8ae41b6ff2f50d7f61d97f9f25bbbcdedb96a6635cfd523bb67a5e6078f5d557f9e8a38ff8e4934f7a747cf4d147bcfaeaab407b275e27bb80d30eda93ed76de93ed0e3a8779d9d2526329b39c76b1ef55c7ecb8b1ea81edae8bebbb427134a4c2b10a71d3c107b2fde43dd97ef29e442a3761d2e41fb1fde429ec7ef0adb8025c0120718544091d17cfd4476a26227f28a1e3a0b1e4d55bd965ec58b6da66025b8ede92e3aff910cbb2c8e572d8b61d68013c0d8208e2fd074f1408110225c43ad3005cb4eb00008e39fc34aebae62a7e75c4b1000cd8ade38fe1cf2fbd955b2ffb0500d5a34e5fed39bf6bb4366683eb96a72e47dfe490351f54988cfac74b0c130ff0fc8937d2d9f75fea95eb91b55300b016dd446ecc056d0c83cad152ef503d791f465f7a25d69c47827e63b6e9cbbb77be1bdc27dffd22b81e37a91fef4e7f2db85f1fcc0046ee35884feffb0c80e67bff447caf5faff9a0218dbbc426d511be7ca70180ec3b7f4556efdd79e38d94963d7d2f57e93b6223a5e5778575cd34f7a6f3e8d1a379e08107482412ab741432f0df7cf3cd2af79f356b16a3478feee2535e7fb04168003ebef812ec8f3e82150d28094a08a47271d219b22fbeccfc0f3f66c9a4ed18feb363a89ab01532e265e8edcebe1f60f6ecd92c5ebc381008ba836ddb2c5cb830b8f6c77d75dab17cb9f75f79e7b46d78f7e68339f89c37f8e02f93bb7444eeca84a75023f0c62bcf753a4657e8cc71b994e6e1f4198f73465e3310ad1ac06baf3e8bd024a8b648424a689ecdbfd050088411f1b661a48e2fee646dc5b1074ce3e7b31773ccd008d24ef0e1c73994ed78f6fe85cebeba165c3bed6cb024960d9aee0901eb4a0370c06d8f71d6b47379f0d9e7b8f6edc789d50c60cfa3cee2ea6bf7efd0f6d4c8eb4c9bfe2e75a376e5af0f9cb05af37d1f78f7b01f61391ab819a8dd92494fde18d4bdb0db6e81da7edebe9399b3a81580a7b6de1a7dd0394cf9efcf3a1f5846197de7cbb8474fe6855f1aec79ebaf823101946b41e548b67fc29bafe5a619f4f96ddb0f3d6e868f8e3d904c4ee026336c76c9bd41d5660f3d40f32fcee499bb6c346ce2db9fc34e13470230e4de47683ef94c9e997c11ba917704bcf4bb7704ec8a3e7dafb987b2a37ece0bf70a54cd36ec747f9b636648e38ee88a0e5dd515d272c2035730fb57fbb0588b61bb358c7fe8f6ae27dd0869d9d3f7b2abef8892e8a5b45c17c8e572c1c655785eb3f3f8f1e30198356bd62a7f0e3e03bfba7dfdb9d77788c13b9ea7de7de2dcd5ea3c7dfa74ce3efb6c92c9e42af539f9e4937bdc76d2a44968c7fc142c1b3762a094c2b472389a81ad69f49dbc33cd2fce2436660c4e5525038f3f967ebbef8c16897488735f68fab260c828ca5b5af15c55099253750757295cc0061aa311b6583a0f8003876dc6b40f3f67d74a936cf3ab6c32fe1656cebb87b98f1ecea12f9fcfbbd76f4bc3a7e73164e77b7979e13c2696e95cbfdd58ecc7dee2fcc115c4aa07f2d8c547f2c7a73f63f137ad1c7dedfdfc617f2faa42ac7a20e9a6253c71f4211cf1d4eb6cb5a517c9e1ad592ff0e29f4ee3e47b3ea2a642a36cf425ccfca7e71065a7bfe4fc5f9ec3d35fb452a62906fef03a665c39bed3790a058258f540928d8b107a9bda3553ff3a3f3ffc5cbecce838d111fcf9917fb0d7d03a145e62afbbcf3b9c1b677e45bf13efe5f533b6e491a5cd4c346c34e5450f72f3e4b5521ff19b63cee2c3861c995c15e7defb08c76ddd07848b290cee3eef306e9cf9354b977d41d5113379ef9aedd1116ba401701c87ebaebb8e8b2fbe1858bb31fc37f4bc00eb0a6f8c19c5561f7c5a52b51f62ed20a4f1da4348cbb58790961de1ff8ea452a975bc92106b0bd75d771ddb6cb30d3beeb8638fdaaf0a6f0cf0de7beff1e69b6fae529f424c3ce0ea0d4303e03a2e4e590c2393455a16e8125bd7d1b259ac45dfe0c4630c38fe672cbcee7a963cf010f1219b5235763442fa7682f95df8fc1f7836db1a60e4cf52a9bcdd7a69a8fce1028e3f62c14efaec568b1d2a22080191caedc9b59c80949281bb1ec7a20b1f42dcb01d5ffeed75261d31986b3f5cc9fd3b9571c3d2385f0caa08e6787cd419cc3c67339ae7dec5b03dcee192031f0aea84101c78ff0ca81ac0dbafcdf4d6a414c75cfd182f7fb38011319de4b274507edb2187f3c95e37f1c9bf7641294573817a3498e7ebbb18b6e739fcdf010f76f00330740da1c0712c9490dc7af04944ce7c92370f19c1d7ff3e991f1d741b2bde3f1f95dffb7f6ac2ef79fd4fa3b17219fef3c9647e3c6c0cbb4dd98d3d7eb42f271cb31765c2fbb2bfeb278731f12f1f70dbb6fd699e7b1f43763a9b9f2dfd17be35da7f275cc2ab578e245dff0c03479e8d75f9332c5cbc6cbd8f021462d5b0c3679fafeb25f47a84345e7b0869b9f610d2b2735c77dd75eb7a0921d6125685f95f57d820048091d75ccdb27fde869dcd30f0a413597ceb74061ff7739a66cd62e8a9a731ff924ba8db7d4ff4aa1a1afef73f963ff23855633d154ea76136f158ce4221a03b1d8082c0d4c5d71a14dbf22b2f2e26e0398344fb1cc088c4597c99be8cbb9e6be4e6fffc929f5cf0094d83dec61d7c3ab18249afda6f184a292a37fb29d9e68b7b449b1327d671ccd40b997ac87e1c71e02ec17a2e79ab9ed7ffbd53d0aeaa2042c255fb0df3ca363f2698a7d84cc8755d0c2f252f8e82ab3f6de29d0387a3691aa30ebd86c6a9dba1383fe877c3612350760ee55aec73e5c3cc3df13d9efbdf6c1ebffd0c6e79fcb77cf2d00908a171f9bbf50c38712f6ecbcf53211bf3cebffe38a310cac528ff2167f5fd2997cd69e4f26dd6af2840850877fe4384081122c4dac0eaeee68608b13ad8209c80f5588ce898d1a4962ea1f58d3719faeb33c82d5f4af34b2f8210347ffc112defbcc31757fd89e5331ea1f5fd0f81ae63f84bda0e2d7fe8dd1c7e3bbf9f506db1fc77ac307833e1319bd9c43b989593fcd938775c0557bcff3633b423193d6c2adafbd39977f7736cf1cbf64958da84010da5ec926b2f7eae4b9e7e93e927efc19297ffc2d83dfeafe0193ba7673c88d4d0368f3f5e30b60b8e129ebdbf20b0d1d70c03cd30f23900da84ab6ae94548721c07a5147db798c84f7f711af7fce729be79fef768ca41132e8e523c367b361fbcff2e1fbcff2e4b96cc47a010ca13adfae80a5c0794c3f157fc807f9dff3273e7ce5d6d6720d35cb318f7214284081122448810bd0d1b840660fe9f6f22bdb2112d9142a53344876fce8a575f41392ec2757122268e69784caf26b10bece84a690000b8a72fc4e38808081da42690dd89432eb88e42d84016d4cab60e67efbd2997de33875d4fdd9a4feebe86c1fb9e13ccb5dd996338fdfcb3197cc8dfd0f432ceacfd98f3ff9ee2a76f0cec96c12f2eeb63682ccdb96c624a949be593152e5b4ffe3163276ec69f861d0efc01803fec50c7d45b66f3d46f3c21a37971ba9d16a014da850795c273f41502a504d3c6d470de7f1772ef4fb7e2eb47cea3764bcf6f44f87a13d516eaf391173fe3a83dc7207169fef279ccf209485c94b2b878421da74c7f9da7cfdc1984e0eb37e73062d25894ca7bde3b3628074dc0a653ae25fb8b1f337cf8a2f55603102244881021428408b1a161831000e263c720de7d0fb1e9202a26efc4d7175cc0c0a953492f588892122d9ba5f5938fe9b7c79e34bdf72ecec001dd0feafb2d5bc2a38294797d88cfd0e6cfc267c295e700e0ba9e07b0a520d52650ec72c35d0c3fec44b6bbdb8bb030e3e136dbaffe3b9d48e3873fe3f83bbc38d5bb9fbc39e75ed4c093fde2ab4c8bbf1c3f99c93bee419f98ceec971ee1829f1ec2f29cc04a6638e9f2bb82763f7bf0413e3ee96cc64cfa1d158660d00fafe5912bda7ba697d28cf8cf23a5f442ba49895270f28cdb39e9e863d8e61a133bbe050f3cd33e849c1fe35f2a98fd8f0bb9fcdc06e2114146d572fd03b72070c0154c7dfc7e3e3eee376c71ab430c8b21932fe6c9ed4723f2028063e582f9896cca55dbb91b4426e01021428408112244880d051b8400e02a17d7b6209b61e9938f93fef43316df70234e75050bff7c2320f8f6e187a99eb43da2ba86da1db60ffa1687da0c76d76d1b2c1757495c57e208819222cff817dbcf28100ad755b84ae0da2ed82ec269cb606bc436e7d6ffbcd47eddf978b291ea1f916e5a12cc3ff284c76839a1fdda522b17b75b73e1bddf17e027d7dccfc1f97eaeebf2c4f3cf75784e2104467c0baebff709aea73da35f3856e17da11370ae751920bd645cca138ce2fd7fc883af7c80699a2824ae72f19dab6d278395cd7a663c4271e3bd8fa20990be19932b70958342432f1bc3df1e9b89143a8ef2f23128c7c2711cb289264fab23bcdc00ae7039f2e94f8946ab430d408810214284081122c45ac2062100ac98f532b80a7d6533f627290c2948cf9f47aeb68adc279f6297c5717369eadf7a879afdf761e094dd81d2196ec16388b3aa9ae6742bba709182bc5dbfc467fe859079c6d93321f21858858bc2761cb28ea22965b41bb3d4754fd155ccfe627466d6547cee6e1dc5b9117c1320a514ae0025746c57a1691aba6ea2eb3a6ede65d7ebab70f3a63f8ee3a05c3730a3f2841f81905e565f8140a982b5e5cb1cdb0de69442a2699a977e5b394186e075a501f043b309a911afac65f8d8491c7fd6251cbfdb90d51a6f7dc075affd8cd9e92c9a70c9a94a0eddf2728ee9bf49977dee7c6d5f6e58f62def1dfc5ec9fa0933260475d9ec3bfc6ae6d98c19f74fa60d19c18419131859e5c5edced88a3d465fc99943366fd77fd1a293f96de65cfe3562c45a78c2ef0fad2d4f71ce5bd3691211f4e8365cb3e3f90c901d431b3aee222e7bed2c3ece02912db961a78bd9b444bb8d958eff78fb749eacff8005e9d60eef584f69d7d3f7bab7d3b8a7efe4b56f9ecaace6e5e89ac491033865e2e54ca9ace8d0aeb7d32b44888d191b8400608c1849aaa9092b1243cf66b1750361db389108ae1981beb5987dfad277f7dd18b4f71462757d83be9d6900861ff05fa4949d32c942883633a0827e85e36d56d4a73843af9f29b8d0b4a65472b2ce1296f504c5ed57b57f210ad7ef2a17213d12283cc65c481d57790cbb2605ae52a01c94e3e0b816423908045279754a825202443e99981008a181d040ea9e00e03838ae178655ea26d2d0c001c7ca80f09e675d6502f631fd6f7fa561c107fcedda5b39f7c8e758f6d87b9cb763bf351e775de017dbff93b30d4f704d269e63b7992773cc818f75dafef3afcfe2c9f834e09c6ec74ea55fe39499173169c25dfc7ae0d0a0fc813d1e00209b7b939d9f3a9d3387fcb75dbf97e67cce313f1cbc1a4fb36e71d5ac4b99f483ff7062750dcb96dfc429efbfcb8c89db7768f7ce7bbf66c12657f0d088b17cfad52ff87527ed7c6c6c74dc6ec809ecb3d518f6ffef4e1dea7a4abb557daf7b2b8d7bfa4e8e1b7a0667f61f830eaca8bf95035ef91d53f6bba1d3717b2bbd4284d898b1410800a3cef90d2b3ffb9cc6cf3e27357f01b9440205e81515940d1c48cd9663a81e379aaa915ba0c76328f271fe356fe7a390b12d64c6fdfbee50c8a8fb3be5fed11df31eeca897c8915e2820f86dbb9ab7b05c296f67deb7bd2f7e36bfbeb07db173b15f5f5816f8000889921aa6d4d1751da149148e97f81750ae8b26f1cca25c175d488406422894eb8de5287f3d025779ccbf9026482d6f7ae52509d3740d5d1348a1077e1886164161e3baf63af70138f8e04381433970278b71fbfd835b4eb991f3debf1c003b3b8f4b7f7526f73fff0e09cad9f6474771e35f7fc766119d8fafdd93ddfff82147bc3087bf6e5dc30f860c62a1b12d8bbf7e82252f1fcb36873ec3a4eb66f39fe34604da86bf4f3b94dfdffa244dfa269c72dd0c2edc6fedfe78561b6d5aabac9d201219d769dbd6c4639cf1759c47a6ecc12ef3ba1e37999cc9892f5dc694edeee1c4fe034bb6c9e59a905afbe771dde5dc9edd92174c2f7bf71b737ecb250b3ea7c290c42acee1f6ed3d5f1acb9ec3656f5cce17598bac8a73c276d77340551500b6338febdebe845713096240bfba3f70d3d69d3fd7dac2f3d92c2f565503d0afee2496bc350de8c86cddb1f45b4edd7a0b00b6187a0a4b9ebda3643bd838e938bedfc44eeb7a4abb5579af7b338d7bfa4eeedd7f4c70dda7f62758f6bf3a1db337d32b44888d191b8400d067c2d6f499b07587f262c6b618850cef6a99e5749319a098a12e36cd295c63b1b050d8af476b59c5fec5ed4b4516f23325770529f3bbff42824f47918f98a4dc60e7df550e9e97b44008cf57221f9609f0f227483c9f09958f3eabe77f1884f2e611087ce94d20b06d07a5dc75ae01f0d177c2b9c03f482dbb0ff00480078ef90937ff6f09934eb99403c5135c7ccbcdfca469241f3c7c0c438fdc17fef821efdcfa15993f2ce2eb8c834abfce2bcd39727ffd04809feed5fe07f5fac52338e7370732ed9287b8f9ccdf70e17e8facb5f5fb78f0b5137830f90ddfe46ab96acfbb4ab671dc259cf7ca742edcfd51ca7b20241ffbc2f94cd9f1494eecd7bf43dd91338f045cea53dff283e11790502a18b3a9e9262a079c14b43dfff367b96bff3718a2e9a43399a07cc6ac5f3366fcc3fc5f5535c9d4d34c79e96a0ed8f732afeeb593f9baffa53cbec30e00b4a6dbfa7d97d82f1ae32fcb1671ce2683f966d94d58d6bb25db7d60d96cad7b0caaae6f836dbddfe9981b231dbbc2aad0ae27ef35f46e1af7f49d2cc4075f9c47bfbace357cbd995e21426cccd8200480ce50b8ab5ec87c7767035fca9ca7b3765db529b5abdf9d10506a1dc5e86afdc576fbc59a81e2be9df9267426b494f20bf014152e4ab99e9d7f5e73e05816ca71c055c8fc4ebf10c2930350a0246edecc4a21f2fed502a14940a295b04d5579b322d775702d1bc4bad700b4c1ffbcdb6874d9ec6500dcfebb5fd2571cc2c5b78c63d9eccb8163281f782a75e6d52c7df12196ef358f58df23189f7b945b3f6ac07aaf1e23368aa38b2241dd75cd590c352ca65df210b996596b69dded71c44eb773048a0f16fc9e33674de7a53dcfecd0e69ed74fa46ecbe9ec1a8df668ccc3060ce19e2f1fe2e775bf225ef49efb6602a0f8f89b4b39f4b5569e997c34001f7cf6367b8e3f2f687b68752de7bdfd270e1fb4277b0fdc21289fded444df774e6646fe3e2e5a82ba5b1a1bb977f276c17d45ac676b5e539cb5cba5fcee9d691cfe99c9e67587207af075da9d28b531d2b1a7e88e763d79afa177d37855dfc9798baee1ccf9e5dc3165df4edbf4667a8508b13e60faf4e96cb3cd36dffbbc1b940090ce645959df4cbf4dead075891f8506da33bf01135c54bfca3bf025aabbd32a7426301433d6a5e62f64de4badb79400d1953053aa7f57ed0be92784f09870c7c275045293f988a80ad7b61042e13816cab54128040221bc1d7e2f4598c271fd90aade67e5d76b4282f4f52b9e0993c7f8e74da51c1b5739388e0562fdd100ac78eb2a00e2fd8e08ca0211c6f389ce236fda25e39c39a492dfcdbd8fa76eaaa2ffced33865f9ff38f7aa7b58b63243bf6dcffaffec9d779c16c5ddc0bf33bbcff35c87a377a4a82055ba6243b1623796a8d80dd6d8137d638c31c624d65813a289c69226a8b1458d5d8982820d05e9bd1eedea537667de3f66f769f73c77071cc2e17ef93c3cf7eceeccceceb65f9bdfd49b896f8f8895ac556b971d8760708f9f52f9d961407d41e9b18d3594565dca846f52cb26bc3e813b0e7d812169e1163e678dfc07f1e9a772eac721a68ef9110539ef03c1806e375031733cf04320c1239b0b78baa824b9c59507ff87c32b3ee49d154f70dcbc69bc3dee3ac04c4477df217fa34b0ea571db47bd6c1fc5c5e3b8f7209370201a7b81f7971d9673bb21219b2f9d0423432112ce97d8a1a139b783ef673f36c4d6f49da1e1eb1a76ef3e6eea3509b074e5039cf7d5021e19ff20bdadfca2c0eedc5fbb1a93274fded94d08d8090c1932843163c634be6133d3a21480785d825797bc8e539b60f8b763e8d6af039dfab6cd29fc1b725be27d1a530072290ce9e3001a2ad790b09d1eba94af9e6d0959ca2697c2d0988292f1ad4cfa55074d28e4cd83ac5ddc8483e37af9fab5c90b6452777ac7e509c342034a23d0e08d1db0a4f43c0abea5df498e6310da53065c07e5a51015b0d33d00cf3f3f958d4bbfe0e1bb9f42c8303f7ae4eae4badbc67761d2abcbb9e0f6c7384e9b41875dc6df965c7fc8857dd0377dca2f3eabe0d85ff765e0867eac9b681489fe57e61f08ba23506a238b1225f48d98d99197ae7998a2c2e3736efbfeb1ef67fcdef7f97d79e5c8571aa83dc4f9a3fe8933fd144e9b613365d48584735c6aabd7ff9948d84c4e5753fb0495659712495e930916c414fdda1d42dff29efcf9e58b0023244c6a5dceed8b67f3481f632559be6931ddcbcd30fccbdbb6e5d60533f9e35e66f6edaabae87762298c4737122e68032478fef33f31b4dfc339b73bb75367feb06c0123fbf467fed23fd0b9d3250dd4fafdebc786684adf6dcd756dd87dfbb8a9d7e4b2550f72ce175ff2c0618f303087429fc9eedb5fbb1a93264ddad94d08f81ed1a2148092e222da1776e4bed67730658f67b97ecd4fe9d4e71084cc9dee3317bef03dfbdb15b46ad58ad2d25284b4725bfbfd32a479140468e552555545e5962d0cd8b35b6699ac749ad9e1358d59edb3ebf2b7cbe541c8756cfefa7ca1480d91d156a5115aa15d8dab1542db5896426332fea88483945ed4bf7f5c64b651a391daf6322a69240ae1ba99db2805ae0265660036430b1c844ea50fddd91e8049975c4e51591bfa0c3f92abaebe8d73c7a662614f7cec35165f7f258ffdf597dc4619879e79230fde7d62727db7634f869b3ec5d59a4bfbb5a643fc5cb47e07808bf7af1f53bb23517a13bffddf24b62889208e8cf4e3ee836e49ae3ffdedd3d35cfadb808870d1e867897f740aa77f12e25fa3ce49d60ba075021deacded07dd0ac082f9afb1ef3e298b97d631eef9e842362a41c28971caa00793eb4e1dfb30f3a6ff92e397384470e8dc66120f7842c2f1fbfd91f99ffc9263dfbc8b12091ddbdfcafd8376fc40c195ab7fcbd58b1613d671f6e874310ff64ee5054befcbe143efa7dbffaee3d425021deecf03fbe71ff40a7ceffa71ea7b27f3a73a3333e391af1d4971e18f78eee0538086fbceefe3c6aeeb9ceca67ddcd46bf2b4198f6317f6e28e691393ebff32ee1f14e77b47eca6fd1510f07d46741ff3133deba51bb6a9f0e4c993b9f6da6ba9a9a9697ce3b4324dd572274f9ecca851a33870d440120987b5f3363275f1bf79e3b09770658c43de3b8e895d7e48b741ed49e5a64f0bb121951dc7c7178ee72d5e4f615111e5e5e5141414d07467a3261a8db269d326ea6a6bd9bb57c78c7da6efcf1f649b4b80df1aeb7f76f9f43a726de387d4f85986b2696aaa509d9606554a7fd23395cc6a947d0c4a647a19a40629ed647b8510082b9431264269c7280028e32900a378688df64261566ca8dd6e0fc0bdf7decbcd37df0cc0faf5eb9b74fc013b96eb5f1dc77547bd99334f7940d309fa71c713f4f1d611f4d7d6e167817bfffdf7e9df3f95a169ce9c3900cdb62c60f7e1b3cf3e63c68c19dbec351a76dc5d2dc30350b5a98ef91f2fe38d82d7f878ec7b684b51505bc207fbbe46e5f2f59cfde6790c38604f7481b12ea714009d216ca60bcc7648100a491c278eeb5ac974950d63846ec789130a49623265fd56b1a55c71da05ccd800a2edbe3cfbaf3be9e17956f309dc85adbb3078e08064dda192817cf89ac9c55c54de954103f731e581413f799c3f9f90390155ae7102c996e618a390ad2035541e40ca541a5523f0bbc918feb01d22e13af5fac7df87e58d040085c4c2f5fa0e3781065cd735b300fbf56a40a68720a5bc323bdb0310b063b8fb9877767613760b827edcf1047dbc7504fdb56d8c1e3d9acacaca1dba2c20c0a74528008fbffb0fa68d7983553d9651beb62385d545680d4575a57cb0ff7ff972f1e71cfacad14ce87e147b0eeb89657b966f2d9342a491733de112816d45b0ed085a0be2712fdebc8921395a0b6c3b829075c9721f5e7f36f38f7a8459970f61e6c32772e20dd3f9e2c1fa13dbf8dbfbfb9a31edcd0c613ddd82fec9b4b732f69d6bf07076e61fbfbc6d679eda86c623e443087f3f9a647e4e40a151ae93e161d05a6393ad6058b880d60a95dc8d57a72571b4f2c2b76c6f80b1327b12161281d002c9ce1f03101010101010b0a3c916d6fbf7efdfaccb0202d269110ac0733f7c82505d986edff64500b5edaab0e261424e98ee5fee45459f554c3df34956bebc9c73a69fc73e237b130a35ec7a1c3d7a365b2a53db1839d8177473613c04e906f382825a36af355916ee797925b7fcc6b8da069e7d3dcb863c8c78682cd5ab5e66e09807f8f7dc57185c68f3ec1507f3fbd6b732ed7693a9616b07229bb6e64f13dadca40f7cced7b67cedf0857ed5848823b34d4aa110de3fad74e001080808080808080868465a840250bca18c0e0bbab2698f75c4caa2d83561428e6073f70ac2b5117accdc930dbdd6f2d18437297ba58cf60b2fa4d35e6df2c6c0035894605180e902e9a5aa4c2735043813e57d1ca44e85d07c549560647108ad35a192e1c42b672084da4a80760000200049444154a0a4cbb1bcf6eb5738f2c47b78e79a5aae9c3e82f91f1d949c4360d401e39335977699c49bfffc41f2f781871c4e6dad43cf61e3b9f5ce1b18549acad6d058f84ec69164653e6afa1880ad13fc9b5a6f53311985244b030f404040404040404040b3d12214804e737ab2e4c039146e2ca6edc20ed495d711aa29a0ede6223677af60d161dfd0f3c37e680def0d7b9da1338773fcdef9f31f1b2cc04610f2fe96642573cfc25fa730998b4188dcdde78bc1be00bdf7d98f70edd4e18c3c57f1f7d9ffa358a604e58fdf7f23552e4d80fef49bb9ecd3b914adea78f5c14b39eaf0bb59f9f14d5b2d64e713e09b524fae89cebe2b1432d98f81072020202020202020a0f9c86f22df85583a762ee58bdad36651072a3b6dc20925b012828d3dd7d16a453b3a7cd58d25fbcda1c3b75db08a2c166e5eda689d2e215cc2388431c9c7b6e613c6258cab4349217f4c6988e95531b4d644ab66122e1b95cc94e32636f0d1bc6a7a15d4b16c631c29653def44b6403ea04b99592e0b9970e5836c9af7e856f75b431e82e60e1fca9e44ac39bc01ca12284bb068d1a26d12fe2b2a2a0887c3dbdd8e8080808080808080dd8916e10188ac2fa6a4a2156b062f45b816edbe6d8f7404420ad60f5841974f7ad36a493b36f7de48417511d56c695400fd3727504a2511204cca0700f57d007e4dc6f60f712006ac270c2c06e09aa3ba72fb337339f8d2c17cfdf4dd743ffaba64f9a9d79cccb213ffc07f272ea7ffb13fe288d97fa34781e9fa5c139869adf976438c7eedcc8427735ef92d259d4e4caecbdebe296c4bb9744fc1d6840d25d94e25400bb3dfc0031010101010101010d07cb40805a0a8ae88cddd2a105ad0e1dbce6ceebe1157387498dd95d5fb2e65738ff584621122b5616acb356d23ed1aad731346880f931c056026a122b7026032e0fbd1ff4609d8444a303ee8f74ff28f1f5cc8c86704ba7c08cf4d19839492156fdcca55d347b060fa388aa5e0f91fbdc411173dc39ca7cc442a630e3c3cb5171966fafb66b6d52b4e3e9a2dae8d70eba0ed409e7ced9e8c366d8d057f5bc700248fbf091391e56ccf76c8ff5a80d226956b90052820202020202020a0f968110a40644b014ebb04222e117516d1e25a902669a44808946566e8b5361450ac4a19da6a50a3752ac7495af35dd2e2f6b3be45d6b7f6b677c148a81e76416ffef47266ee632104dd8ffc256b8f4c8d071873c314bef1feaedbbc2ae7045f006fbcfb169665d55b9efdf78e249fa2903da3b14f73b74b793309041e808080808080808080e6a3452800763442f99242960c988b922e56dc22114e60c524312746eb4d6d2959dd86cd1d56f3c3b91731f4807e4829335258a6e7c81742a0dab6a1564a705d509ea829044a6b2fe3bd3f91154821406be30910c2840269a8894472b63797e09cbe2c397998526933ec66e6f1f7c709e4cbff0f241584f46dd2ebdadaf09d6c1acaa2d4d83102346508712e8f84391e856587408ac0031010101010101010d08cb40805a093db09b502649d85438c36b33b122f4ea02382ae737ad175412fc2dd25a7ae3a9551fb0da1a4bc286fa88bbfecd8af662405ecf46c37e902743e01786bd36f3675b6deeced1bcac1df94b9001a6b6753273edb5968ad112af0000404040404ecfe4c9e3c7967372160273064c810c68c19f39defb74528009796fe88a5ed57f04d742e8b0b1751b7258ae3c469156f4dafea5ef4eddd973ead7ad2a9673b2205f9b3be6467aac916b0b32df10dcd9edb14e1b8a1349ab92cf5d9bfb385ff7ce1428d6db7adec6805a2e1f20ab48bd2c14cc00101010101bb3f93264ddad94d08d809f88adf77ad04b40805a067df2ef4ecdb85831895b13c5d10cf35d03597f53cdb72de540bfab62801b91488ecbffd7a9a32d0766b8fa1b904f8e69ee0abe928d04116a080808080808080dd934993263179f2e4ef5c016811f300e4235b40cf16a0fd3cfcd9cac1b658ceb765c06b7a9b72fd9d1da3efc7fe677b28f21de38e267b7fe9edded1ed108085c0f2b20005f3000404040404040404340f2dc203e053178db37afd66c2219b92a208254505d8b69577fb862cd8f93c035ba30434462eaf41f6eff481bfe9db6c6bfcfd8e10cef3793076f4180129341a1d780002020202020202029a9116e50108d9165a6b56afdbc8a2656bd95459b355612eb92cd88d59b5f3290f5be301c835e6a031af443e0525d7fef31d5773b1bdca48be4f63486d3e81072020202020202020a0f968511e000029058ee310578adaba38aa95c6b2520265ae909e5c42f1d8035fa3e71e1dd86fffae149746c0150829d14894823816c725a6e020505a228457af00a7aa9a8a0f3f60e382054cf8ec7f4d6a77be3cfed9c27fb657209fa0dcd0845ecda5046ccba461e9c81c7a83da9aea54e0010808080808080808686e5a8c02108d25d8b0b98a4d5baa514aa19462fd86cd844216edca4b89844340feec3afe329f9a2ac1ecafaa19b39fa4678f1284b492e59512c41c41977117118fa9b4721ab4a6a6aa92c40107128ed6e5dd5736f9c26872e1a71fcd954528fd18b2e701f03f7e393fcd69bef6589695d72b91de8eecfd376570b0d02011482dd1d23b2702a430f30368add1c2afcf2fa532c641e06a64300f404040404040404040b3d2221480f51b2bd9b8b99ada689c582c8e6581109aba6894b5155ba8aa89d2aebc94b6ad4bf165d2c6b2f4b88488c760fac7eb905262593259ced582eaa8cde835af92286ce74d08663eca71d8fcf9e76cfefa6b62a1088c7dd494892ee18ad32ee0930d40db614c79f64e7a15e41f9f000d64ef71ab1973f089de8464e0c657f1edf2d654aff908801b4f3e96ffae8912b23551d58a8b7ef930571cd639b9eecd35512c4b1353adb8e8970f71c5f82e79f7df58c8d103271dcfd3eb6a01f872f6d70c1e3800d01475388d779f9f841b5dc2e5a79e9ff3b843ad3b3064e000d08a6ab715d73cf404178f6a87f215887a0a469af2a6345a0804c13c000101010101010101cd498b500056aedd88521ac7895258f8153d7abc875209962d3b80446204355a535717a3aaa68eae1ddb100e357e58524688846dbefaa29a8a8a9558b6446bb084c05182759b6d26fdb23d5bd6d4e22a5f385628a551edba5374504fdcb89bacef83ebce66fe510ff3e9654398f5c8499c70dd477cf1d0d86d3a5e619530fdc33793bf67de7218e7aefc45f2f70d8f3fcf6f5b85104250b9f025baeeff03ae58332db9ee77ad4ddcbb59776a725d36bea7a0a1f1063f7efe457eecfd5dd0aa3333a6bd9951e683ebce62fe518f30f3f221cc7cf8444eb8fe63be4c3bee591fbc07c09a59f7b1e769d773d1a2c7d1987e33332ba7edd88fb25246e5f23d1081072020202020202020a0f9681183801dc7251e5f4d69e92becb9e7544a4b57110a6da47fff579839f31962b1152c5cb48875159b59b976238ee3365e673c426db49068bc88458b040be6c3c2f98a050b140b16b8cc5ba8a9fad7b3d44cff869a19df5033630e3533e6513d633eb1796b897dbb96baf96b9271faf7beb2929f9fdd1f807dcebc8e65af3c0240f5aa97e9d5f348beac4d00f0ec150733f6e677ccbad56f71cce8110c3be818cebcf5650a5b77a96f91d70e3f79622197dc362cb9ac6d2b13eea4b5a6aeaa9282764393c7e5af03885667ae2b6cdd8537eebe8643c71fc55e7b8fe5172f2f4fd619af9ecda4932630e6a0c31932fa449e9abdb949e329ee797925b74c34c73df0eceb59f6f2c319fdeca25102da0dbb84ba4d6f6684f8e41bc89c4de0010808080808080808683e5a840720169b47af5eafd1addb528450d4d559680da1509cc30fff84e2e24dfce94fab9838f11744c2615a9514d1a675498375566c0951555984c44621f0a2e609a131a2baa0a8ff49c4ea42241c2f3405505ae32a402964b43259df475509469746004db87438f1ca19082128ed7a1caffdfa558e3ce95edebbb6961f4f1fc9c219e31042f087937f4ce7ff7b99578edf8305fffe31cfe768e7a66f7fc7e7e12378ab6be6f14cfec1094c5ebc94c51bdbf2f4c72f658c43987ccaf14c5ebc94451bdbf1f4c72f65947b71ef1ff3f6f5bda85cfc143dc75dc72f8ef90742081e3fe56c86def50e7f1ad286aaa5cfb3c7f89b397bde8339fb2e5d48f78f5b0888948d4c1eb717cd83160a8460f15bbfa1b8d3c96081f4f44ed77593f509cc9801b3c01fbb10780002020202020202029a9b16a100fce31f3771c9256dd9b831cc238f5470f9e51d78f2c9758c1a55cea38faee08e3b1c66cd5accfaf5b7306edc491c3be1e84615806b1febcd96682b4a4a2384ac10758e4559b1c071a1c681a23038ef7e8ba56db0fcd87470b546a3105a239139070067dbb0fb4dfc03d74e1dc6f07335fffcfa238abd41b10f2ca8e4b3637a2284a0cf845f0053eb0d167eebc6e71874dddfeab5ff92a92ff223e5f2f1d35773ca09f7b2f2a39f25db3269ea8b4c42f3f1535771d209f7b0eae39b93e5ee9cb00700ad7a9f456ccbcf92cb7ffdd9063a5f761a4f78bf4be4a69cfdd6d0d88a5c4382471e70284edd3ae62e8df2e0a79fe52c077e4851666a568d19301c780002020202020202029a8f16a10044a32efffb1f9c745231871d56cd430fada04f9f524e39a580c71e831e3dda317c7805e79edb172947118d362ef49df6e28f684d94020b425213b68437d857600b4d5c17b1588c01eddba1055a83522014e0828ac593c2f07ea5216654c739b82c4cac6616e1b251c97d2967231fcfaba15704966e8841bb82261db71b5bc5351f6de2f9a77be7ccbc238464f40f7fcde6ab87002961dedf76f49977b0f9aa41404a0128927e790bad9da4b0ed6acdd477dea047c4ca484b9a8bf44c4b19c75d3d9370d9e88c6da77ff416a078f58e93b9e28a67b8e03f9392eba41480466adfc3e21d63da6060841578000202020202767b264f9ebcb39b10d04c0c1932843163c6ecec6634488b50002eb9a407e5e5113a758a118908162c8833664c01353536b6ad705dc1c68d613a74d8c0ca95b58856658d4e5eb5a1ff69c46c28b42521dba4c494427a0351052028056f94aa06a14df88feb927034b6e3525793122caf3dba2bbf7ae65b0ebe74105f3f7d37dd8fbe2ed98629579dc8d2131fe1bf1397d37fc2c51c3efb6f748f58fcb86f1937bdb182c78eedc9d2d77f85d95d4ac05ff1c68de8be3f6544492859974a5430677329033b182562c11b7752daf9d4e4bab99b4b19e0ad9bffdaef28ed7c5a83fde02b00370f6dc7658fcfe2e54b4602b070e67c7a0febdbe8b9b9eee86edcf6f45cdeba6c30b39fba93eec7dc50af7eb038fac6bf3364727feefbf674aedad39c9fe4245d6ed6dc0880161285041178000202020202767f468d1ad5f846012d8219336600ecd24a408b5000e6cead65c408cdd2a52e1f7c50c3430f75e5fefb2be8d4a998785cd2ba758211230a78f1c54d74eb5641cfee3d3266dff5499f64ab76da6b082781634942482c6121840548b496a4025a34422840a1b58bab5d122862aea2ce55886bce00e0c0fb9ea2d70f2e60f853025d3e84e7a68c4108c18a376ee5c7d347b060fa388aa5e085492f71c4457f63eed3e770c573f773d2092731ec771dd9f3e08b90d6cb19ed7dece6e91cf9c85d19f9fc13ce06ae39f53436262452c710ed06f1b7ffde0d80723670cd69a7b32921113a866c3798bffff7ee46e720d05a73d1f3cff0e5b9d7b2cfe32e8524e831fa7a9e1bbe67bd32d929430ffcfd93f4fec1050c7b5aa0cb87f2c29431c9ed0084251042822ce6a1c74e62f819f770ede7b77b197efcd4abfe0468a9b11680993440061e808080808080dd9f6fbffd7667372100e8d7af1f43870ee5f3cf3f67eedcb9db54f680030ee0de7bef0d1480ed65e3c652a4d4d8b6e098633a3270a0c54d377560d122c9b5d7762616939c7042275e7c713045458594b72a6eb4ceb21f5f46596919a15098901dc1b2c208617942687672248510da28006e9c8413239188e36eda98dcc22eeccda3afbc5bcff3d0ed885b5973444a201e73c354fccba9b0e348fef3c92c24b0e2dddb78fbb93332cadefee5bc7a02b75db8376fbcfb3690198fafb5aeb72e7b76e4e896d5197545b7ac4eae0f950ce00f535fcf59ce2756b9a65e3fda857d78f495f7ea955102e2b5eb4c1cbf3293a9753dfc3ed678c300cc8465aec90aa441080b294572923090202d84108107202020202060b7e7e28b2fded94d08001e7df45100e6ce9dbbd5e7c42f3b76ecb6a581ff2e69110ac0c08113a8ad9d41d7ae9be9d3274c345a47af5e05685d48fbf68255ab0a58b7ae2f878f3f994e1d3ad1bab42863706efadfbed0bce6d24b58bb69b3c939af8d802a11b8180bb4142239619585407b7982046670aaa3153591082317cddee6e3aa59fb770ef9c154a48e5225bbf2d0f38f66ac6f2c8c29fd781ab2f2a77b3e9a526f5366366e1a22736662612608931ab4d2086d940d250452585ee88f190ba0005b4a84b49bdd03d0be7dfb6638b6808080808080e6233058ed7c6a6a6a8094f0efba2e4aa9267f8f1d3b9669d3a6050a4073515a7210ebd6d944a39f505c5c4b342ab16dcde6cd21d6ad2b64edda81b46d7300ddba74a5439b326cdb089a0d0d623d62d6b47a21425b2bf86eaf905cd2e5523efddfa579d737360837fd77ae41c2d975e4521672edb3b1599473b523d764625a6b94a75c65cc1fe02923527ae70989abbd49c9bcf1175a80b44281072020202020e07b4153debb013b96efd33968110ac03e7bf666c3a6b6acabe8c7e245f3d8b8690baeab292d29a673a7be0ceabf176d5ab7a3a828826c40004e273b7c26df36bb22b93302d56fab6f794f5f9ffeedba6ede3101f9eadc3aa4377e5a231058c2029dcaf68336a1561a9362554b81901229ece46461428866f300ac5fbfbe49ad9e3c79329326996c4573e6cc61f4e8d1545656d65bd7947a468d1ac5d8b1634924120d6e5b5151c18c1933282929a1bcbc9cce9d3bd3b66ddb06cf414d4d0dcf3df71c175c7041a3f50704eceef8f7c385175ec8bdf7debb55f769be6db7e57efff6db6f1bbd2783fb3d2017df27e17357e5fb740e5a8402505418a1a8b003ddbb7460f8e0b17963d4b3d9d613f95d09feb966dadd5672f549ba20ef5be1f3eda721cf4143fbcc56a2fc7a2c04aea780e4da6fd243208cd5df08ff36966da765643275ee4c0f40fffefd93c2ffb6921e06958fe2e2622291086bd7ae65cd9a35c462315ab56a8565590dd6dbd4fa0302767776a5177763f76470bf0704ec9aec4acf911d4d8b50007c7209910dd1d41399ab9ea608e43bf242c91586932bcc26fd3bbb5c2e0f41bd701cea0be8cd3506c084f9482ccc605e94d72eed85fe4881f0047f2c09c24258c6f2af100861b65fdcc2b300650fe4cec6755d56af5e4d656565d2f3b17af56a3a76ec48a74e9dbc8c49b9ebcd577fdbb66d19387020a0a871cbb9fcdebf70fea8768db6b56ddbb66cd8b021efef80805d955de9c5ddd03dbf23eef7f51fff85f3ae7984ca70313a9660c8397fe1e1cbfa35ef4105047c0f68ca73a463c78eac5ab5ea3b68cd8ea5c528004208621b3713abd84049c70ed8a5c568e185906ca5acdae06cb6bb40d84fb680de9822d0583dd934a7e7213f1250a0255a0a6f3e05df1361f62b6d13ea83af002051e864d620df1ad6d2c700e41306b4d6545656b270e14256ae5c89520adbb6d15a138fc7f9fcf3cfe9d2a50bbd7bf7a6a4a424af97265ffdefbefb2e006b3fbe93e1675ec179f3ffdee4f636f43b2060576457ba4e73dd933bf27ebff8cc9b99f8fa379cdeb715a8285fcf896e757f388ec9b4b73d34471d01013b93c6ee1b3f8948972e5d58b162c577d1a41d468b5000843659f99d9a6a963cfb3c85caa5d5be4368d57f6f0af7e80196442ba3080861a1bce78f4421fc73e9079ae3af1348cb4a3e4c9327ddfb128022bf25dcb76ee75be7b73b790cfebc02b996652df7db296d4f60f605679d6f7fd92f0aef5b667a02a4bfdccf6ee409d84a29944af59510c2e4e0275d7807a51c53d613e0b184992959fb0a954c9657022c5180d61a47294ca08fc4b26da465a5047fd3111e0aa13596008448f6cfce9c0760ce9c39800905da1eb25df6f1789ca54b97f2cd37dfa0b5a6a0a02039df837f6d69ad59b46811cb962d63e0c08174edda15db4eddb2e90faa5c2101feb276232e23b665afe4ef45cfdcc0654f7d493c1aa54eb5e1ea3ffe85d3f729e7b5734e00e0e0830f06e09d77de01e0cd7baee0ded7e7b06a6515a7de39859b8eeeb65d7d1110b023d8951400c8bc2777f4fdfe75ad43ef76116f7998fefdc3c96de2d55f71c3f937307b639c68bc842bfff857ce18500e40870e1d987cc5f14cfe7031ebd62fa4f484e779efd67d01886d7a953dc73cc3d26f9f21d1c43ada9ff5479e3a77cf1dd29f0101df050d3d47dab46993f1bb5bb76e2c5dba7447376987d12214009f82d6ad9196a0e29f53d9f0c69bf4b8f03cba74eb84b00abc2d3c01594b108aa4153a077b0e5ac39e7bb6e2c0038b292db59096cbc4b39f62f1b2bd79efedfdf2b64108a8aa527cf0410df3e76f61fed79d736cd3b42c3a8dd1d4b49ddb5b3f786140f5d609b41249cd416b81d6a9fe745dd7db3835695aaabc44e17aa13cde805e29119605529a4f0e72a95b3bdb03903e08785bc8b6d8c5e371e6ce9dcbc2850b894422589685ebba49af871fe3abb5992d5929c5175f7c416d6d2d7dfbf64d0a058d7900fc65f35fff15856d26247f7719ff53fe73665b002a173ecf90137fc9695fddc7917f7d013a76e4edb7dfce28ffca9e57f1d2d5bda95cfc57061e7535371ef5ec36f74540c08e62575200d2efc9efe27e7fe0fcfd387ee8180e3aec200e3ce468ce3de3708aa4799a3e7dfa0f19f49bf7f9fda072aa973dcfa0637ec6e9b31f4e967d63d04ff8cfcff724bee503f61a792bce2f5ec002be79e82ef6baf801d0bac975a4b73320a02592effa6dddba75cee53d7bf664f1e2c53bb2493b8c16a100682171133136cd9b4fedc245a8682d221e65ddb48f28d97708a5fbf43382657639ad33acfee96cd81066d972c9b0e121faf50f130e2b0a8bf6a04d793b7aee5194b72daeab993933ce5b6f4b8a8bc2f5e2ed333c068d3c071b7d5026bd17b9c73e3416c6a4b31ae07b467c4b7f830a009e67c42f287cc1df2855e625946a9e3fa197a957985cfe5a8334d67ecbb3fafb31af08d168fff8ec4c0f40730d024eefeb55ab562585012925894402dbb63314473f34209148605916b66db360c102cacacae8dcd9289dbe852f9f0270e8a187028a50795f1e78eeeee436958b5fe3da8b1e67e91617db12d455cc47eb7b33da9bce6d47ed81d69ad23dce22bee5ff82177cc02ec9ae343036fd9efc2eeef7f1b74de18b733fe3ed0f3fe2b5a7aee5cfafdec0274f9d03c0dd9f6fa0e355a7f08cb76d89dc9451fed7137aa3b52654760097b5b990bb166ce6a77d4ab9edc945fcdf8c3dd15a37b98e8080964ebee7c8e6cd9b1bccffdf1269110a40edea35acff7806ab5f7c0577e62c64c2415921aaa77fc2fc44822e279d409bd1230977689f0c57690c13a728f8f0c304e1b045717182c30efb9acaca185f7f3d206fb944023efc300108a4d4f803667f73e1593c33ed53e6afda42ac724d32df3d801b5dc2e5a79dcf8c0d40db614cfdd79df42a300a8b1b5bc2e5a75dc0271b80b6fb32e55f77d22b62a5ca9d7a019f549872539ebd93de85e69409219217ddb686f12ba53206000b2108957524be650d26802a65912f2ced406de5da64d9ec01c6222d6407ccb10ba449ebe92b000d64b868889ded01d85eb25fd8df7cf34d32fcca719ca4d5cf719ce479f5e383239108f1783c1922307ffe7c3a75ea94ac3757fd3e6fbef966bd76009c7fd68d9cf5fca79c3ea03d2a5141d71e8332ca67d75520fc6512ad9de0451fb04bb22b5d97e9f7e47775bf97f71eca29bd8772e2e913e8d1773c5a4f34fb44f3c4abafd32d9c7afea6976f65a51491336e19cd89b74ce392dbbee6abf21f717059c884716e451d01012d99efd375dc221480d93fff25ce975fc1fa0d68095a08a456b8757544df799f455fce66e5a811f43e7722ad870d814861b26cfe01c24601f8e82387952ba3d8365c74d1937cf6c5093cf9e41179ca681c07962d730081e3a4b4be83cebe92337e33987e7d7bd7dbf7fbd79fc5bca31e61e6e54398f9f0891c7fc3c77cf9d05834f0fe756733ffa887f9f4b221cc7ae4244eb8fe63be78c8cc20f7c1b56733ffc854b913aeff98af1e3e20ad3d268c2691508442b9426afc65999da0d2072778fd6026dff23c076929387de17efab477d31485cc7d096f865f854c5b26b02d33b8d7f6e2fed3dba595aaafb8e8d47ed39bbd333d00cd45ba8560d3a64db46edd1ac771884422b8ae8bebba492ba0d69a502894b42c84c361a2d128524a2a2a2a322c81b9ea6f6819c0aa98a25ba712136af0b7eb33b66d635bac89397448bb9eb2eb69a9d68e80dd9b5dedc5eddf27dfc5fdfefcfb7339f1a07e0860f3fcb709150f4d6e73eda076dcf0d7993c73e10800967c3e9f3d86ee99b3ae8e87fc9af8e527f0e2cd30f2e6e7b6a98e808096ccaef61cd991b40805c079ef034838a888b146588938ae65a184a0cda187b2e59db7b1962e67d1fd0fd1f5bc89b41b77085641887cf1ff00c3f69b4b3c6e230524e261dab7df8c948be9d2f5230a4b16d0b16305901ea562a4515741cfbe26a3a5a60621cc80c9b1e3c664d49f7e11ddf3f24a6ef98d19443af0eceb5936e461f084fc7b5f59c9cfbd7503ceba8e65431f49aecb554e3f64e641089776e4c9ab8ee381f797d071e21f78e5da03f8fbd52770ef7b735913ebcc1f5e7a9243db470063bd7ffee653b9e3d57954acade3acfbfec9902f7ec37dff9dc78a65954cfcfd546e39a66bbd0b3fdd33307aec2144abd77bf575e4a55f9cc11daf7cc3ca15d5fcf0be29dc7a6c37045050da9658f54690165628841d2a44ab38d52ba6b2d7a0dff1ea8a690c2d0af38f8b06716f9b7bf8e4ae231b3dff3bd303d01c8380b32d76fed809dffae7ba2ee1b00927731c27b95d2814221a8d660c12f46387fd7a73d59fbedf5cfce5d633b968dc21b4eedc9a3ee3af015e4f6efbdbb3c672ccb8c3282fb479e38d3772d6f37d7a4006b41c76a5eb32fd9efc2eeef74ffe7a33f7fc7c0385614154b7e5b6271e496e73cedf9e62cea4eb19fbb443010e5d475ccd5f87f4cd68ab8f0c75e61743153ffe20cafffedc799bea080868c97c9faee516a1002857e11617128ac6908904d812c7b6b16231122b96e31615d2f9dc735876ef7dacfce7bf28ead19d56fbf46b303666f203e7525a5649380cfeb85421e080311f33fd7ffbd7dbde1f4ea014b82ec4e3b07e7d182196e5d836151a04f051558251256100c2a5238857ce00cc0be1a3aa04a34b23d80645d30000200049444154080191b291c42bcfcf2837b22c82121abbcc943371fc66fd2b836fe0bddbf602a0f85a7861dfffe3fddbfab0e0854b1877f2132cfb60525281f977df2b79ffbd7e542ef92b5d861fce397f7e91b76eec4be592bfd2f3c06bf8f9d27f66b43f1f7edbfebdf7b5bc73432f362f7c823d0ebe865f1c3b153ccf80150a239029abbf1094743b85b7ee799e438fb89d6937d670d9fff667f9d74778ed93267c286b58807ff676b607a0b90701171717275fecaeeb26c303fcf85f21048944824824926119d4da640f698a40b07cf9f2bce7719f89bfe67f1353bf1fbc26b5edd1b73fc3d169edceaea7a17a03027626bbd275997e4f7e17f7fbed8ffe2b671b00ace27db8f3e95773aecb753f9ff0cf4f38613beb080868a96487ebeeceb4080560afbbef62ed9fff82138bd2e5a20b59f9e864ba4f3c8fcdd3a6d1f3d2cb5872db6db41f771876ab7236bcf71e6ba7be40ab7d6e6cb0ced7df3f0d3bec12b2054a45282a8a72eab18fb3aea2332fbc760ee5ad2bbc2d456ab0ab06a5348ea349389a9a6a87bdf7a85f77830274036dcab72e5f2ad2bb4fe893f1fbce09a631bd27dccea68b0e40939ac2feee93f606a0ace70f71e33770e771bd1142d06a8f33896db929b7f53fc760619fbb8eeb851082d67d2612db72931904ec65f6b1ac9097d73f8546d3effc67b8fe1f7b30f834c573cbe6512c9b367861779b09b873e7ceac5ebd1adbb6715d37d9775aeb0c81c017027caba1d69aae5dbbd60b09c8ae3f20e0fbc8ae2484a6df93c1fd1e10d072f0efb37efdfa316ddab46daaa35fbf9631095f8b5000ecc2420afaf763dd6baf52357d063daff83155f3e7b1e5dd77e0b2cbd932fb2b2a67ce64de5d77e2ae5a49d1808148094aa5f2d2a7a3b5e6e6eb7eca96cad640040803163f741fe7e5ff9cca9517dd91a7250a70813810a3a0602d574e94c93a7dfc98787fbffb95869851ed7070599858f56784cb4603261bce7ea5213ea971cdba1ab34e08931a6e4c698819d5710e69152156332ba31c409b9067614f9b1f20691df2dcc8befbb9c4f60616bb21004a6df3e2d184cdc04e29b0c8cc646404fadca9548bbc197c5d07b47608852258e108961028cb46025ad57a5b4b33af825bc14773abe85d2058bcbe0ed1beb85ebdb9949d9ded01680ed2af8f3e7dfa50535343555555f265ee0b04fedfbe30108fc79396c256ad5ad1bb77ef0c412057fd0101df4776b57bc06f4f70bf0704b41cbe4ff7568b5000963cf020759b366255d7a2eba214f4eec3fa0f3f40bb0aa1146e248c1b0e99881f4be2d4d6365a670a3300b6b8388a94d0adf33220778e7a432a374e63178abffedaa3bb71dbd37378ebb221cc7eea4eba1f7343729beb72acf3cb5d7374577ef5d45c0eb962085f3f7927dd8ff94966cb93c2b2f9bee9b5e5fcf9f83d58f29f5b68ddefca8c0c3f5b83494f673ec60d90e705941e3bea59ff0f6d1de1b1855bf8519f562c7af9fa8c7aff35e910969efa0cef9ebf84bee3cee0e865afd323d27866a0dd2d0b5049490903070e64debc79545454505b5b9b7ce9fb9999128904f1789c582c464141011d3a74a06fdfbe14151535790c4040c0f7895de91e48bf2783fb3d20a0e5e0df5b73e7cee5e28b2fdea63a1e7df451c68e1ddb9ccdda21b40805a0689ffe88599f21ba76a374ecfe2cbcf146ba5c7c31754b97a1a5c48ac5a8fa7a361d0e3d8ccd9fcd4275f1072f991969b365e094489bc2df46e9ad4b55e95f2c7f3ee2007ebdbc1a80defd8752d6fd3a66fdd7045a8ffdfd53f4fec1f90c7b46a0cb873275ca9864bbc6deff34bd4e398f7d9fce5c0770e0ef9fa6f70fce6778daba0c4f037e8cbdf93af6935f72d03df35955d781c75fba0fe32df0b7f6bd217e1f48844ea52a1558c92c407bec3d38b98fa2763fe0ab0f7fe1154a791f3432e96530d55b80e4d1bf5ccf1107edcbe4eedd1870cc8dc0640096bf7a3d974e1bc38a6f8ea248485eba620a879cf9288ba65ed2681fb7f4998073bdb0cbcaca183468101b366c60fdfaf5ac5bb78eeaea6aeaeaea1042108944282a2aa257af5eb46fdf9ef6eddb130e8793f5657f070241c0f79d5de91ec8be2783fb3d20a065907d6fe5cbfb9fefbbbaba7a27b57ceb69110a80d20ae524201665cdcb2f52f7cd1c56fefe7edcd6a52c7be07e40b07aca145a8f1a89685d4e9bd1233d2b76fe3a5dc75fa90085d20ad78598538809f3c9d992b44f2ac408e0c2373ee4423243581c6fd65caba037935f793f678d76611ffef4ea07391fe87eb9f489bffcedeaaad6d5d3624efad5e39c94f6dbdfb6b6aa22f9b71082baea0da67f94a9af76cbfae4a0e568d5866459cb5330945026b38f47b466636a1b2b84eb44119e22d0f3845b997bc26d5e9b154fde62fab2fb3177b3e918bf06c1d89fbfc3a29c3d529f9ded01d8de41c0ebd7afcfbbaebcbc9cf2f272f6da6baf06eb705d37af22d350fd0101014da739147ec87f4f06f77b4040c0ae428b5000d64f7b1f94c6deb405e7eb5a425250b76431f136ad887ffd0d4e71112a5e47c52733293ff618ba1f39bed13adbb68d22e466946ba3b424148ab36e5d848d9b2d2291b519b3349abf15a01142010e102312de04b44bd6b935e136d9dba6ef2f6d2108919a10d85ba691e065cd4947a74dd80420d2ea4b9ff42b974291514fc6780681e56d9f3e124008814222bc197e9365fdb651dfcbd27068557d76852c40cd3108f8edb7dfdeaef20dd1af5fbf1d5a7f40404ba23906df6dafc2bf23efc9e07e0f08d8f1f4ebd78fb973e7eeec66ec705a840210deab1f359b3691881462c762387608e138b891082a1c81766d09b76b47fb71e3e87ef4780adbb7c3889ff905f2b95f77cc127e23c052269e04133d33ba454a58f6b32ef883b7b42e06da242de7f9c89e3137d7dfe98a463ab996fbfbcb5650eaaa37a46d2bbdf56eb2ac9f55229ff09f9ef33f7ddfe6dbfbdb6f83f76d59b611febd7d6a9da55c785e00d160eea3c6d9d91e80ede58a2baed8a1f58f1fdfb8c2db2019b78af2ceaf22a94822510aa4008422515b436d6d15da8de12a8784eb120a85915688f2b61d711c17db0e138b3b44222193eb5c28fc2b477833e4496d1e3fae7f5d8a948ae97b90c0ccbd619659deb56f19dd181abac55b0c5ae7f338a668e879a175eee78adf7fd94abe4267dcdfb665e3b871941b07ed22dc04ca89e3c45d94abb1ed020a0a4b90054520241ad7181b928abe8b44a642125d53afc401e1b07ecd129c441d5a25b085f70c75416b890528eda0752adfbd24f319158d4601b02ccb4c2ae83dfbccf34ca3120e429a70c46d19f3944e7328fca3f66ec3a8bdc7a0bd197ed38f492993f7df6402b2711cc70c04b62d2ccb422351d8682c12aea0a8b88cb2d6e5102e30950b187fd841e60f4279aeff5c1982b6cef8d27cf8cf91ec6f731d2aa5706251e2f1282ae1604941b82042245c00b6092bf5af5e93482241acb68edaba2a42b639e72565e5c46a630861138bc5282c2c2016abc3b23588b47b4b9bfad02140636907917cdea50c68ae9f9c5a9ae7933f403b140a615916d19a5aaab65452183213b9216d428585d8e142a465a1b5c0c5055761474284426110025783ab05480b095834fef84a973b72fddeb1a4b252f97d906e44ccfe5d5f4ed9ba70ea5d8d4001d845d8e76737b371f6d754ccfe8ada458b885755a11184ca4a29e9d69d76830751bacfdeb4eadb877071042124ba8149c07c1a7d59e84cc1385b806eacde74c1375bc0ce16e033769bb63c97b09fef0694d2cef8ed6833d53c6eea46f6514a21bc349c42fb2fa4ac874a8e431449c9cb3c84fc32fe980bbf58fa0ccc1ab15d4ac0ee90052817b5b5b56c5cbf918e9d3b110aefdab7a2d63a3980c43fefae9b12d2b4d6949696e2c4e3d89102a2755142e1826416aaa6d49fef764cbf67ccc76bcaf7240c3afb3991ebb9d5d0b32cdbfb271168e12b01124743dc81442c8172eab0b48ba515288dd40ae1c611ca01ed6212fa6a54d22ba810be4221bc3b3da99959604141411151e190883bde73419a6f25514220844b438915fc5cf8fe7527206d82acdc99de76268e36cf5ba9054a0b84062504ae52d4c404115b63494dc47b7efb8a8bd21a0765fa46488acb5a118a14835500be72a55586b29e5bb0df59c27e2e649e6f23da4b2910e130424a1cdbbcaf846da32ddb7bff660ac9d20a21422eb65b80d675c668e05d075a09d03219fa2b84ff9ff29e5126e187560aa9410b81402677a0b56bc6df79e55d2f4353d2e8a7045a08c2a122caca24b5951bb16d1b8422168be16a41a4a0102d05aee31ad54539a004dab28d402c04be29a4258ac7becc118c41d93dd8b5a50e8f762346d06ec408f6c2089642a7b4614b82502ef1441dca4d605e502a69b996da4b41b98def07a3c52aefeff4177046400cb91eba52e30df6f515022b294469bf988fd2490b686a7b40888c6f55efc69308611e5226a7b43fab19d8cabc585c5cb4abbdb01d81f42c1121e91d9bc0c4f0fb5abcd668a5d22c8b9ee02784e97f40e109ffc2a40ad55a6508708d7946b686963e13703ee275715efcf6399c4d0946ce3f809e837bd265ef4ecdbe9fe6c0647d028411be1cc701ef1c87422122910876288493c814561dc7494e7cd4947d3424dca62b00df2772f54bfab206efb39c7dead9a385f6ee676395d45aa014d8264500422823ee2bd708328e0352a0840469e1a271b522e24d00a895f0e70234f56b095a110917e0ba31e36140a134b8daecd742a25cd29ed9699ec634e5d2b7429ab14b2a69390788d896d9170d8ffbfaae10cacb9096662c320619cd865a2348862c4d9b624d514822a506297111a08d21c7b2239496b506699b992a21cb5cbcfbdc049665bc1fa150a89e873bd7b5ef2b4daea3d1da78058400e579d232e74d309f742f59bae540a1533ffd8b178d26a538232c3466d666d775095b618a8a0ba9dee2202d891602c789e2e2226df33c346753a194c67541088590e134ef96a0253cc8f28508ef4a0a77c0b6b32b990af262c456f3c8135a1a0540696c69792f2a816ddb58b68d1290d00a85c612124b48249651049440286134792590c2c692a194ebd875c075905a119226d440b966f65f7f1bad5d94721012842dc112e63d27354a28efdbb4dbb62521697942b5442170b5c425841261ac7031c22e04193259743cc5c642600bb085795c486d846f5bd8d83284c40225282c2ea5a0b09870a4103b144158b6978dc7bc488488a00921ad022205a5840b8a09850bb14261c20505b8da08f2481b2d2c63b9300e7e94002d14488db06c8465a385c451e02833219af1b4f8eed294fb5d80d7efc2f4bd67ffdfda8fcfa2458bb649f8afa8a84866d2d81e468f1ebddd75e4a2a4a4840e859df85bf19fb8a1f325cc5afe295aed040926e3599edb629714c694229e489070158e92082b4c385c485171a9091789448845e3440a0a3cb7b1c8da5186d68b12ca28be2277d842fa9c1af55e3adfe13b283bfc2dff5952599fc6687c9b7441d8ff9d5a9ebb13d2d3f4a6df9b5a6bfc7f00528bd4fd2a2552d86861a32d0b2d2c6330f0a74af71e2dc60a2fbce79434a37e8440e3e2cb534afbc29536f38358211036681b90486d8e5d086dc27744ca1a8e14084b263f0a01d2acb36d9b482444515101c5c5859496167bcf7e816559e6f1b71dcc993327a9f46f2bd9d7aaffb72d216c09622e54c70535714f0193a64f00b024e18208c5a525100a81657bb12902efa1ecc9b4bb80a6b39da4bc3886a48747648fbfd31993a4657bc4d2e75530e7df5c4baeeb66ccaaec97b12c0b615b19fbf6bbd7944eb5273bbc25e9459712db068479630aa950ca21e1d4a1749c70c4843b699540b9092ff4cb9763344d7b36ec5cb2438473852106b46c5a8407c0a0a8dc524b6555156ddab4a52052e00d72cd8a8715a91790857f034ba417eee26a8dd022ed85eabb915d2fe6cf8b3b765d84c8ad1f09930113a54d3ca711dc532130c27f56bb5efd9e555e4863a1179609d591b66d8e415968e58072d1ae83560e4ab9c963f3861f83f6662110be52e1df90d9a13b32b95824db24d0226426e8d22e526b74c87fe9a63fe08c65176da6ad374a574ae0300f647fb7f5437b768475a0a5cf049c8b4422c1eab96b58bc7221c57b96e1b68a31ebc34f19fcc5be741fdae53bb1b0e40b411339ec02a1903f919c26545048a1b4482412b86e82a270315a790ab86b2c7af168026149c2e1b017e3ee5b315552f854f8f1acbe67cfdf9b4c09b94a60d921bf611982b01fbdab557abadb14be50991a0b93755cca0ba2900d4713692fa050629e1f2885ab35b694589ec429fc1629c7bce0fdfd09733ce97a9def0314a894d7ad015b8c6d674ab54db9344c9d56daefecfda77e688c15dd2e2c226609e2d128756e0c0b0b2b12a6a0bcdc6b9f79f0997b5e833651ff264cc34f09ac4048cf986ac41d2b524cb194c462095c15f5c2583461a989476b282a8ce0ba0247e9643f294c2887521a6987114263090dda456b854423a4404a4d547ab3eb0a6d9495ed647b0701e379004c7f08df954b4d5c104da42e84aa281486256505d2bc2fd0d87698824811e1e252fcfe3671e6fe75e28b909a1dff84d8f1a487a7e57b1ef924c78878de6ead3cefbe52846c8b44c2454a2f34561a4f4b9ebda67d0bb275e8ccd8f5d44acb0a99764a81560942611bc789a265083b64e36a88c763d8b6456171116e22619e775a99503a933683d435b16b936b8c60fabac00bd0f269111e009f583cc65b5ffd97295ffd9d4fbefc98b5abd765584cd32d086681405836d20a21ed30321421148a60db21ac906db47e526ec6fa31ed507f6062dadfc6f44fcab2e985c39059876f75b06d9b5028846ddbd8560881400af330b34321f3b16def182c94f25e84c2426981a38ceb5c23105edefda49021486b0f99c790d666ff387d97ab694f28e986b5ed30961532163bea5b1fd3ebc925fce7cb2cb43dec6c0f407353b9a18acf5ef992c7974de6ad312fa22d45415d09ef0d7e8907aaeee0cb5767a3b7662e3b8fdbcf9ac0deddca733e98af3dfd08faf71bc090a1831830fa589efd667372ddf5478e61d0e0a1ecbbef60fa0f3998dfbfb63ca3ac6f45bbf3989ec6025b5044714919ad5ab741ac7d8ba3f71bc98831fb33f2d8ab581e5726b0434a16bf7427fb0fe8cfbec386d36fc081dcf9e262e37d73ab183e6c34c3869bcfe0815d28281990b14f737d59d8e110ed06de8556a9f0b807f6ede059abfd7bcb08f1fe7874db120c1b3684a14306b1e78003993c7d2dbe45def7e0a15d3cc3b2b1102a85f4c2df922170dec771e268cf8a27515896206c4b2c290085e3c6492462c4a2b5c4ea6a89d5d6e0c6a2a05cd22d7d2acdca08785a87a23906cb7df4979fb3df80bd1934782803fbefc36957fcb6c9659362a5109414b74658161a9b8486989b1967ee0b4b429b40229171ab7ba1179e6ae60561a2b4c6d516d28e20ad88176aa4929edbda681d8ed2c9e7b4162133605258885004190e831df606c71a4fa4abcd75197312c6b062db2005f184b35dfdd81c0a7f7ab892108298036b2a5dd66e51c4d386c4c45dcd9a2d09d654394413c991ee5821db8fa132d6a68cc1cde6996f542f735e26f49a50af0d8dddd3f1ca0f084bc97ebfffbac9e584100c1d3a34f93977cae226d509b9afcf74ab726ccb0714d861c6de3f27b92fad359bbefe1be387ecc3b0e1c3193de14a562434e17098482482763671c7a567d277f058860e1bc6397ff916f3fa56686713bfb9ec4cfa0f3b8c31630ee5dcbf2c34e7c6d9c2c8fd0e62e47e0731eac0c318366a6f4a3a8d467b0a56515947c68c3d84fd0f3c94fdf63b9071275ecc636fcc4f7a2b2ccb62d39c7f71e8f0918c3dfc140e9df81b96459da4dc11af5dc4e5c78d67d090310c9f702d4beb5c2343288d10c5ec3b7414c3860e67c4d0118c3ee0bc64ff2cfaf76fd9afffde0c193a84bdfaefc7ef5e4cf5edafcf3e769b9eebd9e7ebfc179735b83cfbdcdffffaf2e4f6b61d66f8f0918c18318a11234671e1734b92fbb1ac10fbee3b8ca143cd27fdba50890a6e3df7087aeeb50f4306f5e38c3fcecdd9bebdfa0ee1a74f645e370df54943d762f6ba5169fd1c90490bf20040696931b254f06ae4793ea8798b33569ec7b8f607635b1229b2846fa11132e4c5b64bb03c339f144801a3474ea1678ff68cd9bf2bc5a511704148535e294860736ce2191c044a4b844809f34e5535151f7ec08685f339f6cbe91983d1d0d2b3aac9645cbdb443c6ea2f6dcfdd6b50cab39ef99e06092224b0a4442a854e182baa10961146709122e50a6f8c86347848b9f2bd2dbcedb497ee45a36ddb138e1a3f3746f06f7cbb6da1a56701f249c41d167ebe9097e6fe9b0f47fd87553d9652beb62385d545680d4575a5bc37fa553e5ffc29874d398ee3fb9c4cbf517b63859a26201e72de4f39f3dee1f4e954526fddc8f37ecb9d470dc316b0eafd5fd1f7e073f9c1ba1700b8f19fef73776ba32855ce7f9676430ee3eada79c9b24208be78f8649eee791f700a90ca4271ed119772f88bf3f9bf111d58f1e6cf187fe5877cf3a78341c39167ddca5d5fade5849ea5542d7e818e438fe286cab908d98a59b33ef52a577cfad3919cbdfc379e29deb791a5c6cb9cbce5b77c5a7335234a054eed97dc5e7132f02713c8a25552e915421b991bf8e2f3998066dd8cdfd26bc2e55cb2fe1f28d7f106251bafa0b0cc0d2833ace3ae5717492b5d38195792126b9556b89ea0178bc5bd9817e3c193289463612b85150aa3846816cb743e96bd742913eeaee3c3695fb14f79185494ff4cfe6993cbfb2114fe39354ab346a9c607fb19e5257d9b6c9b92448a30322c695dde1e275147aca68abada4acf832829282836e11d689432de1361626370b4b18a2b3781e328b4633c0fd2cb3b841458a11009c7c1754cc6a29d8d145e9087d26cac71a9a8d6b8799e8f8e824d350e957582f2529b725be3ba1a0bdf2d66aec564d48f30d79f40b0e4853b38eb96bff1f5aae50c1e349c713f9bc2fd67f4021abfa7e73e721d7b5c700d5fde712b5cfd6c727963e53efffcf3bcc79dafce7cd7677a58dadc3fdcc01e175ccd97bff925e29a7f25975f35fe120e7b6901370e6bc7cab76ee6f0cb3f60ee6387605916532f3a9627abcfe68b4f2ea76d59198b176e40488d725da65c70244f549fc3d79f5d4e818435abeb0081b04af878da5b8009b5fdf496719cbbf2d694410f98f1d187288c82b9f1db77f9d1498733f7f7eff3dbc3bb1192826b265cc5414f7dc00d830b59f2f69d9c74f32c3e7de00000a6ffec52161cf9205fde780033ee3e9ae3aefd84d98fec9ff476ce9a391dac9017409762fc193fe79e391b39698f52aa163d479b81e3f969ad515a0e3eef279c75dfc8263fd74f5dffef46cf57aee5f5cffd915c5d930a87fbecb399f5c2b052eb66e50c11fae799a3f973d524e6cffd49da79a8df8ebaf56f53d6fd187e77ded226f54943c7d6d8ba80142dc203a005245c8715ab97b322b684dae21ad67758cbccea4f58b17aa519182b6d33782a69c9b6b1c246f046782e78ed7967a54575257cf555155a0b7af628668f3e65f4ec5542afdec5f4ea5d42cf1e8574b9e8223a4d3c9fce13cfa1d3d9e7d2e9ec73e878e6d9b43ef34cca6ebc894e0f3d8c91da4dfa368d440be9c5e54aec70c47c6cd3ae9477011c9db208aaf417a810608710e10856a4003b5c80150a6387c358a1b05124ec10c20e9172cb677b2252613fd931c97eba3d23d89b417f7e7bf172f80b2c8490d85638e99148352f3396f8bb60677a009a232618201e8bf3c5fb5ff0c492c94c3dfd3136765a4fb76ffb52b2b914d776105a1272c274ff722fe21d6a9972fa9ff9c3bafbf862da5724e24db36a1e70f841f4ee589c73dd0f8f362f09804e632efc7ff6ce3b4e8a22ede3dfeaee099b97b4e4a882e49c1441014541309ef9143d51c470a29813663021e6337b66cf5304413d13a828060409928320795936b03ba143bd7f5477cfcceeecb29cdc21bef7f86997e9eaaeaeaeaef084dff33cc48a1389e9eae727fa28525642b841ef947b4b57bdc8c847b2f9f231151f37d929f39f3b225cd9b30080a6836fe4977726fbcce4914db3282c52994e23c53bc968d0370553ab22d2c084675672e9e4c314f32ff404f3efb677fccd1d98f0864a1bb7eecdbfd2fe962bfc76206d745de7cd1b4ea35f9f5e9cfceccf6eab6dc0a47ecfb1448a3e241a2d231629a36cc7375c70ec00baf7eecda11d07f1c20f9bc18aa903c08e831d67d53397d0b74f3fba77e946bb4e437869e176b0632c79f0083a8efb1c271ec18cec66d7ba9768d8ea5c2c33ee33ff383699751af3da0d7fa66fdf7e9cfcec0ae2bb7f64cc317de9dda33b1d3a0de4c59f8a7c785032ad7aee12faf6ed43f7ae5d68d7f9285e5aa492ee2d7df8703a5e36d7bfae62fb6b6415fc09094c1efb0ad7cd7c443157005a98e32e99ea5f2b84e0c3bbcf6740bf5eb46ad2969ba72536d9c8b68f39b64b6b3af5e8cbe937298130180c929191416666369999994892fd06d298fd65f21a947a8594108f5b808166840866e410cec82618cc463332915a08f430110b4acbe3988e4e38a70e0d9ab4a0a0590b0a9a34a34efdc6e4d76b444edd02c2b975d14259c8400622988911cac6b44004c20433b3718c50d5f6fd97c9300c34dda070b7cdf6dd12cba95939222558b66467a9c5ced218d1781c3b1e578a18a1bbc204d8b64a60e938e0488711674fe4baf7be61409301fcb4e0534677abebd759f39c96dcfcc012ee9d7417e7181f326543592defab89aaaf73cfe3136e7d7029f74eba93738c8f98b2a1ccb7caff734784bf76af8f9492c6475ecf2fef4c424a8919ddc4e5efffcaa553cf252414a6bea0a1faf6667433e3666ce48ac74613728d7a0d1b65a458c0354d036971dd0bab197b672ff506eec0f5f45d191999b4ec3d8ad7ff75052ffef531df723ead30ca459deb62399266478c63e3ac17908e8e44e7898fb670d39f3b635bd0e9cfd7b061c663aa62db852d3a326d44126fad04a8d8554846837e7ed980a1ffdebabeb754f5dbab7ea91c6c20ad3f561ab2e39b18f3ee7ac63f3b8eb0bbcc356a9c91f6dad8ae1d181907a79caba94ffe47fb860e080bc0cea22296ac5aca17bb3f6369a3055819269aad31bfe06be21b230cdd712c9d0ee9406e6e269a30109a07dfd1718444da12472a7ca9d2d52b47dc780cbe9db7dd9dd8897072b614ec8e1af4dd3a0b33a3bebbf1b99a3fcba278e1428a972e2516082107f4450a98f4973379fdabef58b5b9844859b162a3f50068023bb68e8b479cc2b78540fdbefcf3fdbfd12aa4a36b6047d770f18813f9ae10a8df87f7de7f9c36616502d68d80bfe51a68d8ae96424526485251a62515c543fdd5f1628d7ba655211266f8544b81e65a2582481907c7219091459323a7b066d605fe7559d9f97b2b4db100002000494441545876544130b4805b7f2a44caab77db574f72ea450f5112cc42c64c7a8e798b17af4a403ee2a55f929d3f889e0f2de69b2b53a120b0ff2d00bf19130c6c5eba85e945eff0d9a8e9e4eccca760755376b5da4e2c378a511e2460098a9b1712ac08d162fe21ec6cbd8daf8ffb88dc0ff368b8ea2a9a766cf29bdfc3a3b9934ea7e9d10fa59c7be2b8013cb1660d6b7616f0d6d26ffcf376741da71d75274fcc5f4a9e5e750338a7711637cd5ac383c3dbb0f2fd9b88957ee55ff3f8376fd0bfdd21dcdfb0119bb7847975c9b77e6c6deffea29f6fe6c7e0f1cc699e97c0387b2e352e1d7ccec32c39742ae2a227983a71090f2d3d88de634117e045ee98d9fd16bebde7202ce910b804e2d1322ccb64cd47b793d97014d18a32a40dcf9d74169deffd9047bad421baf17d0e3e763ca72f9bea8fdc68e92e24507fe0e57c7e8a62a876ad7c9776c3aee2d4650fd0e2cc49ec38f46276ddf305b99ae4db5b1ea0f72dcfa3d9713401ba96882cfe41a7abf9e2ce4e64e4e6f3f8e1cde9f1e8129ee9518ff2b5afd3f4b02b397fcb8b55be4df31177f0ed5f1a0050b2f2759a0eba86f3b63c47bb8b9ea5b0f1a9143fbc847c433077c244fa4d7a1f01bcb2bd820d2d726afce6efb6bf91af6e3a8492d54fd1a8cf85dc75e2c7ee773f9b82895ff2d12907b3eaad73f8075e549674baa1caeb4d123cc85ba864e2a7c748593618363852417e0259f9e41861745d609b310531334268010b231822233b8f4038030928f70f8d000ea18c1ca215bb91a28458453931379c63289c43cc8caa082de1f48c526d695f44fd1242501a31d9596ee3d4c27aea91e3488a4be2646694939b5f4f41d15cb4bf105e3020154255c3214b176cdb5aa8ae30f2e95e29075a7573ba74dd646687ffc2f4fa1974babd0723aefd9af16f0cdbe37d00fd7af7a0bcdca4559fe3b9fb91dbe9921bdc639dd58d4f0ffa56ba6e927b6f967bef3cc6bf310c21d4fa72f307eb9972fcc1ac9a751bb1d2af1042275ef22f2a6c8792c99771f8c24d18f53b70f3e39319d13a8f78d92794db0ec5f78ea5df824d88fc43b8f5a9291cdb3c5b390b63639b16156bee6341f0583e6d9687637b894e20140aa31b06b6cb37d439e4af44b61f4c38f3314ccbe2cc46994cfa721bf71e55c0aa4f2613df3d9f60388bbccc5cbe2f3339aa5101b6152798d39f78e9b9e8c2f0f87f7af6ea87378f729b5fcd97efff1980c7e7bd45ffb6ad98d4b0319bb78479ede7ef80aaf1fe6b8aff9f6e5defd6ad9bffef97e67e4fd7ac408de753bffddc1446bf7f9f5e94979bb4ec3d82bba6de46a76cc3dfe3fbf5ee454585372e26d2253748b468a6fa0e13cfa0c7fc8d88fc76dcf1e2738c6899180baa1d0e5b7f59cf31973e4e892dfd7da6ba3ef1a8bab158f9fd729a25faf97f944a078400f0b76f9e6279a345ec3a743bd81a9a1b15219a51ce377567b36cdb52ba7fd39b51078fe4e0162d3182862b743baeab54225a8dda98049a162214d459fcd36e0a0b37a11bcae94c1702cb116c2f36b8f8f606946cadc0f6fd0c54582fa77e733207b6c48edb48970139f29cf19c715f0f3ab46a841e0ca989e34207e68c1bc9cae35f65d1f85e7c376520232ffb82c5cf1c05c017e386b3f2f857f9697c4fe63f3488e197cd65f9b3474252ac003f1e8ba6f9ae5f4951e66af6604c71784a08395e5c6db766ffeaca9a2a6f82b75d78037f5b7b2a17b7c94d721876aa5807d24106ce1a791563e66de1dc76f9e04458b4389a525e9de9d8a3033d1330c0e78b3f65cee019e46daf4bc1aae6ac3f6219194559d45b5340a44e844079987ac59914372f64ed909f69f9d5a14809b3bbcea4c7a2be9cdaf14fbfb90d00cb5e1fcfa8677399bb3c75411cf7c1578c43f2f5f3a31939f476762e990cc0945306d1f4fe4f19d538336d7df7cffe3be78d3e956eb785e830f82f88a425e59ea1e730f085f93c32aa2dabdebf8ac38ebd979397dc9372ffc77f7d95ae377ce8c3e0441213e95120bb2737d619c64bcbfaf266def53c9ee33d23c1663e38b209d14839b62be8f6ea3d10b362072b374479f08bcf716c131d9dfb7f2aa2e15fcfe165b7861cad18db3295e61e704c1347c0ae551f70d9e857585f62a16b5051b816dbba178c963cdcbf9c4b676fe2e5810657ccdccdcc075b22649259dce5faa69c783019a11048b8e3871d34be6008cfa2b6ff1cadc8850ba6be6ce99ae99c76da13acdd6561e8828aedcb81e73032dbf3c4c072c67efa2baf0d0e70d1bb657cf6f441e93f721a9a72a2d2aee51d3c8658f1e5fef9c94b8a587282aae7a0931e02de4872f0ab7e6111c98b4f252f4a59c9509091e1267c8baac861ba66a087320107dd08a10b49dd9c7cd742ab62bec59dc4da63db3681808ea1070965e5604b81d00c4cd3443a16313346564e1df2ead4410f641289fcb6082bbf55e0b72dc9ce72c74f6057994cd3c4b22c3232aa6a436d47b2ab244253db46dbc3ee3cebe3671877d369ccfe7509bd069fca95939fe29cde89ccf4d5cde92fae7e9a1e777c08409b331f66eb957fa2d85a45beab4aaeeebec51b8be9d42c0fe95430e3fe33187cd8440addf9bca73a6ba29aee55ebcb2974b92d44c7216312eb8b1b8063f3e05bf9ea91b6acffd7cd0c18760f5b97dde3c3f8360fb9956f9fe8c8aa993770f8b0bbd8b6ec7e1f722b0d9d8faff9079daf795345f6d1841fae58416edd40208e407394da500805bd7de0d367197dc1851c764f800e47fe19c13b8433f210aedf9cd0830485c0c1533e791065f8e1bbef9533b19e1acef8ee216731f0c585ee5a7925fd8fb99b932aad95355175ebfade4080a0f2b7bf839d4b942fd1a20d3b93befd590c1d7007db7eba13809fd6efa0a35b36f3c173187cd8ed142eb91be998006c3a7a12f39fe9c8cae97fa5cfc0eb295eff98bf7e24da21f9ee958be8386c17bf7e72c51efba4a6b158d3fbfd8f52e98080007dd77e363b1b6d438f04d0e3ba1f0141d83a459f9752dc60071fead3797ecd732c58b604cb745c275a17ea225cbcbb9e083166c54354443388c63359bb56b07a15ac59e5b07ab5c3ead5362bd748cadefa07e5dffe4cf9773f53fedd32cabf5bc9eeef56115bb98dd88a6d44566d45a0a1099d0143077148937c00024608c308298747e0be691b987841276ca0d3f913d930ed3e344d6538bd7fda066ebba0331241e70b26f2cbb4077cce5e133ab3ee3c8f7ebd7b7370f34edcf1fe2666dc399a4187f5a175d376dc3623c9414b13fcf386d3e9d7a7132dbb0ce3e36d11f5eeee26fecfebcfa25fef2eb4ec7c2c1f6f530cb11082cfee3c87d60775a047f7ce0c3cfbd3b4defe004f3c3d8a3b4e7b38a52c1d16309d697051b949db462e03a965d0a56b9de427546b3af6687f5b00f605ad295a8d9d6bd36065337e397c3975d636a0eeda024a1bedc20a98e8a6a0a8e576f27ead4fc1e266acefbf8c82154dd033755615aeda276d58f98feb397cc2623e5af40e1d32d3711782fee73dc6aee58ffa67eefeba8ccf6f3a9a56ad5ad1aa552b005ab56ac557c54ae39ad9f278def972210be7cfe399ab7532ea9fa4c241e23065e92e268d3c182104878cb88b5dcba792ec146bc73672f9973b9972c121c9f07a9f7c93bc03a73d3898cb465ec69029a7f952aa659a0a2a0184a315442bca894594703977f60cbefbee6b5e1b7f289327bc8d2e54a8494b4adefc781adfcc99c1bccf67b27ad15718ae03312899ddd0e09cb36fe5c47b9f67fe17b3f8eaa397904e9c80ae21a4c3e0c917f2aff1cfb071e60418348956210d818d86857023d400d4d151efeb3ef7dd79f399bf70213f2e58c8a6cd09184e329d3cfc524e7e64164b16ffc48fdfff0be9c4fcb2639e98c087e31ee597f7c6c090a7681d560ccb3905993cbdb1eabc49a64cdfd14147ca544859e5f0a2debfbd283cea744d8c5c223955ba4b6d09a60dd1788c482442241a231a89211d0dd3b4b04c07c711200208cd4077a3a519ba81ae1b1846c0151035742d444e6e1d1a346c4241a3a6346adc94e6071d4cddbaf5706c7e174ec042d752a2fd54a6783cceee1a9e1189c6314db3da726fd36ed0f75cfef1c9f71cd9ec285ebbe5702e1c3a2a5d6b52e6b4631672e9079b5871fb31b46ad58a433a9d44c059cfe573b7d4781f40a76679aa44cb64e48497295af670adeaac697ceee9dedc834ee4dd2f7f62d1fcef78ee6a8d8cfa270310ca1b801082db467540d3349a1e3981b2cdafabb2dc7e0821b879f8a180c621c7ddee962520b3d2dcc295738b78e05ce53391ec572784c0b213996c77ad7a94ac8667b9f0219dbc434e64da97dfb1e8fbaf78fe9a3019f54f4233423852e7b0dc205f97c44037b0220b08e6f64f1104130ee2a9fd3065e92eee3dfe10000e1e7eb7bb56d68ef6bcaeef2d79dffe313fa847eab77f89a2658ff87b7d87a6b92eaf1166f8f8e7295a3655e568ca3a0c2104134f50a6a9b623efa56cd30b40d5002520e87dd6c36c997d937fa6a63ea96e2cfe8ff68e0e0801c00ad884766760072de25931a450581e333346b0994ea824835f5edbcac206dff3c18e596cdab215c7f6a202193ed39fc0ba43614980cd5b33d9bc39874d5b72d9b039870d5beab069531ebf6ec9c3aac824b3fd496434ee4da8a02fa1823e040b7a136ad88b40414f8c82ae6875db12ccc824989149209481e1e14f3dac9caefc03e696c6e997134600c1dcfec44b144c42d7e0ebd238fd72d47d5e99e74f00f06edb6b99fbfd0f7c3fe772ee3ca517333adcc89cb9dfb3f0cbabb8efbc0bdde7a93feff4b88b79df2de1935b1b70f6f027521c9bdee97927f3be5fc427b735e0ece39ec40b3d78da5d6ff1f1d2c52c58b8840f1f3acc6d7ed5cdbef5882739b6e4296ef961474a46e1640b40e50840debf5fbc7410839ab765f8e917f2e0f333287712d779a6e353ea6770d5ed3d78fcdaafab3cfb8f1005a882dde89641ac6e05a11d596417e6b1bdd3af989916b99beaa2993a4213ece8f82b19bbb2c95b5f9fe236458477675246f19e1fb0075af5f60df4bb7c1eef2f7a9f3ef9099cb4636e67c9f6844566e5fb3793d3f43cfff7ae5dbb58bb762debd6ad63fdfaf500ac5fbf9e01f961745dc72c541875294d9ebfe41e06dc7aad7feff175c33cf4ed0ec061fbb70f10ae3bd2bd56f9a16c98390ed9ee2efae605f1506d52c2a1ed0ff582f1b8d74b1a0f7a84dbc6decaa3831ab92172211629a7a25c31161aae40ea661e96aef3fa31e39fa6f3b2a93cb27c17b66d737d97ba5cf1fc021c4bc5085f3d7f95bf290358522598fa3566d3b2711696e3b0e0d59bdc76086ce9102e3887d3ad9739e7f2395cfdc0112aac2e0e3d060cc3086818ee94b0cd18f1a812b66fed59c0d8a7e7f97db3fabb6555c20f026c8cd9b46eae36b71f9fbb28a52ca7f9659c6d3dc559633e66c2a343fcf3d73e7e0693468e6779892bec4a938f9ebab26ae569e89a0e7598307d2d524ad6ceb846f5a548682c3daad11958388005d8aef6555d9b1409145d875028443823838c8c10a18c3042d730022195c344e858b6c4b21c3f38822395f0a7923d2a5f829819571159d0dcf8ff41302dd03402e14c8281fdef0320f4d4b0af1e4929312b2aa8fbda6bb4f8fbdf891717a7ef57a98404a43210a50c1391b07a7db26ca73a85a0558f7ed871c534d734a737cfb994f23677b3e597f5ac5faf8e25b34ee5c3cbdfd8e35ab0bc3051b66cda8d643739738f7542cde3734ff746b76e77ef89f3ecd8bb1870ab726e3732bb72e541793cfd6329a051b8e019b20a4e24103030323a7259eb5c9efcb61081c1ce058f93d5e024a49360c0377e782dce2137d02b3b88d035572b6fb8ddaf1485baaeb3e3e7cf38f7b847b8f0d96b7cdfa7c896ed2005d28ef3ecb8c90cb8e55a6c47f9718c1fd19c892f2e41028b5fbc93e623ae50cf743fa265c7b1dcf52b396adef175c33c386f3b524ab6cdbb9f70dd74c25c55aa6e5ddf5b4affedcff57f277ffbe5efdd4c769333fcb62fdf11f1fbf5e769b790ddf83425006474e48a36793cfaf5161cc761dbb70f9255f0a76a7d08367c763719f51311ad12fb07eefe91e893eac6e2ff68efe8808000fd7cc35a1a9f5f974030c096e777d2e2fc466c7cfd57eaf5cb67cd0b1b687d83c9d6afb66396c4a9e863d15a1cc2d9cd6b1e10573ddb8692482ed93921027a8088a5939b25b06c28b7203308d6ec15e8d270c1c68a21b1a58a0a2ea444136e9e81a488253e89f406f49a24ae743ab6297f5298f8dcd61760c7c7f1e04987f8bf934df900534e744df9273c44d1399d81abf0368b44d983149dddd52d838b7a37e4b4b32fe392334ee1cc5386d6d0388349af8fa1e3993773cbf2a76a788ba45bdc3e19fed027fc7af1777cf8f91ca63f3d86c7debd9d75332e066a673afe2364026e96db8205b646b02444667626c5cd0a115250b0a231c5cd8bb08545c192a66ce9fe0bc52d76108885085504a9a823699051bbecc04f1fde813b7e519ac566cd9a91dbf2567e9eab98c8ae674cc668d19e7143128e545fce5f408655c865c3875264ea08278a56d083b7bf7e26a5de9a70a7eba75dc6098f2e2724a3b41b7e03ef8f6b8fc0c1766c1e79ff01fe74fe11bc2e8244edba4c79ef351cdb7423e2489ebee64b8e7deea99489624796b0a1f0509568cf3da7eb02f402264c188f635b442b760360c62b305c46d5311d95e8cfbd49382a97802083471e1f41bfd14f72e5dc5bb9e8cd17f879ccf5747fd926038be6bd2fe31f3d0fc18b99ef48819482d7ef3c83b3061d4b9d26f9b43b663cf0098e84706616d1f22857ddd38d5ed7b5e2f2b60d29dfb5036bf70a36ee6c83639a29ce72713346acb88831b3a6b1f8cc71b47fda222c4d5a1c7e0b33fb74f085198fde9b3286933a75a06eb37ab41b712bf05e4af9d50ff4a2db55edb8b479222248cb139fe1bd1d3732ba7f67ca8d0cb02d3a0c398f61ec992efde065460d1d4a977b9a70e8d1d702afe1ad525af24720d552901c2659dab6af1d450817bce8795b2522d60742aa8f9595405da5a2abb9c91c7552a3db27b939090df4a007ffb05d6951b8a61b77fd352d76959510cea8d91fe23f4d8ee3100e6889d09e2e49c721f0c927b47bfb6d74d3e4a7faf5899f7516462895710b063495693b89fc5e498257bd7afd29dcb2d361e5d62574ef7e1e63a7aab1e2983bb86cf890b473fa952b3e61c003f7a7d4dd78c054f495adf8bae8286e1e91fe3e808b8ee945b16d20ec08d4efc61b5f3eb7c73ae7955d46bf1ac6e79eeecd9f7619a31e5d4e58466937fc26668e4bacc377cd7983334e184ebfa88ea937e4d97f3d831108108f45b9e393e738e7d413e86585b0f4263cf7f1df95ff915079249ebdf15b8e7eec3ee567e206e8f0c674f7eedd95c5495a841bb5e7bcbf7dc798639aa2d28b4ad6bd7725273db6823031da1d773d33c6b603d43a39e86feff3c68893e9fa12c83a3d99f6cee1482d21b4f53fec704039220b2dc48ff39552e0b1590f73ca7987f30f2383885d8f473e7cdb7fcf7f675dcfd1f70cbd4aa67463e61f7313fbfcc5c3fab8df3e0af5bbf2c697cffaebdc25c30f4b1a175d7975cedffcfeb8fdb35738fbe4a3e96e0631f526bcf0f9eb29cff5b0fad28923f3daf3f217cffb658f7f309593cf3d8cb7dc3e79f4a37ffa65d58dc5caf502082dc4821fbff5cf7bf0a0eafefdff890e0801c08e5a584ba1c1d07ccafa54b0fae90de4b6c9a5cea06cc473828607376053f7ed74b9f850f4a61aab96adf0ef15b8610225f8f003a171daf48bc89711c23a04344950177e940b4348e2329375a21f481f39ef9ac45d85970d4edc44a023452a9e4fbaff9342856b3b3c37c8bcb21847e5858895cd239837c04fd173786e90ef2a9525538e67ba1741ffb7901244a08a293f250850225b57d2df44321feffcbd5ffdc269736631ed8dc91c34f903b6cf4f72224adae8a59434e8753b63f35a73c9879b521edb30a8f34bcca685bb41dbb15fd0830d53aea9d7b63767b7edcd99a34f2594db1db8d837ffc6e71f43ab3bd47501e7572e9fbb859707259c5ef7a70f00ec1b27e0ee05bdf872f547447376132a0963d53711710d11d189665580a6a2410953e0e84aeda7ef0c932573e951af57ad9e71d1dc9fb9a89ab20aab1a4072664766ffb0b8d6ef51596379e8d8b75831d64fa98337c7744da3a0c7683e9d7f16f168cc755c14c4a3e5184610cd30b8774d216a3cba95390e853fdf47ff7beff571e852dad8b609d2c6b62de5346ac529d9be1ee9e2ee776d5e83945e3221d8b56915b62d1142a20983a643ee65e310d02488ac4379f4d577d5bb548ac651ba5d85989340e7d177b278b43a6fd90ecf5dbb01cbb2302b2c323233f8ecc5751cfdf0e35494a971b16bf5b3f4bde52a6cdb46d3342ab6ad00a1e2864b5d2794d58d673e9caf7ac7f120474e953eed76c913acbb24d1a6d726a6f6f7572fac61e823cf5399068cb9877963ee49c93d52dd374bfe9dd9f8583e599a04479a9c2a90a8cfe260dbb68f5d4fcee02a34892e849bcdd78d7666e8e8ba81a6e9083404d24bf956b9e62a718592dd9ad2b330ca3c201d07699948c746d755baf648ccaef2ae7b4bfb42e07780bc4c8d58a993e25365c5e3e4ad5e4d5679394849e6b265c422114812008480ecac20862e7c6dbf901ab28ac6d4e185f766032a0fc0ccb533fd12a386397dfdcf3bab9cd3020dd9ea5aaa6a5a0bbef871c9bf552724c6e75edf3bf62d568e4ddf9ecc82614cff6e191565bbd074896945908e5a37321a0e66c6bcc5082da806922d71641c890a7e71d7d2d52e5458ad1b5e060bd38c29289a1b240370838a386e000e87f617bfcaf28b71050a701ce5988d100432dbf2dc678b90d2c6d0c08e47716c132124f14831960342d70904c3e822c17e35e835862f968e49fb9effd6ba4ef556bb74e7d38d192f7008c09cf98baadce3212bbef8715135cfd2c86e7a2cd3e62554119511033551fd9e17f2c5d20bd396553716f7546f32935fddbfd3d182050b00e8d4a913002b56281eb34d9b36006cdca8e0d88d1ad54e59f77ba103420038686c0bb273b289e547205352b13e46933e19a083d4254624402012c20ad818b64105e5aef62f599b94caa1ef6c7f1a315d92616804bc34f2c2634614179de3dfa76cb18e54d9714d4b62583691f2a8d278555a9bfdf12740229930b205135f58c25157f664f1f3b7d162d444ffda9acafca627f9d9891ae6cc8419ebf8fbc907b176fad5d4e970cd1ecba41365f176876e8346d1a9f721dc5d7730523e98f41e55937a5dfde60db43e625c4af98dddea73f94b3ff2de983e00fcf8d215d4ef76a37fcfeb9f2ce1cca33b23805d2b3f2298a3aef3ccbf854b27f8d76efafc0cba5dfe062cbaca3ff747c804dca35f77cefef0625ee838859cf26ceaaccf607dc7e5389a8d1ed73183267a4c2366c5c8df558fec2d75296eb89573565f468f21dd7ff3f3ff9364db5239b521b02d5b69ef3581b42da291720ca1614b89633bd88ec0b22cf46080801142d7751c5365e1168641a3de2ff2696f001bcb5619b11dcbc6b462d8f118d2b1541658e9201c37ba97ad62af7ba8156fe3363425887849c41c37a18590f8eb8304a56dd5125a7b15ca3721f8dab67276979aceeec2d90c1c3c91f2bcc12c3aa115919d3b086850b7c33d4cef2095a9df71705c4c93b46dc299c144f85c70a373ed1dfa3256fc297d8e184b799de1fc7442cbdff0b5aaa394700329256ad356e18da59b455dc1706ca40371cb0412b904028100c160984020e0477ddae3db4a4849ba08ae93b4830a30e6b8904607a4c4364da2d128663c464057d00c5b0af4e06fcf03f05b057e2104f9993a15318bddd1847cab1906b17af588190601cb229e9f8f4ccae7a2094176a64e9ddc70150761e12a94a0666f8cff57e4f2e5191959c4cd08d211c4e3710281009685ef940ba8fc3f0450d6261b69dbbed3af251d342f719b57b50b1916491bae177d2f11fe5a221d8983c071a15ad255be0917e6a8690aa2e5b8797c849b30ccb2e2e8014f29f7fba4ea9408d525184d2ef3828c54f62f3a90b307f7eddb97f2f2f294df3b76ec48f9fdcb2fe97dbb7eaf7440080015cba2881e606d3129fb3ac2a177b464e3f3dbc86a9a098ec0cc8a937b6836db3e2fa4a0537d1a061b031a9a744194d2c3e069bed93932f7238419c3d2350268e842779d7e34a41f531f40ba1bb68aa16f4b1b138798ed10b1250885654c36d3b568d18cdc96b7b0c435d30d7a723a078d38852e2f0864dd9ebc3f6b009ecee1c8a7dee3d5e1a7ba65bd787fd6c09477173295e94f2f00a8ba46cdbb967ef7ac6053a4212f7ff23792b78a51f3aea3df3dcbd91469e496290160c20947b23d0ef1dd512e7e70ba5f57759477d0454cea3a85bfce490800177ff80e0bceb88476534d42c408363b9c691f5ce46b71e73e790513afd841664810910d983a43451ad9a3e93847593df6b705605f505e833c860c1b42f6d7797c54f75dec5f1db4888e458cba4b1a12cf32912141d365ad69baba0da1960667169e4fffa3fa91536fff421af686344d433836d826b61903db52e16b5d30b39a8e0e662c8e198da839e7a8644fa150082da8366dd334b11d13474acc781cc78c2b4d9a54667821a4b284b9d62c89ededbe78f92f94e3a8e326ff52e465b0d6bce45e9ac0b65c4dab6b97f39e81a3367bddd088c562e8ba4e66dd81ccfee413ea356a48f18e42b5993b160281e1c61897aeb06349018e4976200042ad3d522a466f6f29943f849f16efd9197cef3758d7915f24395d507583d7348d603048301844ca30b66d63d9711cc7c134753c014208a9f0d47e3b12b62181adfe4a2d55a1e15b2db51421c0ffb7506d148e07fd4960a76da9a05fba1e202314c60886f82d7ec0fb42e0972e74aa69dd3085bb2d4a2b6ce29644370c2afaf665ddbc79044a4a2819308050a60a8e60e8823ad92172b294f0648433d33ac42728c138ce5c37b372e1ff0fd2c1b61d74c3c0315546da9829c9cd0963daaee2472d05eebeaf206342ea3818e8bac0746ca425919a83a105d0740d07c7f721c40dc12a84068e37ee54d5a663a99c397a523a4da92c54baa663db96efbc6e4b4b591c7577df742c085479a3df2d25fc281383d20b23ee957b947c5d4de535414b7f6fd4bd7bf7143ea25dbb76ecdc99b05e356fdedcb7021c487440080041278ca1198880a4f9b0c6043a0a9a5dd1007dbb4eebb14d016831aa09253fec26b72c9f2eedbaa1791b8b3b5ebdd4008e508331e78a4bc8cdce211008ba9ac8a00aff95e4289c200721a40b4788635a314c338ebdabc8bfc233d3559e24024120b31d2f7cbe8474ccb591d196173ef7cc6b6ea230afe9b6e3b75f48f777125596c44fbdef1f9ceaff52614d91205df5c4a9a49266e4f3af6f17a66d9794261e3315a928516d70178131b39671918be10508d5e9c7f31f7eefc33092c3814a2979fc9dcfd3b6bb36a6638006097c0000200049444154f863440102a8535087238f1948bb0d07b3ce5ecb92f245ac0daea4a2a402cb32c937ebd0a6e210dab6ef40dbfa6d69d2a609c1f0efc389b926d234812d9512dd4bb013a988e058510c5d73213cde06acb4b8b6edb8903a87a06e60c66258f10aa42670a4446a82402040381c24b2bb0221c0d0a462251d09b6e2f2046068ae85c151f35441d19516ce7112b0243fb4a5501ca770b579c2ad570889e65902702f05745d231eb7d004848c80aacd32b1cd388661e0f80e3fcaf9532a6e034337d00221bc788e897c2289cdf0f7ad0f53ad334ddbd5ee27b47d86a1f2ad48290987c324ad5a787debb345d213fe921285b9fde591db65a4aebd1e04434bb208a83a0d4d27283484a193911156428a6e001aa615637f922674a466a0e1d03037487e1694456c76472db47687b0f3da6b211623e3a036646786c80c196467865406783d4056663e56c4c60887508926bdd7f6bc2bfe7396803d658fff3d918383d001011999592033d95d510eb88939bd712714084d8d470d616410d403c4a331345dc7110eb60d8e6b3d50cee57a22d8859348d529849eb0f80b4d790548cf7325916b074760e80115a9ccd1d044d867fe6d47feeefb56512a1f24fc71a848f9a92470c74288946b6a82e21c18efffc7a703420068d1b319b666b13baf8450db3011ab9cac96196487b230f235c23b3309599914f468c891d631f46ad7c7d53e7b35487fd7f116d26de3c6b1ada808e148852795124d284646a2f8142f92832e524d581265362c0f8518b0bdd0871e485c4d8d508b82ee776f6506db713745af815aca75a25ab3a0a711f37ea74ea22ad34da6f9778df3aeaa20a0691a8e483d9f920d380d4c28f9bacaa9c393b3c0d696f6a705605f39017b14ce0cd1fad0d6b43eb4358351915c0e64f3a83b9dd09cc409db54587d69db1801cd872e48e9b8080e892e741c0d02ba866dc65d8d9081109a3b1f411802a105711c1b43170a17ed80e328473ee10a155207dbb14830f70a82a4347696eb74ec78ad55f523537c0f54126c472900a4400a108e04171618d0356ccb241008909d974be1f66d64676651118da0eb068e039623d1bd6f691804432182a1f4f913d41a6057810ffe3b9488dbbf7765b5254f539788fea5e03eba674549bb5eb990226983d0fd7192d094baf788c467485e45845f6f929f44f21ae25a2474c340330c1ce960da8e7218dfcf24a5ebe4e9082436011deae51934a813c61160b7ae83e33818b6824cd9123423886d816604d08c104253c20ce077da6ff36ea81d558672fcbec91b8f9aabb813201311f46ce9a0490da10984f4ac50de666da01bea1d3521b1b12b415912d1acaa2329002761b5f2adf3d2cb9aad1005b8f67ecd95ff75441a9f8e038f0ec4fdeadfa5fff900ec476a557c10a5b11282bbc3d8e1384634801370089585c928cea2ceb6fad409d6a177417ffa753a8cfcbc3c1c6c844c30fc95bdca46ae5c8e178e1094964f4a89655948db54c66ae94612112a05b861045d66c2d5d4bb133e859777a9dac9219335653598c0aa5b7baaadd6de071b84b7e17a7f55842321128c84947b9f642739cca2974e7d6f687f5b00f68513f01f9d845031e31d3b8eedc63017a8ccd94aa9eeb8900d258c7b5a7275958dd004ba2ed0033a420a4ccbc2712cb02d044a20b06d018e72f8c4769d4101c7b1dcf92741384a0b6f4bd7eae731fe0946527a73cfb30e48e9e2ccbdc834bacbac0a34e9201ca5d5d574a14084b68963990869a3a9d6218586d01c3f0bb0e60abe967408489980bcb8f024474ab47dc09cff3728c154eb958455d58f5e96d3caf044e17ee3b40a8d4a0a89caab8a96f42fe9382ad082072572004d6538d70c9db86dab7e7714d3f75b685f08fc524a345d2579736cdb8ffbae695e32478990b87b54427baa69aee0a0eba0a5ae91ff0976bc26e1f040189795a9b2f5c2b22c028180ffbb72b961a810e1c950160fc2571bc1d983ce25c67d6a5e1ca5c8b0abd42534aa320c072025c37bfe9df162dba942d7ef7dccfdcf07603fd1e80e17f2cbe60dacd9ba9a2da55b88442a404066289b82ecfa1cdca42d6d9ab6a269936684422114eec575e64b716ef398764f232910426961a4702352e8ba0b9d71d05ca1403a4269b1b484a65ec5aa4ec6b5b90caef04c62c994b401a668ef6b100084ffbfc46fa9d7a8c1af52546b885de50b13ce4942d3d17413dbb6b193128ba598f8f1fac25b645327b5129e0c76efde4d3c1e272f2f6faf84803f4226e07454515141d18e220a1a352410dc9f53319969fa37709952aa582f8e493c5a81b44d0c4d20d1b1e21518ba3b1e844407d7ca66234d87b8e3100e86dcf115c38e999896858d24606427c689eda808f3b685e63868c2f18508474ad0340c21b0a4820749c0110a676adba6cf7827ded14bc623d0dd90b39a04c78d01eee5c9104260db0e961d2723230b5d179496eca24e5e0ebb7695909593434534a2203286c0d00c3f6a8e138b61399240280ba486d02c7474d7174022ddeca2ff5972809ae69a06d80a5e93f2ed1373db8bcb2f8437cf95454539043bbea36f2a096585498ef2945aaca8926226b9d55e6ba448b21c826f5142782b904650d7fcd7fcadc9c07eabc0afa0deca2fc56fb704d3965454c409bb73ddd074745d69a78590ee7b394ac80570214dff2ef35f1b2dfe016d7dac04354dfe0be91355a683387916ae8492abb60280edaf136a3d4982bf0a07c7b1d27e03cf8275a0534dfd53dbb1e7f5b32778255ba07e4f63f27f3e00fb910e6e7d3007b73e98210c4e395f53a83b0faa5313439322b94a151e53b81b97e63838b6e30b0c951705151de0b7e8656ab100541effff95f950390190b7c0a9cd49e53c706a35392b4f622f4a48bab29a687f5b00fe53148fc499bee21dac5d26bd570da06597963469f7df36213a54a77f4d37ba1d0705ebc075f8151227b61bc78a6359ca295420b1a5ad34ecba9624487b734812d03484612806ddd588dab6836118844221a2a68519b7712c49400bb84cbc44689a8212211086721616e820050e4a8bea31d5d2d5ec078ca012306cafdda91bbdae07b0a5a3fc0534e1c6bf172a71906de33820358d986993935f9758712952c4d1032115f3dd1038d252a1811d4b09bd008e099646d9aeed64e5e4a305c380c0b21d1c34a466604b30447553db0b4e5899127354e0ae83be6a3c4112141cd1871656aede834bed41184f0b414960d33de34baaa36ac24748563903c9634ea0570b22721b982227786cbff73ba4ef3b666a5f08fc9a3094d514251c79bc9e69d9ec2c8e623b100c08ea6507c9cd0a2aff13257da6619cd2458c3af099c7ff04ed2d6cc9711c7f3faaacc5aecddea4e45017f7af25418e5d2598ed4215bd19e078282521d0ff00028047e9f8b0da5a500e2cc8d91f8f0ee851980e83be3718f3ca58768f3c988ac7b07ac7ef4922fd6f50e53959b96ff7d4cf7e1c65f71ac33052ccaeb5a53f4226e074949d9d4d4146235ecb7a9a6b1a8fe5c78d3f2887edfd42e99933504cbfe3baade81ae8bad25c226da4a59c776d2b82744c901612536d889ad2c057ab8973a43b0e14765b8d0d052bd111fe1cf4ee5711375ce6de1d76fefc24a169f5c81b9f09c63f8165f762d9ab283e2e14d065846ddbc6b22c7f8c4a2d31c6edf272f2f3f3fd6b8410caf919159a54738519a4c7bcdb6059c42315d8b108b6a5ac11866ef85a75af6fd551bd4f8d4cfa2fe5ab553b649ca4bf69e69bd780a4caa4c48bb4e91fb52251150294dc0284824149e12093a2fbe04658abc96e9a2e5862927dc26db077d4b2bdff41d28c00b65456634df372226804748d60400992651516bba3163636b6707c2b87d4dc8eacc5ce9cbcffa53b92d7eb7407fcfbf08ddf1ba5e305d2edd9a938ffaa736daf7cd45c4598d0124caf7728d86bfabc149ec6fb8f4295c75dbaf53e1d257f9fcadfeff73626172c58c0a245895c082b56ac60f5ead5feef8d1b37b279f3e6fdd1b4df4407d4288cee2ca264c50acc5dc560579d5c7b3b68d22d9a1e79f1acbd43d7f51a178e3f22259bfdd32da6d52db095ffedf595a66918aed6776fbed5fece04ece182f72599a6c9e6e55b58b7690d5939b9186d6d7e2cfd815f176dd9e7cfaa1d5586a42518465d538787e50707db8a13ab2867f7ee522c5b41c47c465d9214324f62498585f7e78c54da755b2a463c1e8ffbf7da3e665aa0bb63c487d454da589205f3648d7eba0d29f9fae4f9ab691a8e65fbfe0052da29cf033084e6461573282d2b26909deddeefc6f67643fd7961843d4a7e4e341a65f7eedd58f1389a9068494cafd7adc9217f9393f048c7f10315f8e7d272ba095659a6fc56878374a39654fad649c64c81c22827e63ebe245059f848a1e4fb930ee50229fd77f30f9c4a218e3d41c03b92ef4f3e1cd7a53259a849fa2dd2083aff65d235230127c11b0782f2a843452cf15d4b2b2cca2a2c57c8aafc4eff79faad108edf3b79ca26a8fa3e35319ab51500d4da03de0492d27193159ad8a69996aff09ff93b6370f70555c74b5547350900bf47eadbb7ef5efd3e10e8801200ccddbb59fbea6bac79f041364d7b8fc8ead52e26e1dfa7ca526b656bc2ff57edbf479e0090eea8be5f52e152c9cc96e794b5371a90fd6d01d8d713bb7467190b662ee2850d7fe3d37ed391ba433892cd9c2e33985a7a378b662d415624aedf93a6cfa3bbce1e41bb6675d27e93ab4e3f86f68776a46bb7ce74ec7b3cfff8b9d82dd198306c009dbbf4a47bf76eb4ef7a140f7f980ecbe870fff09608a1634523989108663cc6ce256f3162c091f43f6a3883ceb8955f4dc79f4f6b673dc9e0c38ea6ffe013e87ef8e93cf4d1afea7dec72fa0f3991fe83dd63c000f29b1de36bd5a563f9e3c3364db67ef336e79e7c32870d19c58041a3e83f7c0cb7bf303fa575c9f3d863debd399d3c4e3d9f947aad7a72d0d09753c6e813430792dfb4ab7f9d773e59b8b02c0b4cd3872a99a6ca55a0ae556dc969d211cf0f46c7c5b7daaee3b2ebc4ec3826b615c3b64c3481eb1808686e8e834a82746a6c7dfce7c93418fa745ba8c7b8279be8130f70528f6a185141aadf4fca034532339e7c4f32558622d59408291d6c29dd5aef992bdcbf4ed54cc67b43fb42e0d70c1d078174c34a97476d361596b37967057133f10e71cb61f3ce28db77c588c66d3fa4a444ee9585f4f836c75739b7f6bd49f46fdf8eaeddbad2b67d7f264f5fe7974d18d68fce5dbad1bd7b17da771d9432dfef74d790ead6e778e99704358dfe0f2fad759910826eddbaf9479f01a3d3d6add697aa0aa5e47bcf7b3bf11ed71c7b185dbba975ab63f7213ce2ad2f529299994daf5ebde8d1a307ddba75a3ef11559f2984e0fee1ad5dc13d95be79e1360eefd291aedd7ad1a55317ceb8e23ebfecee7346d1be4503742d94a27c701c8778f96a2e1ad6871ebdfbd2f3b8cb58174d8cc7eb470ea667efc3e9d9ab37edbb0eaeb2ce7ef3fc2df4efd88ece5dbad1a97d074ebb6c925f56d3f7aca9efede81a2e1cd299ce5d3bd379c885ac4d6a8f631632f1bc6368d9b6035d3b1fca194f2dafd5f3bcf1d3a347573a743b92873fdca8dedf2aa5478f1ef4ecd9939e3d7bd2a5437d825987f8f75d7dc6303ab4ef44b7ee5de8d46f246f2f2bf1bf772010a067cf9ef4e8d183eeddbb73fef40d40cd7b5a4de3785fd3ff7c007e0714ae5b07ddd0d9f1d22b147e300b7bec389ab56881e6a652df1b5cf9c2853f919b9b474e4e8ec2c0ee85a95b3a36656565949696d2a347b77ff36d0e1c4a982c13b1953dc60aa8b6ef2a0b00c99a9564fce59ee88f900918c08c5bac59b88619cbdfe3ab3e1fb0b9c52fd4d9d6908cdd99480999911ce6f49dc5c2753f30e4ed918c3ae8640eedd30ecda85d3f1d39fa3ace7aa8270735caae52d67bf424ee3bb6078680cd5fdcc9c183cee34f3bde03e0fa3767f340be12944a57bd4dfdae477365c572bc6475b665b1f0f153f87bb37b81b38945cbc1b108088d9b4fbd9ea35efb9209ddf2d932e77e865ffb2d0ba6288169e4450f73cfdc1f18d13444f9864f6839e87cae5aff3142cfe2eb4fde75991d871fee3a99315bae45da5e922f81c0c136e36c5ef41403c77dcd0befbc46ff6601340d225b96f2f4933f22652fd7e7405411889219770f72960c8b001855fa1cf34bcfa25b9641bc7c050f140d01fe99e2a7e248071d1dc7b1d06c8da06e5052bc93602888a6699496c6b07de7f7248757a1fbcff2c6ba824ee9085be541b01c1b21749c907b8b10209d2a1a42ef9f5a120a5eca4498e2aaf819d5feb825310c2f73a9c0b124869168a397504d3aa94eb3febc4d72f8f7ee48ae5f26d5a1b4ef905e70a8c65a5139f15715da0be58ea0f66bf81ee8b73a01073332b12c0bcb34d95516a7b0b802db49afddb42cc9aed238a5e526f5f2b3685890abc6a996e4e09a9c8d16e1cfcb75ef4de2ec5b5f63e9e68d74edd28ba36e7a9ba967b406e0e8336fe5c165459cd42a87b2b5ef50b7d350aeab5803c0f56f7e9134dfff41fdae43b8b2622500478dbe8eb3ab594300963f7135ad2e18cfa27b26c295ffa875d9c2850b6becb3858f9dc8cb2da700a7542dabe6deebde98cd0375d4e429fcf90d9af43a86ab2a56128d468144e8c6743c81a6692c7cec245e6ef910706aca351b668c63e48311be9abb880e7582483bc2aca7aef7f7c123475fcb190f74a66dd3fa2ae4b19d88ff3ff78a53583de2397eb8b42b3f3e7a1c275df50d8b9e1e84a6695cffe6a73c5847090d65abde71d7d995ee332f61c40311be9abb980e7582e044f9e06fd7f96d1a7ac62dd57ecf9afa7eceb8e1ac3cfe55168fefc50f530632fcd22f58fedc5100bc79565f9e2bbb9855cbaf25acc1d62d912acf3bb1653625abff4983ae43b9b67c35428834e36728e32b56a205f353bed50fd775e3ac8df7fb7de3ed419a74d8f4c59db473f7202fd0c382050baa286c6adad36a1ac7ffa3dad1016301b063318a972fa77ce54a9c6805cef6adecf8623665cb9621adc406565b539261049052aaec9e19613233336a776484d175150ecf300e28f9e93791b7f8e9ba8eae0530f4a0c264bba137d299586bfa06b158ed93f5ec6f0bc0bea0782cce4f5ffcc48bebffc63f4f7f96a2463b68b6e260b28b73b00d0b2135025690e68bda122fa8e0edd39fe3c9ed53f869ee622c33299a4835585e8001470fa44dc3acb4cf3ff338c5fc0334eaf71762c55ff865f5f3137d14292b21dca057d29d0e252b5fe48447b3f8f4fe610058f1288e65221d93770ba35cd2210f29258d075ccac6f79f02d47819d83893e23285938f941413aed7b56ac31c879b5e59cfc5b77673613f6a49324d936834ca337f799cb3a63fc39043f3d17581a60bb29b74e4aa3bcff61d7bf39b77f39f2984a05eab9e082158f1fcf9f4bff527df1ab07bfb4c1a779be06becc7fdb50d374edb8010825f66dc47db2bcef29b25842056f403e78e3c813e478da4ef09e3f9b2308261189497979359af0d9f3c740d234f3a93ce3d8ee3ce0f36e3380e33cf3f0f80c38f3e91c3879e0868ac7ce516860c3f9101838ea663efe379e9a71d386e34a38acd1f30b4536b3af7eccfa9d7be89a6ab88488e6da5c5fc03c4cb16f097617de9ddab3b9d3a0fe4858545fe7c1342f0c675a7d1af770f4e7d76398610bc79dde91cd6bb27ed3b35a0f3655ffbf5946f7b8dac82d3889b714c2b8a65c7b02c13d38c6359a6fa6dc77164fa68265e38cbe4b192f85b0df32e15e3afe24109a4270878657b435ee422cf84224495f0997b4bfb42e0179a813002ec2ca960fbae0a2cbb664cb4b22c39ec28dacd8ea2526c29aa75cc96490129469c3d91ebdefb86014d06f0d3824f19ddadae7fdd914db3282c520c5dc5ae42321af4f3cbaacef7defeef9ad61090dcfcc012ee9d7417e7181f326543592dcb6aa6e215cf73fcd46cbe7ceca45adf53f93de2156584eaf7502da9058c24f1cc13ab944d1efb2ad7cd9c4afb7cc523481162d8c50ffaebc861430ea765830c201169c82b7b60faafdc726e7b65b9b8e01636cc98aa128be93a0575c368424320889495a6acb393c7bec275331f51cc3f8016e6b84ba6fae5357dcf9afafebe691bb8fd82ce00743e7f22bf4c53960c3bbe8931efae67fcb3e308bbd3ae51e38c2acf935252515c4846838415bca6f1936892c5554fafe0b2fbfaab9f52a6ee417d2f48d9833caa2cacd5341e6bd58e7d447f541f800382832ddfb4996d5f7dc9a677dec5fefe7b34d3c2d103947dfd0d2bcc4934fdd369d41f7004a182fabeba6c4fd68040402310d0b0ac38b6ede1fbf7643df060007102018d641ef6ae7346f2ca9c6f58b9a93805bf0b0a7ef1c14f9b088635ac504b26bef00a7fea90afee3b7b042fcff9dabdafeac2f5f913d770cdd419c44201e2b110275e3585c9171f51ab7efbad54b93d7bd2d87b1ad7e4fb2b3b9c79f8ee783c4e4646467555a5d01f210ad0e6a55b985ef40e9f8d9a4ecece7c0a56376557abedc472a318e5410296a0b87921c18a102de61fc2ced6dbf8fab88fc8fd308f86abaea269c726fbac2d73279d4ed3a31f4a3aa3f1c471037862cd1ad6ec2ce0ada573ddf30e76743d670cbd87c7bff98e5c94a06db81876699b9c5190c11d9fae67f2b056acf9d703c4cabef7c7c0948f1e6570df23b8bf4103b66e0bf1fc576f23358148ca8459bce6117e0a1cc9bf9a6621d05ca15ac38a9b081c9edbb89b6fdb86b16315685269c155c41e5bf92578513c3c98995baf2e046dcfba8da29e1328bee52df20cc1f7f73c4defeba7a2b9d7b639f11a961df53ace5937f2d494d5dcf3690b8eba1170544e8d67ceba9ae0252f3177544b564fbf96e3cef83beb3ebd8880eb14fc4e9b31cc9dd3810d0b9fa6fdf113b961d8b30c7bee6568de9e391f4d4308812d25cd865cc957e73721100c51ba661acd87ddc8d9ab1f05014f9e3096c637ff8b59271ec49a69637907b02cd789da564c60e5c859cf1e3b9c1e8f2de1f96ef5285df73a4d0efb2ba3b7fcdd778c7ebfdbedcc9dace2d8072e8159dd6fe7ebc9edb12b96d1a2f1a9143fbc845c5d32f79adbe97bf73b388e89261d3f0782972d1d40a0633b0e42d808dd8543faa3464b408b92ec13554826396efbd605b708953d54854455b526eeab544faabf72d5eb2bffde4fa41941a2319b9d25e57b05e5711cc98ec262ead4a9477e30e4d5e6970bcf49dced982c5db06d6ba112c48c7cba1f9aa8ebf1796fd1bf6d2b26356ccce62d615efbf9bb9467a5cef76f6ad5bed27593991dfe0bd3eb67d0e9f61e8cb8f66bc6bf316c8f6500ddba252ce539cdaee6cbf7ff0c801d5dc76947ddc913f39792574d12b77ebd7b505e6ed2aacff1dcfdc8ed74c94d307e8f1f77044fae59cb9a9d05bc32ff9314c553f7eeddf7f0ccc5699ff9caf60a36b4c8a9559f24ef778ee3f04d599c7eb919188646a0ee61c44b4e43d3741f3af7c471837862cd5ad6ec6cc05b4b13c2f89e9e59d3f7aca9efe796c6e997a3c65230b73ff192af008816cda4dc76289e78063de66f44d439943b5f7c8ee39a2b66fbb16fdee4b076def342bcb2785e4a7baa1b3f1e0f50b4ec167e0c8ee48b665535f74208be9e7c264d873e98c2a7f5e8d1c3bfe6a5b9dfd3352b5053d7d7d88eff04fd11f300ecffd5b216b470c20436de7107ce679f23cb7723854ad0232311229f7cc6ea9b6e62c1b5d7b073eed738aef9af266f7e85a90d621821a414c4e316b198493c5ef3a1aeb19052601821545a70751c35fa7a3e98ffabfb84546c6befd19358bc6c293f2d5cccc7f7f7e5bc41e7f965478ebe2ee9be54fa65da859cfcc8765efd61318b172d66c90fafb265ca282e99f9dfc19a292c72e2a8ec54e81d9ef3a3127c5c673e91c063277f038f99c9cdcd4d6b35481741607f5a00f69513f0e78b3f654eff19e46daf4ba3652dd9d06f1556d0a2de9a0282b11081f230f5d634c2366cd60ef999fccd0d28d8d89cd95d67f2cdeab97b7e402d69d9ebe319f56c2e1fbefde794f3e33ef88a252b37f3e9fddd183df40efffc94538ea2e9a4e91c5b5fc38a2b893714d0098502040c8dbbdf99ccc6c72ea3ef9093b96b5e5b04baffdd279f7425873d3a83a5dfcce6db270770d9694fa63c5308c1e7b7bc4fe7bf5e8aaeeb84c361c2595984c36182c12019191914590ea168858aa263db5c73f2990c1cf627daf73c1ac0371f57f6e19152a2855af240df08e3e76e43da455cf951058f9fd4d2bf2690d59e09791ff3dacae9bc9bf317ba6707fcba6cdb66eaf212261fdf12c7713868c4f5ec5af502a669fa82ebed831ba2676590d7fa54e2a5a90c56b24f42c5af9ff3a791c3e9daf7288efcf3542a76bc8d906a8e3cb2aa84fb8f6f8da6c14123ef54cf97169665615a314c2be6430c3c4dfced3fece0d9f387d0ad7b37069e3c991c6d4ecab3a79eda2ee5f743a7b4430046667b1e1b58ce259ffe8a636ee5e269653c75464b8463ab6845e0cf614f8921517e19b66da575c4568eae1a2ad8a196ec4f9cda1f023c30900b18420af72f89bfd5dd9f1c8ab4eaf55ad2f13b20a1b1754711b69d9ef9374db3dadc249665b365eb76bc75b52a263ec130cdfaf8193ebee53466fffa39bd069fca2bdf17fad7dd3de42c06beb89035cbd6b0e895a31973ccdd29f5a4cef7db6bf55a5f5cfd343deeb81c8036673eccd61997526cc93d968182f17887c788034c3965104defff17a31aa7cf98bd786331f3beff91454bbe654cfba50c3e6c624af9d8f767b378c5463ebdbf2b6346dceb47f702a5b55db060c15e3fd3a3645fb7e4c8801e94aff275de77f1f2de247f39cf9277c907b359b47c031fdfd78dd143efacb2665577dc3de42c06beb080d53fafe6a79753bfe79efade6f67f20fa994399b8e99cc8f0b7ee2f52b1b72e61109c8d1dd43cf66c073f359b178050b5e1acac5c7de9b32ef6b1a3f42083eb9f255bade705b5a24c0b2d7afe2c4e77399f9d6d929650b172ef4bf596d98ff3db5635fd2ff7c00f62359b3678369e1845cd88e19c7d6751c21a83b7830259f7f86be6e1dabefbf8f66178ea1d1d143d1c3e11aebecdb7709252549da95246ffef4a42c04c963391c8e1089a8d4d0038e1e58edb3ce3c2e21d92af84542fb5ad37df75dfa2657cff99576396a320472daf1c8fb57d1e2c80778f2d7a9d5def77ba1ca0e87c91682641f8264f8423a1f81fd6d01d8179980d714adc6ceb569f07d337e19b09c3a6b1b9059944d71cb1d084727d31414b5dc4e9d0d0564edc8657dff651cf27fec9d779c5e559dffdfe7dcf294e99364423a091052484822d2518a1469ba8a222b828880b2e05a50d11fa8aba0282a2aeb2aba8a0256705da4af22bd2a358184242443486fd39f72cb39bf3fcebd4f9be79999241392817cf27af2cc73cfbde79e7bee29dffebd6f2e7d6fef62d9e6653bfc0c004b6fbd9c232e5bc87d2fddc5ac74f9d48fdfc1a1e75c4fc7857ba1f5b710b475e4dc000020004944415468ae7ebc97a645a732fd4a0a5eaefbcc3d949b1efa2b87d7db8c9a7e127fb8e3446362b3e156eefac3f108a19152f0e357ba5979bc21a0a7bdeb73749e73307019810eb16d1be5afe7734f7670d7ed6f239d96647b33747676927213d4373480d69cde9ae096d51d7c6c2f2399baf6b6df028aa6890782968481c61202694b93ad42e5a2275268ad38e61b1fe6d20ffd91d7bfb4020ebf9c2989e2780c028ff75e7110079fff6d4ef8d6ff94496b851085c463a9741a2f6754f7d21204a1c9745c6f097a376ca475f458e2e841b159a0e5d80861d1d4d2c2a91ffe2ae7dff73ce71c308a20bf91e4e8038c4f412c241031f312452bd2c5f0b9420854449cc7a14e03adb9fd897f32394a28657c181571c6dd518e44eb384279f41b9327ebc4ffba8c0b8ebe9ed7bef9321cfd03c6cb10c771d004915371e4500b45270321515a81af50418065851121e480b00831199eed48021f063e8eed14090e591c3b6012c1c58998b58812c39550279228d1734972258030d428ad11914f4ca0210814b66db407b95c9e5432c18e6038320103f4f6666a96799e47a6b7b7a606b4a7a79730d4c43466d1f1baa859164230e69073b8f56fe770f2d493f9c1954730f75da7737697912a5ff752071b4f350e98fb9e7c351def6d03be597127c161e7fe271d178e05be3de0f3287f33ff76cf1abc674e60ef483ee0a8d55cfad83a7e7db85bb3ece6770eacb9bcfaf11e9a5e3a9ebdff5ff1d8de7befcd6f5f5ccae18d2e074c6c322d95694ebbec66b67e795cd973c4be37879d7b3d9d178e43a96f0e6a0254fd9ed3f8ed8b4b38bcd1e5ecb6343f7bbd87cba63414c65ea5f6bb4cf3a823cf0c2138acd1e5e9be80635b1cf2ddffc06d3a02ad2a04915272e8b9d7d371d138c038fac6f7fcfcde8d55db7cdd4b1d6c28bccfabe8f897b1c037077c2f37bf733c4734ba3cd993e798a604f99e27719b8e0420d174144208befe5e33cef73bf55bf4bc6f0cf09f68adf9c14b1dac39799fe2fdde3f0eb8bac2b2a2faf809f3af73e9235bf8cb6dfbf613162cbdf5728efcfc42ee597847bf3d68fb31f471bc07e518111a00152afcba1432087172791082c0b6b13c0f7ff5eb84e914e3ce3d8770f9abbc7ecbcdf42c1b9c60b2a8c7a2058b31588c45ea71483d1ea927449ff1557e8fc3626c744d0b52d7b295ac8dfee617b571cbc60c974e2d5f109af6be94be0d376df37db71fdb11654994133031aa2dcc4aa948c2589e32bdf4dc5da901182e27e00cbd58814dbe354362531df59b9bd878c06afc7440e39a56a46f21a460d3ecd5a43aea696a1f4de7b4ad247bd3f4d039f80d06c1b2dbbec4a1973ec99d2fdec9c1cd452249f91b59b43157f8bdf4ce2b6998704ee177c7d60dbcf2d2f32c5ef8144b9e376ae0579e7d9883eb246118d2b76e3d0082809bbef8130effecc70bd79ed49ce0fa67b7924ea759fbd44f49341f5370f0cae572bcfe7f5f81fdbfc42cbf8fdeee6e32990c9ee731eff093e8edeea6afb7972f7de314ae3ae71a5ed898456b63671b7a1d40718cbca3d1e1d7ed3d68ad69bfbf38b78410d48ffb201f0c6fe5fc2f3ec5a55f7f7bbf0d69fc115fe4f2b32fe23b878ceed7679fd9bf892fdfb71adff7597ed735b4ccf85859323b00a54372995e005cd7c5b66d5a6d498770482693a035afe743f69ed880d69ae76ebeac706f804feddbc8e5f79888172beffe6ad973cd39f0908216018c69900a7dbefab6362efad95305e7db654f2d8a188888408caeafb422d71a1a265dc287839f72f627fec6a7af3b06a1cb23a0559ba3957338f6bd08a2e46f028125ac82e8c4483f8d2650a9806296540a1fa52050108614449361e4d8ac22e2dfdc2f249fcb10863e9625b02c89529a5099eb1cc710ffa1d63809177f07a3c2c13044fdd2d5f39c68adf133195a7ffb5b26df74135e6775b3cff8dc427e88123f10d38f4623fbb7c546022910ecbde05042af1842f8d4d624df7fca98276c7ceabb245b4f07aacdf72b689850d448d7c2da87fe8dbe6957b3eeb576dadbcd67d1dd6770efa5bf1fb06c3074747414ae696f6f07a0bdbd9dc323339f259b8b6d5dfcbf5fa67efc5985e758b8215b189b4befbc9286f11fee67863af03d57d0debe22bae78ac23dbff0e333b9e6b4cfb2b8336fe684f2b8f7279f29ab230e36553a7784107cee94497ced572612cfc21bff83c9a75f66da146ce2a54dbed1ea20587ed7576898706e618ffcc28f3fc4b74fff2caf749b3c218280ffbbe13385f2535b935cf7f46684106c7afa7b85f73958df7ffeb4c97cf5c645a63dbffc2a934fff3c00767a0e9fdea789eb9fd800c0a67f7c9fbab60f14fd4b5a93fce0e94dd1fdbe4fb2f574238c28193f5a6b5eb9a3fff879fdee8bd1fb5fc5dbeb9db27751ba071dd2921c127d500bdb3b8eb7177b7c007621a67ff75a36fce29704f91ce33f7e3e6b7e7e03933ef2513a1f7b8c299fbc98f6af7f9d31c71c87ddd4c296871e62ddefff40f39c3983d46a01360227fa3b8ec337900620563e87910deab6755f6c7ef1d8928f0c7e32837b24ec5cece0462a94b17d1cc00cab34646365a8c6d26b76b506603830b17132cf8512b72b41ba3e4de7c4cd082d687b651c9d93b6128a80b645135837ff353a276fc2c92748645c322d9a31a9a16507fed911b3f8fa6b8659993871228d53bec2cb8f5d08c0811ffa36f6e4995c7c5cd179ec91679e23e56fe292938f63ab6f21540ed9b680db1ebfc1f4bf2e32684a87c89224652ad296b5dffd0d3ef08b76122ac77ec77d82db3eba4f64e30fdffbdd97f9f0251fe44f56829c6ee1ba3ffd947c3e4f1004343636f2ddfff827effae155e47239f3ce95467aedaceed81bdfcb23a5649f53becaff86bfe0abe79dc53acf22e1d838761dfffe956258be1f7df71cfee58c0ff1cbf16dcc3ce663c06d65e3e7dfbe3c8ba3be3199f3f74a95319986981fc5a5179af958b9015df89bef72c1c73ecd613f9404a929fcfa37671a2393426230855214ec421b9beae9edede5bbff7a28471d7e02a31b12fcf3b1bff3a76b3ec219071d4eeb8456a69f7819702f48630e73c99f7fc47b4f3f8d05df1acbbeefbc0069fd0501047d2ff3fa96fd4c7b9587900954e021b4e6a27b6ee7c50f7d92fd7e1e90c267f2e1ff8f3b0fdebf5ce356f2fc16a5d192359ffbeedb98f7d9e95c3ca90edff7ccf9d1bb1580d65168c3e80a93e748982c02da48e19532a67d5a08501a614963a34e88d4e0d8122924528297e9434b81b41ca46d21848d2daaacb45a47990a8c7954ec559048b885084342183f8f3054282d9042108421f97c9686743d08c18eccf8e162f8d3e914994cb9998f560ae76f7f63ffdb6ec3f27d5e183d1aef5fff153b51aeb548a552486913c68914a3ccd5052d8a3019eb7f73f9fbb9728b62e9fa45cc9f7f2e9ff8e1ed853a7e7ccf0f79df3987f3473b45361cc5f5f7fd09005575beffbc705dad35e4964ffd8d23bf7b6d593bc71df943aca57b73c9793647de50bdecc99e4b80721f0021133cf7ec5343eac70b4f3888ced0468459183d8fdf3ff28bc2737cead433a3e7c823dbe673cbfd3f289bf7a53e00db72cf29effd19b76ffa7f7cec8879f4d9690803661df7114e8cd68e1b8e98cdd7db4d1fed337d168d932ee785bf9f879092637ef23ffcfeb43399f32b896e3d883bef3e1a212c427f0b979c7c7ccd7e9ff2de9f73fba62ff3d1c3e6d067a7a27b9e4bec4551eb7d0ef45e9eecb98477fef40ef639f97dccb95144ed295a1c7ce3a1df71d67b8ee540dfc5b7c6f3ab878a0cdb8feebc8e0f7cf41dfcc94957193fef2a7b8e5b1ffb59d9fd6fb8ec114efae50d65eb9110a2e61ed410492a4a2d0562d41a8f838de379f3e6152212d5fa7b5bf166f40118110c809d4a919c39838df7de4dcf534f33e5924fd1b36c295d0f3e0017ff1b5d8b16d2fdcc332cbdf63b846bd75077c0dc41eb0c7108710107d30ddbc2000480206468766a30b0f9452d9c33b68eeb577673c5be4d8563ddedff49ddd8a13110bb1ab588ff18b119509c64add6b92b56acd82126a096bded1b89f96d07f1c8f2fbc835f492e84a128cf6119e44642d72751963128146f802656910606d4952a71b5930eaa0c16f005cf8d8cb5c58a32c13d460e8d2b379e01f2f9649ce84282edc4aa988d897201599adafa17588d4164a86ec7fde8f78e1a31aada2cccfba18b3a665cefbb9ebc1f761590ef97cbe60e7af94c2f77dae7ce6798410647a4dd40acbb2c8aebe8543afb8cc10e7da10e9f34e3f9fff3ded63688c96a8f44984104c3cfe22fe71fc45853174c3a79f2994013c71eb6a8efeda9565daa5ced7fe5955dbd4d1fe4ca1fd89d605dc7cfb9ff13c2ff21bb222277649d7da170b663b4a6b36b43f874ca5f03b3a78df777ecd29be47db8429647b7b987dfe352cfeb821568510dc74c5c68243676aecc1dcf3cc4224b0fac1aff0c0ff9848449dcb7ecca1577fcdbcbbf57f26d97c6c74ef00a7612eff7d6f44cc685d90149877e88336e14b41e207f13b250a310a8fdeb88277fde8e74829b0a5214c89df71054afba8f029c9f3a105a073a06d727dbd8441802504ae2d49259258b6c04d976ae13410a010262d8252c6b65a809486cdd04a45de02c26813b546e54342ad40da588e8365d94491f3712d899b4e2308a3e862bb567402306a542bd9ecdab2b115781e4dcb9753d7d7075a935ebc987c360b250c80108251ada390129373429aa479b1edbf314435265d37defe2000a74c3d85bb56dc5576ffd16ffb380fbff4712a61a767f3e03f17d66c77ad35e4f297b7f43b269db1accf555f5b4bcbb645b25b79eec3cf2eaa7a9e9d9ecddf9f7eb16cadca648cd995909abcd787639b7e2dee2b664ef4bf67ffdc11475e70354f5e7075c939c5fb7cfce117f9681098b54e87482dc102cb7290f5b3b8f181b87f8bf7b2d3b379e09f0bcddc5191af4045538ebce09b3c7941a5999641adf739f87b99ce8d0f54efc3f4b893f8cb3f4e2a3b166b3446cd3f8f07179edf2f599755d77fbfa8c4b75e351aeba0223a639f1f96d555badf576a5262d41a8f838de35222bfd6dfdb823d3e00bb10ed3fba9e6cc756acde0c3a9b23396d1f363dfa083a5408a508132ea1eb984dce92f899be41ebbc9df7d0401709c0a5a80380dac1278cec1f3c200f6cd20920c76028a8be5ebab7ccfc62307cfe868f30f7d44b39e3e9ff6646a38bdff30a9f3af57b9cf59317865cc7aec6408b7fa923d540d7ecea4cc0b0e336c10b0e9dcf87efbd881b675f47435f3d2ded29da672f41c910cbb3f05d1f2b2fc907799a3b4651bfae95ceb1eb397bf9252c386efee0371826980538fa5b50704005a2e830b1f6c6385f1650257955fc2b9148e0791e411098f7218c139d6db908599aad57d13aeb6aee38409838eaa18f08e28c9ec64424968496328c5a1b69711cc72bde9cf2dd4f73f419df24d378048f9f301e894097442042c7a615158e96ba44ba2d44248135d26da535222c75fa13b896454808f92ca9540a2fdee8c20061193f051dc90f4c94228912c6b4a367c3ef38e68cdb902a478f35811fdffe2b63df3defc7dc3b4ff1c4c5efe7fcbfafe3333ff93dc6af41a2231f04887c65acf8c5c446e3022964644a63a4c54240bee3ef1cfcce4fd2d772122fbc673232f45042a39534a64014357014fa33caa540715d948598ff8619b32c1bdb96f47a59bc6c062934d930c04bb8584292c964b01c9b442a8d9b4ce22693584e02573a2025b97c1f4e22491c40400739b40a23458b60eba64d78818f1692442a4d2a5d8f934c6147045edecb90701df2f91c8e65e1ab1d0b05bae310b48d194da6af8fad1d5d85f54cda36f951a3c8db364e10e03537a34b42494b2919d53a8ad1a347a3b5c6712cba7b3a0995a2b1b1114bda8468fc40e1d84e9591fbd6422159609489dc76247e908fccc442c2201f31ee765123562a959643277f8a971ba195ebdae4f379a425b1a583b4cdbc8e51ba8e16ea209a55bb89e175ecf6a8742cec3141067464c26b5992d8000d4c985d63f960ae91950f5881d81faa766440553856143e19864c6b90b2fcfa8184897bb07d18110c407ad64cc4b3cf21264ca4e188c379f5f2cb197fc105645f5b8596122b9fa7e7a545b41d7b1c9dcf3d8b9a3869d03a3b3044bc4b51fe6f867b7506201eaeb1fcdf8bea88b13de6170d9618f0ba49a7fc987b375ec9470f9b47d612bcbee415fee57b7fe586d3266f53ffed2a5493b05622b629060af6d595137d576b0086c309b8694c13c79d781cf58f37715feb9f09572b64d622204feba2b178753e3a2198b0782a13964f2331c5e6accde771d83187d2306a6821e97614d5c2b8064aa190266a8456204564ea11990889128b1851a1f51191e4a7af8f44c224c0f17d1fd0a4d369841074766d454a3b925c17db620b4988205461a12d1281c238fd2a4a36931a9450a2f1601ebfefcf85678beb29953229a56ac68e2f106e2563320e635b645e8d04db719274f774d1d8d24adfc6cdd43536d197cd60bb2e2a0cccfa1111fd52171fb57ec2c53cfbc4a5514d946d8c0087fdd7adbc1cb5255466930ec3a28db9d61aa9cc7552da86a889080c2964c9cb8144ebb1bcb070b1798f2a20d461318798b06a1293853121fa6fc216a0fd1cb69dc20a3c6ca17084201b6409b547a0b509bb1a06f8198f7cce44b7f1356865c2a4363636a2831449dbc6f372e4337d84a15fd89cfc5c068d3604b0a7e9f37268cb26994c914ad7e3dae629b66c584b10048c19b76f8d27191cc3c5f0271209f69e3c19db5e4b4747279e1f60d93699430e61e5934fe27475d175e49124d226128debba8c1e358671e3c6e1ba2e2a0cf1823c616888b220f4b1a4f1b3a87448bd6be55d555af0d6403c9f955291d6ab48442aad2346384a64292466f11a1e4232d65c9b39564efc574ab27747546ecbf1da5dec9ec8d1060944fb00c5085e83f13195813dfa97f53f56da963dd8f918110c80d20a15f890cfb1fecebf907d79316b7ef043c2e60656fde8878060dd6db7d17cf0db112dad8c3ee288c1eb0c828234bfc40fad243eb581a8f8d6d1f921941ad66e9ff9c520d7011c72de3778f23c131ef0f66f7c908bff781bab2f7a0713dd9d2de532937ebbc5155a969926d482effbe4f346529348248ad11576131f80e1cc04dcd2d6c2d127bc83fd57edcbca70058bfa5e6485bb944c578620f069f65b9896d98fe93367317df474c64f1b8f9bdcf989cc44e5602f414cf086229212ab101139e3ca52064f694aa84943906a8dd6461294c96448a653348f1e85f215dddddd044150a0bd2dcba29404955222620952a88a9b52f42d318e9f5a1b86a0522350f95de96c26a52c932c5532a95a9b2457b1c6231e9765ce9d3a442b08f191521a5f8920209148904c26c964bd42ff1139c9ea12e29f684b0db5466a8994da682544dcf6f2e788735da98accbd71e784422384420a0b2c1b4b3a8030263542c406fe68151ac25219932a29245a89c24c5722eee8ca90bcd51d5b959787a4830e3c84f2715d071f852b254a0791699830cf886d181021d1122c2dc8747712e6b3e4a5c0f372683f0f42112a08954f5d5d9d71fa45a308f03d8f6c1090efeb2597e94187c687c8c64404da51ec30c31f0db5442ac1e4c91318d5da4c6767175d3dbdc819fbb3e58b5f807c9ed4befbd1d8dc44737333f5f50d34d4356245999a35c6f95905e61df9790f4b4884b490c22918acee417f019399efb218123462e04bb7a1ed25304bd78a58c25db9b66c8bc9d3ae842e59f74dff142407256795acc9d1f7b678075663844ad7e55a6b75653fee6108760e460403b0e9b1874169ec8e2e8297323852906d5f89d7da84f7d2cb047569949765f33f9f65d47bdecbc4934f8e36bc78a8eab2cd1e2cf4e8d164a4346128e2d8d642a0221be6d2892e63b383e8786c0ad497d8b19073db8af75cf947de73e5ceabbfbfaa4d564cd0f2b07c0645a94b71b1b086bc3bb9ae3b68a49e5dad01184e24d309a6ce98cad419533996e376614b8acc9daed81ce37213e22ec08ea5fe91a8dd989458c600440a7c4f2175d14448ca68aee82894a6d6343434e0ba2ed9be3eb2bdb98259492e93c59102cb9628210cb1afc1b28d9e596b6d08d2c8fc2716e01935b13009c94acc8d2a51b991546e2ab1c45d88fe9b50fcb72c3034443948a2eb958818224d5ee57112493a3bbb691e3d8620d4d8ae4b3eef63dba5e33beef7786d92915d7d08b1f36dc5a658686b89aaa57cae2ab41684a1471c3fde0a4384ad11b66504153266c8556432e197890085d4980cbd6145fb8a88cd80041853288028a42b96b956073edad210f8601b6b752923a9a2d40815121280368c095a98c83f04e4518481878520e1da6029f0408701f97c8e5081eb26716c1784851f06f8b93e5ccb25d3db436b6b73a461da7e0c1fc36ff4c9b6edd0dcd44c735323beef9ba84907ce443a36b613e592c1368c629c093922c8c2d0e467d068bc7c1681c24da4b02d2b9aafbb892dc92e466948ced82f078accba409525b08b26fb76dfaf16313ad24c55842ced06d59f501f20ab86d1620ead0f6b3144a5c2945a6bf41eec5c8c0806c09d3e83be8e0efc440a3b9f27b01d4410102612283701a34791183386b6e34f64d2a9a7916a1bd34fc55439b8ff65c5f27e12c0a2ca6a60a7d4370b4a1dfb2a3114f39d5ab2801de9b76a5cff488f0274fc15cfeeea26ece688f56ad5202ace8b11133f0369c20a2a8912549e5f4a440d346e2bc77a91802ffe8e63bfaf1aa09e373be22d657bccd624fdb7a458c8521a70216643e27719608c394dffffa524befbae8161a08c0e471ac64d481c69216dc7ec2d9631ad304616258eda710d42625c3b222d8aefe16b43a4d94913c1ae78afb72662ed5a6c3aaa115154b9382081d16c29228da58c547a05d396e1c34823fe21d66ec64c40dc6e452c4ea9b5f3cb01ca2a119b6795f64f6c52598bb6a81480d4d2208ca4bede5d31221880d9575cc996858bd8bc681199152bf07abad1089cc646ea264c64f4bc0369993b87e6993371eab63d36ff5b05955c76a91d718c4a7566ad7acc04ee2f35288f26b37dedaa6ccbaed4000c974d7035d4d93e96df8b48b5d2e743a87415bb4cf3bd4728b2077b30922011a234b2892493c9b175d366daf66ac3913608e3606984f9a29caa12c28441152634aa901aad02422f4f68d9c81a0114de4aa8b43117c8024f58d01696f808949ba32806161e0c8dd07c3398a91499800a7a6090c719ec796be517198cc0af14c856c348f0b1180918110cc0e8830e62f44107b17fc5f1a1a88aaa9df3561c3cd5266161e1acf15d8d41289fbc95a65545c493785bfab99ae903ec7a0dc07038015783ad43926d8fa3c6fa8c7d7801ebdc667a1b1acb88fd3d84ff1eecc11b87e160f80b53d6d83d45fa0a8997f3b8fd953f1374f81cbcfc2826cf9dc4d8fdc70014a4aee6620dc2245153b1d45f08e38313fa8481871326e02dce04f40f29291142470efa16619490cd10a251c8d958ecbd0da8b58f8d78e25f5330931615063dc5686b94477b2b9c106be16aa3608255614d51cdea606816077bcc83861b235a7f180fac5a9feaf6be066fa58154cd490a8aeab838167f69149e6a659591546a39f1549eb3a378336402ae86bc4a502fc7f0ea823ff0cc995f2351bf1c7b246e247bb0076f22ec7026e00845a9b3d966ebeaea694b8de377f53fe7f3e33ec173af3f8389a85a24fe950a234f711d99b30426b15ab406a3c22873fa8ef93abc1950ba1fc5843e5a22851d25a193d5f7fcc29eb4e359a34bdb11dfa354bbbe7ba338d64a315ccc4c2903605956316a12d4ec9f4a216435bc9568b79d8d11c500e4b66ca173c92bf81d1de82018fc8208a583694472ea3b805af6fd83f93894aa574b99816ad75523faab310983a174f2ef2e51807616840e69eaeb46f96ba86f6c243953618d5d4a735737b6f5d61aa37bb007bb0b8693e12f123d26dad9ba25eb685ffb2a750d8dd8d3439eedfe276b5e5c5fbc40604c7b22a7d6d6b63652a9146118e2fb7e614d965262d9234279bf536192a369a4b40b9fd2001696ede22652589683ef17fb90c8c11a4c300113ff3e240ef46d42edfa85fa4db231d5ef536d2f2cdd2fab61380563db82028354f23b0eec51f85430034298ec48a59e543afe3784f6bbae8b6ddb65893e2dcbc2b66d5cd7ad4987943209a5fe037159b550e17bb07d1851ab88dfdbc78adffc96940a69983f9fd6030f24bdcfb4c282b907e5a8a566ab442df55cb58919874f1c68111b8a0f403513a45a783345011202eab5c7e88e8d780b1e62e5b18fa12d453253cfea13ff4673db26a63d7a265d6d13d9e879db640224ed049f3e671a33d34026c3576e5ac5ba60e00afe7ad50256ac2ff68f9fcf70c9cf5fab5af6ea03aff29d97fa33541ffec03ebc6b6a3d131bad7e0ecf03b5697bdabbadf8eb550bb6d909bbf49abf5eb580cd2b5671d62f37d72cafacbff458cb94317ce5bd6dd4850a610996fe7305d73e564c1e6827eab9e38ae92cbbe7653ef5f8e04905f760e4a17b4b0f4b1e59ca3dd69f79e2d0fb0bf3fda1b977d2b57613e7dc7d31738e3e0091aab8300808438d960269db5842e0058690cd65f338d66a2e3ae57d3cb519187d08b7df7503d392039b05092138f0c0030bbfddfa793cfde8afaa961d78c59ff9f5195387a917de281423588581c9bde046d1fa82c0c3f33c5cd7c5b26d822088920c9afdc7685c548171db1918aaa9cb70a334ec7121a29f04152ac2308c984aa32d574a110401ae9bac59df7010e0d5a2ae55de630fa1bf7331221880d89c27d9da82654b36fdfa6636df7337e1272e66e2a489c81ae13835b56dd0f7d9675ff6dd773f8e3aea281a1a1ab6494addd3d3c3238f3cc2f2e5cb696f6fdfdec7da65e86f3b591d7194856a1a94384cdd40d81e6ffd6ae7be193201033842333abb89fab14fb1f2437f67d3d4d769dd3896546f1aada121dfc8eaf73cc8d6d98bd8f7cee369dd7038bdade3c90f519b3cf7f47d99b86425173c9e61fae1d3b9fab47a3ef6e79e41afbbe83f176f57598c179edbc0dfef59c94d97cfdba6366d6f7bdf68ac1e3791d35b3bf8cbd681c77b357cf92313b8fba70bf9ebe6108464dad8f2f13df990896c787623d3de391e1e5f315c4dde835d88f80dfb5ec0abcfbfca1d4b6ee7d183ef61ede4d768d9509cefe96c030f1f720f2fac7c86e36e3b8dd3a7bd8f1907ef8fe518c9abd64569b2b02c53736493adb5e6a18b4f65e9a9bf61e1670ee29fd7bd8393ffed6196fce29841dbf7fcf3cf6f57d9c88111084a6163f2d118a23e088c2646a910cbb271dc6499b36929e13f1c7e8203d5f14611b69582b6580b20a549ee282d89b42201aa0e0ba98d1cabbfe9acd1040c5fbb2ba330f637d31eb65bed410d8c08d1b9d69a309fa773c91232cb96a27219d4c6f56c7af8417a162f46d588fd5c6a735629a0ce04ad0000200049444154d9debc790bf7df7f3f7d7d7d4c9830812953a60ce93361c204fafafab8fffefbd9bc7973d5fbeee8b3567e625558a94a6c280c4b2ddf88d2f26ad7c4e63eb5546d713db66d173ef1e2597e4db94a55a9a0f03171dc8b6ad7ea1f835de90300c363136c1332be6f35ce8cbb78e6d2dfd03b710b9396ee4b7d6703a11d20b4c4095c262f9c0ee3733cffe9dfa10fba95b6cc1aac21daaa9e39d3e1a6678dc47ee5b3eb183b6b2c00a9c666fe70c50cf671cd7b39e65f66f1e3931a77f899622c5adecbbadeea6dacd5a6c1cafe7ad5020e3e666faeffe40c6efac22ccededfe5b063f6e6ba0b6770cb176773ee0cb7ecdca34e98caf59f9cc56f2edd97b7d5972f6bb5cae61f33955b3e378b9f5e328beb3e583b6ce577ffd4c9b91f1e5bb37c204c7504abe3bed18a15ebcb9988f38e4cf28bfbd6f237d5c8fb9bdfda4e9dbb03162f5e5c60fa77045edee385875fe057ed37f0a733ff9bad7b6d62e22bfde7fba417a7e3b565b8edcc5ff0934dd7f1c2630bf1bd0084403836d272d048c24013841a2d2da4ed62392edff9df55fcc7c7e60030e7bcaff1daff7e0780ded5b731bee56d3cdf67f6c5df9f3f8bb75f76ef0e3fd348839026d07de89b3dd3719c82e94910f8515e86a066a090c13e43c1ae30f719ecfea526365a0768a55091f643088d1436a24463b0b3504a6354fa1e969a0dd5a241f660c731223400bdabd7b0e1d14758f33f7f26fcc73f907e80b21c7a1e7f8257fc6b187fc607187de45124c78e19b2877f9cc5efd1471fc5755d1cc719e40a03dff779f4d14781f294ec577df8146e7ee87196aee9ec37713e7be609dcf3c21adca424484ce16b37dec20766350370d9898772dfba1cb6a5c8a9162ebce6663e7dd224b4d67ce1dd875794ddc4bf9f68ca2e3beba49a750ed4969d854aa7eb18955c7eadf3079ad06f864cc0a3fa7a10fb3fc28b67df43c3d666da964fa063ef8de41b73d87d2e4e20e89cb419379360f233fbb165ea06969ef900b3bc065a5ff9009b5283c7559f9d902cce9b3e0df27d38897a00b2dd9d7cfe9e16aefde838fefd21c9a7a6f471d60f8bcf74c32545ed46a66b039fb9796be1f7f59f9c41d215ac5fddc58d77ae63457edbc653ad360d560670e4e60d5cfa932ce9d6d1fcf9df6770ef1f5fe1330fe449b78ee6d64f4ee6d7572f2f9ebb762d97fe5f9e09b3f7e687e78ee18c1f6f18b4eccaa35bb8f4aae758e36b92f5b565211b5e798da74f3f90f3276ce4176b86ee7b0470ed53bd7cfff3b37976690fcf2defe4ce67bbc8455d986ed98bb9c116aecc28daefcf70d58975fce90f3bc7e17c0f868e1d8efaa561eda275fc65ebfff0f7d3ff42c396a1cdf7c7df7d1f8df7363176d9679970c05e68055a0ab4b450b160465858760269393cd6ed716883d17ebb8d87e175997da97ee219dcffbd3f71ec09ffc1e35feae3938f1dceea974f2c346fdebca2a6ae61e2e778e4ce8f147e1ffaf605f4f5f9ec7df0a95cfda3ff606ee3cecf44be335130ebb18b99bc8500c771e8e9cd90482448241205e9b8c91720cb4c66463a4ab500459a4513841e7d1d5df46673b84e92969656632ea505f95c8e44223201eab73557e64019de36c6d86302b4f331221880e72fbb8ce0c51760e366b424cac6a908b359b27ffb3baf3eff02ab0f3984fd2eb8809683de864cd6b65dabc4134f3cc19a356b0a0cc16008828055ab5615fe8e71f447bfc8bf7eff6decb3577dbf6bdefed16bf8ce490bb005ac7df81becfbce73f9c0a6db01b8fc0f0f736d93613eba97ddca9879efe2df7b9700f085df3dc8779acd02dcb5f456c62e38be5076d0b9dfe43bef3ea86a9d03b5e58d42a9bab11ae2093f145f8037830f404bc3425e3ce5ff68dad84adbb249b41fb598d4d63a46bdda46b6258bd3976454679ace499b5971dccb4c7974065ac3cae3efe7d0adf3d8d4bb609bee57b975ad7a6625b7ce99c3cfcf82af5dfb52810885da663e177ce705dabb4384901c7ad454aebd681cefffd1da6d7cf2da6d1aacecbf1699f796e9d882b426f39397f385df4e7252d9b93f596ccad62e594dc30767011b062dbb6b8dcf951f98c41d0b3b79e0a501083eadb9e1b79bf8f58727f2ab6bdb077ac47e78eaee657ce8e93a0e9a56cfe16f9fcc7b67ade3ec9b8de670eebb47b3fcfe6500ac7b7135ada74ca55ebe440d65ca1ebc01182e86ff8145f7f3d0b1776cf37c7ff0c0bb58f0e2219c71c0fb8d96d57249252da46d34ac4a83104e64125444e5ca39f363bfe3f3bf9fc49c0f28fe67d572ea64f18c5a663e0b5fefe480894d6895e18e6b3fc4b1877f8dcd8bbeb9c37db1aba0428d10168e6b8350e4b21ebdbddd0801a9548a542a85528a7c3e8fe338d8b65d2090832018163f805d4dc04a29cb181b304c90efe7e9eee8209bed23ebf9f88e8f6d3b34008e2d8d40f40d6a7a2d462b8e9eb5073b0f238201081e7c10fc009570d05a63f91ea165a4223ae9626fd942febeff63e9c68d4cbef862f63afe5d58c9e48012e6a7813a4c07c855ab90439ca84a6b1426f7e4d692fa8f3cfe1d35af39ebdd45e26daf43cf27dff97dc00cfc5111f1afb526d3dd4572cc4185768f8e887fad35d9de629910820f9db480784d2fadb3b22d03493176c6e254cbc9695ba42995ed7a33440172d26b091b43c6fc6322af1db984961563486fada773ca2684b248fb82ad5336d2b2aa8dba4d8db41fb698fdee9b4bdfdbbbb0536b60080cc04b79c5cc84e0f99cc649d4e1e77b0b6542dacc1a235917c05e69017d83b7b9bd3b8e94a178f2d1761a8e9f036c1b0330509b062a038a4c4a34764a7f0fc7d8fdc5cf17f1d0de8d1c31772c371dd5c819ffb5bae6b99dabd7707b762e97ed5f2e11ed0835636dc1868263b38baa08d1d8b5b98ffb37f7f1c0b31ddcfb9599c066846573e974077bfc7edc12996d07c2e192290ed7acdc13e2716443f1ead6e5db3ddf976d5e16d9ae83ed3a58dac6b26c40a030196f3582231a5d9eecc9734c53827ccf93b84d47165b106ce6f1253d4c4b0ada37e7604ca587717f1c30b1090021d39c76d9cd6cfdf23860043200711eab8a35220c43b2d92cbeef91cbe5681b3bde9817475196c0980d0f97e47f2851f676264ab519a5c238dff7e9eaeaa2b7a707db96d4250d23d4dddd8de77934378d26954ed76c77dcc13bdafcc1c2b2ef6ae6e9ad8011c162a950e1d7a590418893cb831004b68de579587e40984e011aefb9e778fd969be959b66cd03a05260fa0834922ef6a4d426b92353e09ad71b5c68daeb160bbbc541ebbe64c261cfffdb263fff5eea3983b6302d34efc4f6e7efc86b2b29f9cfc0ee6ce9cc83e55ca06aa7357a0d2bf6020ff031838d37069d9aef401182e9b60ed66b1029b7c6b86c4a63aea3737b1f180d5f8e980c635ad48df4248c1a6d9ab4975d4d3d43e9ace695b49f6a6c9db439348fe7189cf390bcc463f75c138362e2e4ac18f7ecf74c62e5ac9677fb6968f7f7c1a6df6e08beba4747179983c733cd99e8ec2ef5f7e7ad60eb769a0b26dc545fb1b5388713326d2b369c3e0654230b54eb07c6517b7dcfd3a0d635b06bdc7ef7fb38ea3de3fa5ecd8efd6055c32bf485ced377f125deb8aa11d8fdd375510a4d58f6ec2cf670018bdf724925bd772e677177176f4b9e0a64e0e3a75f076ecc16e0e01197ab77bbef7d0595699d246f004d2fc1d25b6baecb4c97cf5c645002cfce557997cfae70b57fdf1a277f0da077ec7438f7e93cb8ffe20abf2833bb02fd95c8c42b5f87fbf4cfdf8b386ab478601d57cc42495248c86d85b156111f99e19e23e9974492792584882bccf96cd1b4187d4d5a51052b371d37a56ad5a456f6fef902d02b61543f709a8ee0f575e19fd54a7bae413a8b0a2d8d415061e99be6ea48c7cfe44e46718f8f8b93cb94c2f9e972dafb40cc6417d4751cb07608fe9cf1b8791a101702ddcee1e846d11a6920815801428d7457a3e76772f7e2a89d49afc53ff60ddefff40f39c3955cd4b0a36e998a5236602a2180b034203f1322a61c85a83188b7ff7194effef461e5bf291b2e317dff3089fd48ac76f3c8ff79cf00d36bef8ad42d927ef7e984fa279fc97a66cd3c26b8654678c377a220de4645ccbce6f30ec6a0dc07064020ef36dc850e2762548d7a7e99cb819a1056daf8ca373d2564211d0b66802ebe6bf46e7e44d38f904898c4ba64593eb6b1ed23d5efccb72d69db30f3f5fa0219be18a9b8c447dccf48905bbff9c862b9e68e67b1f1cc5477e6b4c514a7d00b4567ce2c7af00f099f366502f345a4ae8cb7075141ed47252b4a5f3856b4eb9701667470eacbffbc21c329deb38ff679b076cd36065db8a27264de0faa3938cb27dbe7de3aa41cb84905c74f6745a2cb05dc19d77bf3ae83d325b3771c3babdf8d4b4e2b13b7fbd827dcf9cccaf0e13f848fcee5ebef2eb627080d9074fe49c531cf2a1c625e0bf6e5909c071a736b0e89e3565f56f796d356ad46c662636157c23f6e08dc5f044fd924c6c9ccc73db39dfc7a4f68a362389251d2c59acd72e09ca7ef44fefe03727bf8f39370a74eb41dc79b7d1fcbe7ef7e7f8e46387b1fae593a893823b2ffd2347ffebcf59f1a74f00e53e00422678eed9a700b8f08483e80c6d449885d1f3f8fd23bfd8813ed83e946bed7549d41a8829514d88c02608c0b6245a80524622ad0548147ee02325d86e6cc6a3b01004be4f90cbd3d0d040e0796cdab016214c9805e3100c996c2f8e6b914ad691cbe548268d343c9fcf93482476487a5f3bca4d4572325141f4979d2ca344bca27069cc246a19478a026dd928c0cbe748258c6652a2d9b4ee755cd7424bdb0419f103d00a4b98c840bd3d9df4f4763279ca5490165a2984b0e30720081496b5e3b2639367809d1672750f06c788600012d93cda75095d072bef81d420c0f27dc2848bb0244e2e4fbeb1012bf0e87966f0b8df02814414980013786d60c453328ccedd9690584b6fbd9c232e5bc87d2fddc5ac74ff6e174272d839d7d371d138e05bd1b1d8515670d8b9d7d3f18971c03585b2c1eadcd5886d0e6b3902c7c74abf639845d6fcbd2b7d0086cb2638b7655fd24b5ac935f492e84a128cf6119e44642d72751990a0d0085fa0ac687c6f49627bf5845ba61b2e7510847e9e6b7ff172bfe39b96aee65f96167fbff4e032627671a018f99ffd71ffba00ea478fe5e5fb8ae63277fdec65eedac6360d5656d9aec17e3f7cdf0a1e1ea09eca32ad422eff6975cd4e69dd95f7b9e3970bb9a3e4b79fede3da5f2da95a0fc0f5bfadae8dfcfd0f5fec774c873e1ffcda9b210ce3c8c67030fcf3db0ee291e5f76df37cafd38d2c187550494de5bb52e92a69a7a673e3038bfadd7bd2c9dfa3e3e4e2efc3af788038c0ec40d2e7879fed5fd7ae84d69abebe3e3c3f876d5b388e8394e0b81696b0b06d49e01bc23d9132fb9f17f868425cdb4612850227ca096039b4b6b622952497cfe0b892400568ad401a5ac05721b98cd92f52c93a122521c64b09d5529bfaed7fc0e8bb928c2810ff25270893e5b81fc290500ba42d9142e02b8516601bf13e592f475dc205145a2b162f7999bdc68e61cbc60d682d0a11fc22ef0084d60829b12d8bad9b37535757879d48220910d2466b43abbc5504f42fbf5c7d7f7ab360f7a31aab20b46d42d7c1edcb821484ae6306a0d6d8992c41431d4a0a84d66049fc4c64e0ac258655ae82df8c86541291006183b4c4e0f9c454e458140079d01d43e35c97ddf6250ebdf449ee7ce95e0e6e2e2e283ad8c44b5b1b38a0cd382d2fbdeb4a1a267cc438d0faeb59d4d9c4016dc697c1949d03186279d96d5fae5ae7ee804ae7dea19c3f1076b5066038b0d19dccb43b3fc492337ec9a87c1b2ded29da672f41c910cbb3f05d1f2b2fc907799a3b4651bfae950dad6bd9fb2f67b3de9abcab9b5f86ae75ed7c61ddae6ec51eecc1f063b818fe0587cee7c3f75ec48db3afa3a1af7e48f3bd73ec7ace5e7e090b8e9b3f0c4f3232512a248a4d413ccfc3f374e4a40b8e6f9170158e05b6e3603b360aa32d702cabe03caab4460a41100668a5b12c13fd473882301360291985a5064bd8486921b4c6f73dc29e806c436f640baf0a09c2e276c5c9b376726f98af02e12f0bc7b588481b69210b3e0fe05a3212549affeb5c9b4cb61781a6b3630b524ad6af5f4f7d7d3d167188f1f87a73bf2008f03c8f6ccec7711c9ca431718ccdffdf2ac4ff8c193378ecb1c7b6fbda918011c10028d7c1f60284d604a914d2f310b980a02e89d3d38795cf13a493082d40d8c8e9d30bd76a1599fe148e08f3ab2f3ae88bc8135846f32b9e74d1778181d091099d321ec0be864c54a2353f3b7236df78cd6c1c13274ea471ca5778e9d1f30138f043dfc69e3c938b8f3bb4d08a479e798e94b7894b4f398ead9e85503964db7c6e7bec270814dadfc8a5a79cc056df0295438e99cf1f1efe09a61116f3ceaa5e678325b8e18859fddaf2f26317eee05be88fd80eb07a9c5e8817a16a6641950c42e56f21042a34a9db5f5bb57ac44701ca5849568b594cfbd325f41cfe00cd1d16d3b21601795a178dc5abf3d109c184c55319fbca547a5a34139e38990d7a5fb25662e0103a6f716c6ba6df3dd8839d8da6314d1c77e271d43fdec47dad7f265cad9035e6fb84e5d3484cb1396bf3791c76cca1348c1a3ce4ef9b19c57d40934c2609954f2e97c3f77d84d00481249bc9a3c32e5a5a469148264dfe5fa591b621d29536847da002240227f205cb64b378be6fcc89c300421569f3410a8d232d140a05747676904aa74d8c7c6d189058f23f2c1182caf80751f26d61f443032ffa8152d8b6341a8e308c6ce9c142e1071ebeef934ea59142d1d9d141535313d9de3e9c540aa502f2b96c744d311bb29626f2542295c6cbfb58ae83b42cd0b29058f54d121d7550bceb5def62debc79db2d781c2c51eaee8011c100e03a1086514c6481f0434464f4a7653c7d05c2b1a0a199d1471c49694af06ad0810fbe42698952925098ba0de15f49d06a101aa5344a0b54a0205088d0cc602104173efa12175269e367064026a8de0e9d9ccd034fbd607e88a2b38fd621566a267fffc733517d462a123333007d7e5853727ee1a30ba3b6ec5cdbbac124f7b5cc7daa5d5b2d7a90941242f5a6c804ac35f4c914abecfd687ca28d9cbb01b77b0572e22ad2198f20ef23bb1b687a7d32dd99c9e4dbc7d3e534115ad65b66c1dd833d7833a1a5ad85a34f7807fbafda9795e10a16f5bdc80a772999ae0c41e0d3ecb7302db31fd367ce62fae8e98c9f361e3739b2e3ee6f1b068e27effb218e63934aa5f03c0fdf8f085e616cf909159b37ae239d4ed3d8dc826dbb85d0dcb66d2384114419625d030acb75b05c9bbc9741aa102b0aa527b48250010229c092825c26830a4384b08c490d511e81c8bc66e74296d8fd1725ff4031ca11b2e0fb20a5245479827c40a87cb40ee9e9ec22c827c8653dc68e6d63ebd64efa7259da1a1b58fbfa6ac6b434a302df88142d0b61398461481028bc20436bcb28925148f598191191fc542918063780dd1a6f86f0e383614430003ae912b80ef6d62e13fad3920834dab6d09624482751e9242259cfa8f7bc9709ef7ef7a0757ab4d095b3b0858a620908a49005c9bf10712210c3f52a1da2d128344118920f359dd9810db36b87b932c7c3d02f78c0979f57b4fd2b4d912d4acedb1dbce42b231a94aa6ecd37fdca4acb6bd553384f4ab0e42e9f88c361130c663d0f84cd567b145bd528d8380b36d63839a603f610ff7bb0076f18868be18f914c27983a632a53674ce5588e1b963adf2c28ee1703954b6ccb8d127319adb352a6ccb1255e3e4f6fb7d114373536632792a08b84711ccd47298d9492443249636323dd9d5b716c435a6b21512a4485667f97d2061182d278b92cc9ba7a0ac4b77c0308ff32c1656d2a5bdae07981d15c38c68ebfa3631341e8d1585f4fd291e43219933f22f058bb7635f5f58dbcbaa29d6953a7403e4f736b0ba9a666b4efb36ec326babbbb49a4d234373793aaaf435a0e2009c3a0d097bb01e9f186e0cd607a3c18460403e04e9f495fc756fc440a3b9f27b01d4410102612283701a3479118d346dbf12732e9d4d3488f1d3b689dfb9ff974cd98f5952875542d27eafb3bb59613bafd8fc54ebd65750b55765ee13eb1fda28ee2f90a59d008ec6ea81671a972a1a86402621559adfe8d2b19e99980ff7ad5b625f11a1ce51b4418fdb4a4021d12fa39bc7c1f2af0cdb93ac4b22c82d06ca896e3a291f8caa8bc033f8fd4e55a2a15452101235d721c8744228d97cf236dab60131bf87912b6c4cb66c867b378a1878588b4d8c5f4f2a6d228567ec97d8c4adfeb3ff6e376544926579a325e08015a17247fb16abef477acba376d110586b3702fa5cbc6afd6ba70ae6559846188d6baa0fa2fcb122a2cb490788122914c513fa68dee2d1d2452690492402bb41665633cee6b51886ab2edf379b018daa5e7c57d582b0c6f355be66aeb5ae5fc2d351b48a692ac59b914a902449045871e9606a502424cdf69244a07a034d2d2d85a184758210923c14bdc96b8cf8510384e822008504a4592dde23359b68b923641a849261c23c9dd410c17c3bf0743432d7fb13884b39492741497def3f2666e6b8d5601c9a4431084f4f676a394a2b9750cb69d20f07c2cdb415a661f524a118621b663914ca74837a451b94ca418088d483bb26f175aa103005920884534e72d6915988b9d470817b3f596edf525535247917e846d4592f8907cb68f5cb68fd0f7e8d33ea35a5bb1b28afa96512c7e6931cd0d4d2821696e6ea66dcc5ea85c0f5bb76c66dd86f5d4d737d2d6d6c6f88913f13c9f5c368feb1ae97f3f53163d0c0ed02300bb5af0f84660443000b3aff80a5b172d62d3c217c9ac5881d7d38d46e0343652376122a3e7cda365ee5c9a67cec4a9abdbe6fa87ba99c6e58385b28ceb28d6d59fd1d05a17928e1437d712a244c45a8210df37dc77c2b5cbaedfd55a80c1e2f56aadfa3105a58444253156a94150d1c2d3fe5afb9b7e226e3f54c13653e900150404bed9244549242588882b699348a410d2c651604b10f5c6d1ade4ccb23b849e5720ace3a4323a22ba55084a6a6c3781b06c443e8be77904818744232d890e0d31de2fd845ac4f4622842a6abaa24f69a48d6a5aa24288c02af3b7743cc5edad2c2f6f0765e70f744eb576084b1a13423f8fedc8e8bdd46e1314dd8c06d3f254f38f19a8bcb2acda35d5da5379cd40759431ed524214d3bb7418c57d653b8668d74884d626e042c40068019ee7a375312ef840cf5da6118d3e26436e804447f1f2b71fc3e5045c895cce63f9f2d5ac5bb7a584c9518c1bd7ca7efb4d22f99632fd193a62463c95acc3b65cba7b3ac9e7f3482150be0fca44a749261cf2d91ceb56bf4e43430b8dcdad0861fad8b625b66d93f703945648211833b68df5ed2b0b6b8361f0ad689c0ab40a01456f7717adadadd80969b408964388060dee4edf7f07ae3fef85245c0b89229be9a3bbab031d06a8304fc7d66ef2993e264d9e4cfbb257482412f4f476116a8bb973e7b3f49557a87320f03d24825c2ec3dab56b49241234b78ca6b1b585d27da0b0275764157e33638f06603741dbc107d376f0c1ec5fb2f90e57b6be81508bb02f96579f04c5c952e2403cd079251bac99581a1d85f30a8260d8d2920f37aa4967cb0924d56f53af766e391354848cfae3ad30118786ead24d4b00224405219e9f23f03c5418624b13ead60fb49198095148fe1213df0a899fc93210036036456d7c5a84f1cbb02d1343da72247e18222d0be1d838521a35b9a751a14fa8548109896b55d1bd2c8a5135a07f12984ac2bc1633199bc655128ba58cc4403e272a2c6ae06282a0d259bd4ce25d52ae94c20b15b69b30d934bbba686c69259ff78de42c9acfc69c2f92c817da220a113c7604033107831dafc4503372961e0b8200b78469329a1237d20058e47c2fd20080d2c6ce5a48b33e86919040540849f4206b7d69e220639e19a2b5851ec0ef6b57219bcdf3ecb34b49a5121c72c84c6cdb30d1be1fb262c57a9e7df615e6cf9f4e2ab57b45737ba330d0d82cee1d1ac771a8afaf476b4da6af9b946323b4119079411edb4a9248a4c866b36cdeba9c7df7db0f190a7c3f444a701d130e53a1b1a443c24de2e573842a24994cd1d5d5455d5d1dc41a40cbc64d24f03c0f3b91348c26bae037b0e318d807c2682e88b4ad329a33d115026c115fa9503ac0f7f3681d12863e09d72197e963dddab568ad09833c9690388924b97c0e84197f5a2952c934d97c0e27f2af701cc7844db55d40524a7a98fd3c6efb1bc704541342ec6c21e81e0dc06e86a19aec0c15b5eaa9548dd7923c0e44ac9413b4b1a94b31294964b960088e48452e23af1a158646ba8a2e841bb32cab4462b7eba5ffd05fb219ab598be61666d1761ca7d05743d1b0c4df966d23e5aef501186e9be09d0121344a2b42e5a37c8f30f0b0a2cd4114ccc6e2316934dec66c2604426cb7bf2f4b29616a12e498f31dc7218c4c318c24c84258025f0768a5b0a52051578f9d70c967fac8e7fa90d244b5a08a64b97418172571e552ff9880af4684974a85cbfba4ff4651cd1ca674ae97ced952c6b5f2be711b4b35585aeb485be7d338da420a8fb0b04996abf24be74008c6646a000c26f11f4c2359adac9656a212dbaaf15461880e4363d6a82108fca29435f2a20201a146879a4085b86ea260d71d9f5b6a1e2884d5ef790bfd8f22080c21a3acf00d110c6d0bb4d6bcfaea6a1cc7669f7dc6f1eaabab696f5f8f528a3163ea9931631aafbeba96e5cb5773c001d3768b757d7782799d3a12b6291c3b413a1de25816999ecdc848c894742c0205f95c16b445d2b5d9b0762d2da346e1261220145e6092174adbc296164dada3d8b86e2dd2b2c9e57234363692cbe5705d17a57c845004a1476f770fe9864602df475a0ebe1f90480c2131cbb03c3b86f82f0c8b589821b0a44220e8eaecc0cb65f03ccf682c5a1ac866fa50a1a6b7b71761d984a1265d5fcfe4295359beb21d475ad83ab2808acc396ddba6aea111e93a11a3b17b4bf96bd1830399366e0bde0a82c711c500f4f5f5b17af56a5cd7a5bebe9e8686061c67c727e2609b46e926597a6e3546a09cf02fe75a2b37d302f15041d01be9904fa8cd6668db76c10167776200aa6925e20ddc30014141455f1a4339fe2ebdbeea3b88a4bbbb7a22ee6a9be0389a5455080591745ea9c0d858134b488b2af4d889aef077c998f6832a52df92438ee544efcd2b237ac350a131126da5055a2b14124b980433241248a1f03d2fba773cde0d22b97b995911946b964a4dc46a31e49573aaf458695d9573a669cac1650cc450be3b573c5936dfe3be0e431fd038ae8d97e9454a1bcb1284611031fe31115334fdd15a9767f4ac816acf57da0783ad05354d900621fc072b2bebeb92fed6a191c82ba5f1bc3cc9ba34b1091098773aa3000020004944415442213408a91042a182ea12fff8994ad78dca7ed73a32f9d10a81368cb01a782d1f0cc3cdf07b9ecf9a359b9833671f962e5dc9ba759d1c7bec41388ecd030f3ccb934f3ecf9c39fbb378f12aa64f9f4422f1563405aa2e09d7bac800801962524a52c93a5289047ebe0fdfcb0202cbb67042c88501a0b1ad04b95c063fa8c74d3ac484b31d65c70d0949d6376227b61a0191d20869190da7169140ce98e8960a90cc5ae5effc2e313d80995a0293c84ba35488901a4b585896c0cff591701c36aedb423ed3476363231d1d9da4520952f5e92887824773532beb376c64f294a9e4fb7a696d6d25c818dfab7c3e8fe5188d6eec6b516c4189e8a2dca279b742e51a58cd3a615bf156d000ecde2c5e050c67ae58bd7a35cb962da3b3b3b3cc31af96d46fb00db2d2a6b4da75a5846bfc8909db5275744ca8148e55e8f84b2586524a6cc729c428d64a113bd8c48c8debba249349a490036edea51be8509eb9f29ae1806559241209eaeaea686c6ca4b9b999743a5de6eb10dfb7d4f6b25a9b4b4d3b56ac58b15d1370f3e6cd0547b2edc5ceb2091e4e681d820e113a44688d25ca994ed3dfa01594e66e288e57ab30660b63d72afe1d6b744a25f1f1f89652e2870108896dbb200541101086465bd0d0d040516a55dae6681ea80a87de0a549b6b50b445ad65a2536442ab3bc0c6c7b685f8af26091752470c80d17ca5d369fa7a7a1142635b1661e8230bcfdf7ffeea6ddc4c6b49df2b8f555b2b4ad79e6a8cc45051ad1e2ad6be5868e1380ebeeff7fb789e472e972397cbf5ab2b5ed35dd7c575dd7eefb7ec3d2b852d8aebed80ccf21071c82187ec701d31c25091cb792412162b56ac63debce93435d5934e2779e73be7b17e7d279e972597cb1386db46b45cf5e153d87f624bd5b1fdd9334f60e68cd91c386f0eb30f39955b5fee2c945d76e2a1cc993b8ff9f3e732f3c077f2837b5faf5affb5274fe95777e7cbbfe5b8b9fb336ffe3cdefeee8b59952ff6f78adbafe1b099fb73e0bc03993ef330befd979500e8b08779f3e6153e73668ec249ef3ba4678c6f6f040eba389fa54573732be97403264a8d998749d7c6b6256190c7b620f473283f674c22633f264c424f90a41b9b08428d745cbafb32388e8317f805ad75bc7de7337d1133aa0ac2b837064690a6315a35cb064b4a20c4ffffecbd79b8655759eefb1b63cc6635bbabbe2a950e9210480224010d482b44511444504450c0838222b6978320ea150505f1801c8487a3e055105414d12b081ecd45481f841b3121a1d2552aa97ef77b7573ced19c3fc69873cdb5f6de55bb520549257ccf53b5d65e6bceb9663bc6d7bcdffb0e3cd1c3dcd123444292a62983414eab3d4936301c393a4714a74c4e4c3337b7c0e54fb982bbf77c038563796e0ead73bffdd0a3a5b5c60901c89144cd8889070762b7964f534f0e8d2f7b2a20d30f76e2f15b61a7550500bc93592ad5753a1db66edd3af2408e4ed6eb4f72e79d773ee79f7f01cf78c633989c9cdcf044288460656585abafbe9a3befbc937beeb9679ddf38fe83628c412a70d6856cb9dfbe0910a0b57e3bbc7b4854001ea8ad9589ac4feee30ff523e1415cdb469dd7e1e4e72accb4ff1eba831ef9605065dfadd568633dee532538017114a31d8828a2c88b21ac6c0c86537f053c3d2e90a669c5c4628c41291f1ca48d0679eeb349ad469bacbf4cda68fa88c3e46cdeb50bdd5d21ef7b311fad2d42488454982247c571e5fcd49dbd7aa05c35fcca514853e970d697adce5e0810eadfd7cf65f9f7c25dd7b3bcf72696f7dec4d23d373277c7b5ccdd712df3775ec7f2de9b58b9f7cb231580718892528a66ecc7a041b7839211793620895326da6d9696966834dba892cd26ac8393610c58bfd1b97efdcb65c62b8aeb8d5de3d590f55ec7aff9f876d70bb04a333830c61f4b987c050621088ebc77a6fa831c6b2ded660b87a6308e56809f950effcaca0a711c936519cd663304931e4a588e8969c0651b6368b7db685b20ac653018ac791e4ec44e75c0ef020caadfefb1b2d2e5acb3860c7513132df2bc20cf338a4273a2b1d8b35ffd6bbcfc3d4fe2bc9d13abbefb8e57bf933ff8becb89041cf8d2ef72feb35ec58f1efd4700defc375fe20f677c6264f98ebf65eb139fcb2ff7f68cac7ff31fbf888f9df35ee025239fffe2735fcb959fb987b73c691bf7ffdb5bb8f2e7bfc4ed1ffe6e00ae7cd96ff23f6e9be787cf9d64e5eebf67f32557f26bbdbb106a929b6fbeb9dac697dff4445e7edfbb37748c7e4e94b57b13f06dba44498b89498543d2edae90e9c237fce2c86c81d603fa7d411c2b1a2d7f8e74a8c8452ac101cdf614ada93ef960405e0c88639f2cb16ac852172529f3f3f3ecdaedb711450aad2d71f4cdcd9ffa31cfd6c67bffb7c5620acd81fdf7a11074bb5d2aa635e72173328ad9b4a54d6f90d1595e61666686a2d321eff739f3cc33b9fffefb116e985c9152a203843155094ac5431203c692feab3e78706cbc19b93ea69f8a26e5474205e0b40800acb5f4fb7d8e1e3dcaecec6c95d93b74e810711cb36ddb361a8dc62ae7d1ad4309e79c6376768e7befddc7e5975fce631ffbd80d478cc618bef295af70d55557d16eb78f91955f6b341f2d753a0c25c3567df2d526479b0221d7be3ca7b3f35fdab88331fe5ddd1e090fe2466ce4be1654414051e438e3b3ff8472b170fefb0a5e23401aeb333c65c6b5a2a11c5a754d5ced7eaeae5539c9d4d610be67c585df3626676565855ed7a19c0667298a3ed3131eaee72735c96030c0da828989169dee0a517016ebce7add811fd9b75ab6f978cf6d3d98a89fc3fae78b77df30f2ecae82998c050ba5235a064fda0e1032427a0d6f9472a84261853ff7339b66e876ba9e9949c5a4494aa7d7f58a9b698ac9b355bfbd5ec6eb81d87ae3c55ad9b3f56cade0a40aaa94ac2a00d53f04520a9c9368ad038d6c4aa1613018606c8eb2de99b2d60691753b52e9c9b28c2ccb68b52646aa046585c95a8bd61a1995f787cf5e3e94cc155d5cff08fd85162a9fc57447853f623d8fee1cc40d0e63b325683736bceda77fcf33d7fdeec7bf7f483dbcf329af215b7c4ff5f7d6996155b4bfb24463db778cacbbf88d3fe307df37c1adb7ff30331f1addeea78ef6397ad95600763fe737b8f7a52f8610003c7b779bd9f93e9c3b496f6196e6b6a7b0ca9ce657ffe41bbce1bf9ebae1e384f1e7d8430f05a0e294a9a919acb5743b8b1405c44a112b105290673dba1d5f518fd226b14abc83effc6cace2946ddb7772f0c0fd4c4e6f22eb778922155487cbcaa4a3d7eb01aed213d0a7b072be9e95840d00c61668933318f4e8f57a0cfa3dd0059de52e139393acacac60713427dacc2fae303131c1c25207a5145bb76dc7194bdc9e0063993b72146134ce79e8a69471e8df73743a5da44a88e2d186f4519f3ff8314e7e530381638d4f65e265dc368a7ed8883d12128fa7450070e8d021666767e976bb1eafa63c9eb8dfef73e0c001969797d9b66d1bdbb76f1fbbf86b378988902505b8e69a6b489264c3bd04455170cd35d700c3c6418077fce40bf8f897ae67cffe458ac2e381cb7d79e38f3f9fcf7f6d3f712a31e939fcd6473eca8f5c34831082fffefca7f3bf0f0e889425b39bf899dffb083ff7dc6d38e721046596f6ddcf3f8f377d6edf48897bf1eb9fe0252f7b1b73aa49bcf3bbf8d43fbc9fb353ff50dcfd8fefe2156ffe737a69837ed6e235effa04bff6c247e1cc0a973de919d5364c761fb7dfbb89a277e7c62fc806ed780ecb5ad9ccb5ece1a0047c62361ab80e612e4310a677b801dc88ec78bdf2359c342dd639acb09e81a69c449ddf56bd0420cadf0b987dff0b3ee0a89c68a84dc4253fb64449877086acdf47b80289f14c15128e1c3e48bb3d49b3d92473dab37948c5d2fc02cd34458940656aadef2d7025efbeac39dc3ef8f18ea06f843b1145cab532df4208e6efbc6ee4effa735daf1c38e758de7bd34840a02205c68104e93c46d76843662c3acf704232139c5f2922bafd018590445255f098fa3436fe1c94e764dc1e6830505fb75e65399ead05b7aa82a3500128f1ffc27902001782c8421768ad89e2142104795120a423495264a4e874bad89ae31e455185452ec7bf727fcbf775d8252789fbff66d9cabdd733ffb58f7361bc88bab7c1e5d33d8edef0b59165aed83a47fbc857b828cd98bbfa3ab8f4954c9e7362cef1f1ecda77fe18bbbfe73d239f7df0fb9fce07efba8bbbe6b6f3c95bafaf3e37837b78e977ff2e1ffccaad4cabd5e3f14fec6af3d67fbe8bf7fee0f9dcf9d95f275bbebafaee03377c92a73ee65cdeb96317070e36f8c4d76f5ab5fefc6dbfc157931770f55993c7856b85e16dc4c9f4d7df434a8d369e2822c2430d5dc160d0c75a4f5b9c0ac5a0d0f47a1d1082c9e92d24690b2114c658ac12282471d264d3e6ada49164717e966cd0434b4baca2aa225fa74176ce0b6f9dbc1d7be02ac772870f409657e6e9f5ba64791f33c869c7295b6666985d98a7d16ca1ad617e7e91a9e94d747b3dda135314598ed6960bce7b345fbbe9269a498a7296a989168531145a93c40985d60899d00beb45c11dfad672fd9cb8995079ac57324e953d12128fa74500b06fdfbe90ed19d06cfe17679ffd45ac2dd8b7efe914c59359597174bb5d56565638fbecb349531fbd0e1398ab9be84abbfefaebd9bf7fff86717d5a6bf6eddb57bd2fedd9af7a133ffeeecb78cc9933abd679f2ab7f97773eef32222407ae7e07173ee7d5fcc8a1bf4708c19b3e7e157f30e3d96e96eff814db2fff017e76f64684f0745c524afef3033fc2c7cef943e0a52399d86397637febb8e558e71c5ffeb54b79c506cbb1df6a2b1d8e07fb417cb09b80abcc97281d70e133efc1e1b2c5b0f1570981709e1d65044a4399f5b715c58f90ce37bc8df94f1bf32d6df5ea8c5f41494fdd1a05e29b088192a0754ea3d1606969897ebfcfcedd678354cc1df53d1af5fd5b8f837fbc2a30dc579f953b160ca6eee4ae550158b8ebfa91f5d762f829efc5a57b6eac2699529ccf89d0e02b4095fd1252436131ceb1b430cfe4f40c3292b49b0dfa8382244d30d64f60918aaaf359dfd7f52a6427eafcaf07133ade76d6fbdd71aefed2d1776e2869e6971d36f2665986b1a022ff59d92390eb82c9c949b41d4ee659968d0469d60e85d8c6277aefa0e92a203cd19e8a713b9501ffc1dbae65c72531e7ec0298c38fdbbd91657601e09b5097f6ac70f0b66b4f690070db5ffd0a2ffcf014d7defe93239fbffe73d7f07a1cd7fdd9ab79c1956f63ee967701f0de973c8bddefbe8a17ee6aadb539defdef1fe555af7e094ff8bf532e7eeecf206a2ec43b9efb729ef9e737f33f5ff818eef8cc2ff3d4ef7d073f7ccbef8dacffafbff4719ef8eb9fdfd8ce876b59c6bf5542c29570bf086b0c520ae2468ba9f0fd20b368677d80a0629c10ac7496e8747a4c4e4e3339bd99246d92198b505e6c737a6a1a11c6ccfd07ee238a534f9480af584d4c4c51cebb793e083ec6a9768dd7462c144551f937bac8514ad26c37d1fd82b9c5051a8d46c0efc3f4f434bd7edf2717b21ca9a0dfef2242501de1683413fafd3e7123a5c80648e9a704194bb0054a8208ae7f7984a2763d28e9cf4f49a2fdd854a8c7b22c68ce1445411425349bcd1121c193ed03f87605e021629e0bff30d3d3d771f6d95f2649727a3dc5e31ef759f6ee3dc4e2e25389a25dcccece0270eeb9e7564d3c75ab67d76e02daf81320f7ed1b11133a9659e789ec34305f9b409f76e533d65de765df7759d801d879c57f235b7c9fdf96b56c998e21383fbd95251a5b2fab653f154b7bfe8217bc6f925b6f7fd14839d639774acab1ffd70328c79e8c8d3b766bbdaf9b73eeb457023ebe1daf5fc4e2b0586387994f7c66b808d87b892092ca9358188b703240774a48c6e8f684081020815f76aca720bcf32f95726d585bf860c43b791289afa93bebc04914ce63c19d036b89a5a2d35d66a2d9266e34993d7488b4d9626a6a8a7ea74b676511255c454557368d970e619d016bdc291e77f0eb567eb61e23c4780560fcf37abf403d5828af41497bab8d435915b0bace572444d0b14062b5a1b3b48c41b069d76e62e34f72bfdfa7d56a04b8d5dafb7e2c8cff46ed58eb8f571c361a14d4d7514a214ae88e70482b3d0dad035021e36a105251c60ec6180a0af222474a8fe32eaf539ee7d535f750a0a272facb7ba3b4a228f071ecf07e3e593b5501ff72d7b1b5bb0796678fbda00316fa98af2fb09cae3f8f1c73136b048b7bfef6cd3ced8dffc5bfdcfa592e6aad35d50b9efaaa3f66e1b53b001f00bce3ba15a66ffd1ece7deb70a973cf3d974f7c6d0fdf35953075de8bf8f4d52f02a077f823fcd3475f5c2df7de5b1738f283170070fef3dfc1c28bb603c300c064f7f10b57cff199bfbf20ecebc61cb461bc3976efd9c0a225433590086325d646c48902a14376189224c614866e671e6933e4f416d2661be704b1f0797601a4cd16db779dc1c2c202799ea3842469b5298ce1c891234c4f4f93a60d4ec6712dcd81ef87c28b95e922238a63709e1e37524929f3c8e2e23271e4b535f2ac4781f08eb882c25ae224c639cfba152947a41cda646c9dd946abd5e0e07d7b71a6a0c0d21b7867df07549642f7694d4c620df4fa1de60e1f64c7ae33104279781ffe9f732e340983b30229424e4a8c1d54fd72b93280f30280e532d63a64e47fdf3a8b40d5c6f4e175b6969131c3437ffcf70b8b5e54afd96cd26eb502dc55fbaaf0319dff8d5dbb073bf1f8adb0d32200c8b23d3cea519fe7cc33ef45084bbfaf700ee238e7e28baf63fffebddc7df7f310e212e6e7e799999961dbb66dc7c482f94222c4e15586ecd57a6b9479774f2116eef31a346064db62fd2d5df7ae97b3fbcad18cfb875ef05c3e74f7dddc35b78dbffc8f7fadb25c2edbc78f7df7eff1c1af7cad2ac7d6b77dac72ec1f5fffd77cd785c72bc7fe66558efd66d8f130c6c772faebf64878104fd4acb395489c94b22a973b4b452d5966ccfdc058830809810bd97fe70cce89555cf456d49dec55bf5e6dcb394b1225385354fba070386bb0c6605d8ed69a4dd333e4b9a6bbbc421cc47a06fd82cd9b6748628929b20aca5406c0c71291f3fb158eaf96195ceb9e5acfa9adf70c6df475e1aeeb470283b2a761fcb744b846ce79362b5d14f4fa198d7401eb24ede92992c8a08bc2d30fb2d618320a015aebd8361220ac5749d8e8fae572e30dd8e3db5c5dbdf0db1e6459c57856d2d41a6330786c76b7db45c529ce79ca6321048d46a30abcb4b615b390941e1256feaed69a348a11f880970d3a95ebd9a90cf857ba0ebdd483e418cdc90e581ec0fd4be805cbcae4a98133ddf1776fe129bf70039fb9f5f37ce7cc10cf6d8b237c7d618a4bb6fb5e833d9ff90d2677bfaafa7e616161643b4208f6eedd5bfd3d387484c6ceede0723efcb36fe7e9bff5cfd5773fb8b9c17b6e3cca6f3e753b476efc431a9b5f38b2adfbfef9f5b80bdfce774e9e22aad3f2de730e84248e13d2661be30485c9714e629c4158ebfba342f570d0efe09c63268a91518c905e49da38df15d56cb448cf68f986fdc2138ee01c691ca39404abfd381b9ffc7144914420d1459f7eb7c3e4cc0c080263916f6c3f74e810bd5e8fa2df63dbd6196224ad568b423b726549d3940307ee67cbcc26b4f115b54e6799275c7639cb73732c2f2d60ada5d9f42404da16443662a0b32a999f0f7c854e00a6e8b33c7f94e9cddbc3b024d026072432523882a0247867bec6cee4e953cb20c15f22a9fc3686d70da41238348292646218490cc7bca18863e91379f3fa0c711c13459e3ca09c26fc726b33ca95361cbb8e7d6dbe5d017888d845177d8c1d3b56585c8c595e6ed06e17e4b9e2c89188e9e982b3cfbe9fc9c98ff3d5affe24edf6c51c3a7488ad5bb7aebac0231967fcb45d0f028e973c7294925e2126ae4dd2ab27512f5c52b7dbfefa8dbce8cfa6f8d2adaf18d9a7d77ff60bfcbc806b3ef2dff8a11f7827fbffe36d2819f1de1f7e0ebbdffdbf79c1ae266ba9b3fec1173ecaab7f6aed72ecef5df913c72fc7fef2c779e25b3e779ca33e393b5e10006b43b4ea0ec623e1413c96d9a0965a0e80d6059d88aaf9d62f5795c6c3a02d9da7491451c8ae5459fb00270af00d61cbd07668520acabbbdbcb35df977ed5ef7cf911d6a59883221e770d2218da0d568d2eb749191c7c2f7b38c284949d394c5c545b66c99c1844923cbb22aa8291b42f33c1fa1fface3f4adb5a8488edc67e3f7db5acfe738b67fa3afcb7b6f5ab56d29ca3e04aff6eb71f1fe8c59e7fb22641cd36834989f9fa7d59ea25114b4db6d7afd4ed836abf66fdc36f22cad65f5fd5febfcac656b3d93e3ce7ff99973e5bd548771598cf38e7e9ee7a469c980e41b82ad03677d9f53abd5424609799e93240959e69ba2b32c0b15a064e4f7cbf2fe884600220400a70497704aac9b815ece210e0180abfe0be95feb179aef436ed00349f7047cca3f79da45fccebd3e5839ebacb3983ae737f9fab5af03e0892f7b17d1d98fe3f5cf1d567eaffecaff4fb338ca1b9eff5ce60b85b003e4f6cbf9bbebfe74c3bfb9f71fdec00bdf7f3b0d37e0c2e7bf95cfbe7e0895fac0e7dec78b5ff95d7c326ad2375b78ffbf7c6a64ddfff5c6abf9be3ffb5f1b3fc00d981302678312b994b426da14469375064811e06ad60b66892a93ec21c3b93e48d26832d19e2469a63829d0d68013a14727454b159e71411a27c37147584eb60bc039d0da90c4c38ae7e1fbef636a6a8a46abed613b8d06ddce0a9b364dd38f044b4b8b6c9e6e73e8f001262637218562f3f414e79ef74c4cbfcfeddfb88dac3fe009975ec6be3beec4d80293fb1e1ca504699aa26444a1351a532125f23cc7218963cff4b6b4b4c4e4f4163f0f483ff794627d4e045f481b94f002a6b274cec358e09f433b840b01aede4754c39d3a9c6fba46850480ff5c88d5491ae71c5ae7f4fa9d8a76bca4fa5e3d4e0d7fa16e1b1d431f0989c7d32200d8b16385c3877dc6e28c33faacac44582b38ebac3e478f261c3cd860e7ce01dbb77f89a3471f5565918ee5d20b043ef6f6cebfe2f8c5bcd2453261d99265657c822d4dc918af88e9d8f3b7bfce33df740bff72cb3f71712baa32b31ee6e0d92f9efaca3f62f1e7ce41cab72384e41dd77598bef5fb79d44839f6d1553976fafcf5cab192f7debac0e11f381fe7dcbae5d85fbc7a8ecffcfd638e73d40fdce43a2c46a5adf51cd61ffed21ee94ac0250ca63c25466b4c5160b5f6f01b67100427ccf832ad10a54097230a8dbe365406c067672c4119585870d2c7040264d9643cc612546786aedfeb83dcef478204e705c770fef91251445e64c4490442609da599c6686b1984417cfee8516225517144a3d1a868708d31e44657d589d2f1af2b6397627375db68a67be19e1b98bbeb3a16efbe81c5bb6f60e99e1b99bff33ae6eeb896d93dd7b074cf8dacdcf71fcceeb986f93baf63e99e1bab63f70d8cb2ca48bb3059591c42048cba503eb120237ad980c9c929ac1dd06a45cccf1e64eb96ed4c4c3631834198378376016593b3779285aa3f47651050532976650027c75e6b6bad113cace5d0af656bc1840c3ed0745250ee4e39b18bf2da074c759aa61eca13e06a13ed26d60ab27e0fddf74ac0a6c8c8b29c522cae84fc94828225cfbb1022902c0ccbfc36400d36722cdf5273402f8734f3cf9d75a00d6807c642ae61a07d20505828dcb8af724c7bedb55fe7b5eb7cd7d3ebc00a5b17f3effff15f1b3f84b1f3f9d89ffd247b7e76ed65b73ee9a7f9d2ad3fbdeeb67effaec575bf7b20e66ad03e1f140a2215073efc085d1480201211088bc24324ad36186de9753a3eb39ee56cdab299a4d924965145875936e93be750715c39b9025051c2c9f6000801d6141861280619b1922ce77d666773ac3dc2ceb37673efbe7d4cb4da2c2d2e100b4b334dd179c1ccd434e75f702128c99edbf770dffdbe4ff2f1975fc6606989bd777c83b9b93966666668b7db64593f50306b94945863180a337aa75e49855411ce09726d985b9867a23d497332ae32ebc659b0beb74960bd7fb306d98a103214e34ac6209f742a9dfaf23c5a67190c3cdb57a4924a3768b81d51f9026595a10efbac827fa8550bcaf7ab93a6616736747d1e0989c7d32200585848704eb073679f4e27a2d38910c2b1b2a2d8b973c07df7b53872a4c18e1df3dc7f7f0f295737e2aeb28f6f8566039182887c49eab80de4d697bb840632700b6be700469c0d2bd8f3a9b7f0945fbc817ffaafcff2e4a9b8face1647f8fadc04176ff76237777eee6d4c9ef18acac939adcab1df447bb01fc46f7a13b01bbbf12a5fcb0f7871e5005a9cce29b201c6e44807911494bc76ceb9aa2a658c09fd2a022924712b258a6344a4b00e5ffa760ea4445a81701eb36dfda81c9a29479d66c17002f4d386f1eaae4177c00a8174026bfcaefb757d365f5b9fe19191f27024637dc3b0f3f7be292c4591b179e74e3039466be616174008a2240982518666b3894290657d5f964fd380f3ad072776649218f610e0f7bc460f2c84f465ecc26285772a55d039d0d6600a479c7a954ceb023c0981541e36e5044489425b83cead77fe238588224a8c73afdf67727292f6648b763b6179e108fdc579ee5f3a40abd586286666d316a2c929d09aac9ff9332b22ac90c4494cbf3f204a125aad89403e2089025547d1ebe330584350c6f599f0b2745eb2adf8f8cf576944080eb1b6d6ea579ebf104c9695252946a7cc910c5b89edb5086771ba006740068e6e6189a5dfcf4623423bcb20cfc01a54120701a304ad35cd3406674922852932d25811073ef6348a91d2078071d3c38374e69fed344dc9f21c61e164f57f4e79c05f04ce49533af92638fc3afc6d7d505058c84f05b3cc23c72c8122d889802397081c49e21b4297f39c326d51399185ad028756ab413fcfe8f53a080553768ab89112a9844879a84b1cc738278823cf8b6facf1cfbf3839e7bfb446a341afbbc4e12387d83a33c9ce6d5be9f506dc7def5e908e3ceb93e91e69a468a42958cda3ce3d0b8460dfdebd1e0e87c3ea8266b3c9dedb6ec718437765891d5bb73118f4e8169e84218e22b26c80d39666b34156785d0e2705524635bd159f60595c5c4420891b4da2381e71ba95f46eb7d185a7250d827ee5b92f455b4ba75d2935ac12e0935885d114454196f9fd88543242f95c561c7c357a48cea0548a8a0473737315fb1d501befcafd2caffb03ab0a7ebb02f010b13c972489c518c1e262c2d6ad194a39f6ef6fd16a1966660a969662e6e636d16c4eac92b35ed3baf819b110a113588680be9cf5ca54f430ff19c8aa7d0770e146081dfee4e917f3bba11c7bf6d967fb72ecd5afc539c7a53ffe6ea2b31ecbebaf7c5ab5fcbfdf7823adfc28bff8c2e7315f482933595a0000200049444154df98b4fd323e79f507465848c6adfed9f1cbb14fe36fbf85e5d86f963d980fe243420958841467c8100b3ca6d537df0a5f01088e9fa364fdf14e7e2425cdf6a477fca4c08452b30ef021e7348dc863840d3e0359397e1bcca63a81e7bc0f15b571934a7987122f78e7a30c438442e1d085090a9c8edee23cda7a473f8e63f2a2a0d3edd26ab588239f6dd74165d8594bb7dba5d94c190f56fc691bcd4cd5bf1fbe372432414bdf8c56c2779c7348e571e7c61665d4e3d7c57a7c2bce4f9e2af28198c43bfd4279f88bf63d0d5b366f26cbfa2c1c39e0d537b52651d62b36db8c625070e8600f0e4aa224666a6633ad994de014d920c39a02a5867879213cab4e9c34303a67a2d942124104ce255573b2b1459519ad1ff32a3850edb46de49abbf2762c8748144819a066111887b17ad8a3a27c00e0a4078b2114fee01d564ab2c06245d9632004c65a8ac257825aad962ffd5b707ad8cb2254442a257961824aacc77b9fac9dca807f609b4347bf30b500c0acfa6cd03b31a7f25890b0070a173b9dac74f810d257a39c67e38aa298767b129d1bf2620085f14894402ae0acf1d5f722f7fd4a6806fd2e46e7c4498346bbe585fb541444edbce35ae9a60839ce4efa80ccc7d91ee7aff38cee8a40b81649a438e7ccddcc2ecc231d5cf4f88b410974af4b9448eebce5165aad16f373f32469935845a471e22b1b914509c1c4448b6e77c557cbc2bc91249e555085b1d22310fc782785f46396d5c4519346b38992118d76ab72dc2b675b953977af5934c87af4fa3dacb50c3255c173eace7fa3d1a0d16820a524cf73b22ca3d036243304cd669366b3393266d7ab0530d40929df7b3890461b4da4a25abf58d9af7472d7e7c14e3c7e2becb408000e1d6ab3736797a2f0f08266d3849bc3a1b524cb24792ed9bfff096cdedc64cb962dc7dda6d3051416eb24d64a8c103829c2ac367ee7f8f295b50eeb04565bd016618665f8d75e73eb4839b6ee742cf7fbab30cace395ce3b1fceb755f468851d691f506ee7136930b5ff7377ce375233f5acde55b2e7f0d5fbce535a34751db87535d8efd66da23e141048e39a3386b714657b8ffd27173cee113bc43584879ef4551449234aacfacb118461bb6949481bda7f65ba70046312ccd0e85a12a0a4f5b3b505172c61bac33f40705c67a568c38564491071769adc9b2210564511458bd9a21a8de885a7fa6d6dabfd1e3b5a18ae028e1e4259ebfbe9ccf8e87bf85af080eb201511c23634f69aa8b0c9c77d85b8d142921cbfb7496963c256a1411c70ae7acc7bd372690d652149ac14a4e9169d2a58e77f48d21895b4c6fda0cda60f38cbcf018f8a2ef33101903841c364e0b2190ca438f7c264d8f9c176b47830059bff863a74b08df4b02c3cb569e267f0e0483c0daa38d252242481ff409e5202ae80ff2702d1c9e1508c0e184af50e5f9a0827729a5502202e10330e9048e08eb2cc69a0ad72ba58724202551922023af14bc1ee3d346ed5406fcdbce3c97cfffa325d6e9101b5d3e6bf5f7d67f57a8299ef4cc734fc96f3f224c065a63bc035bce7e02451c274c4f4fb3b46cc9f21ea55308c379b0dfef1125b177568d262b72f23cf78ad26a915d679c890834bf5e4c51214335ab82b99f84392c453ea0c806b4da0df2c180b9d92e4992b0f38c5d6cdeb209272407f6dd8bc3b2b2b408ce2043d0d04a1ba4ad06b6d0341a4d1616169044f4b2ac4a904c4eb489a5efa33279e155e28521eb65442120a0d43d712e044f6dda9353341b2d2a4100a8fc149c57231ef47a0cb29e67e292b2a22d2f1d73a554c5e4e6c76f4fef5bfe4d60074b929446a3518de5253c5a4aaae7bd3eb66b5d844488406b5dfdbeac14a34f4df0fbed0ac043c40e1d7a2a797e13175cb0485148fa7d459a5ab4961485e0e8d1067bf79ecfd4d493d8b163c78602809ccd2c0d9688840d2457a1ac5751508dde4cd6199fc1c4a18d21338ec5fefae261a583369e61ab3bf92566cdc312c2645c633eb1c771c44ea621f074b247c283783cb3d6a20b8331ba16a44a9cb02043a354c8ca5ae77042fab26e925084a6ca2a632b05518d654767fa84b0c7e3b666e6dd954e6660cba9c1720475788a4345826c9051584392f8f2fb6030208e639a136da228626169d1c360a28848f8de1929047194e0998cec2a8d80725f2aace8d87d5f2e5baa7e8a00317101436a42263d4e86cda661c5e1fa4291249ec6d269034a86c6b428b054441c387000a74b8c7282744143249c8f225fa2d168912631d89c7eb7c3a0db23491a8838a1d3cdd8b26933ba284884a29f7599dab4855e6f401c2b0a3d5412ae374f97ac39793e3c37f5327e790c7592d811a2840d8e1371da4426094429bae8a3b5019b83f5d526448495c2f7444917faaf82a36e2d226af889dd398cf1f956a522a48a4912c872cf4022543c72df68c0194bd61f604ce1a970938d093a7e2bec8ae7bf942b9effd2077b371eb6e66179811440f8ae13172aa520491b4d585aa2301e9ae754a932eed76f36d3aab9d598c2f7ae388bd13979dfa0640959f195d37a705c584ba2e4495501a4f04eb33106111486e344d1ed76397cf00083bc204a6206fd0c5de46cd9b499eeca024a4a06833ead668b4ea74b9aa61c3d7a944d9ba67df3eec44470ac63fafd3e7d6303538e57d75691a0d56a33c872642a512ac2585fd96834db4c4ecf90b6da9409a572eca863f3b5d12c2f2f93659ebd2d8e639a8d069393935e23216450b22cab204279a6ab403f8ed2d02f25aa7112fcb8e85c09bd1ac20c81116ae052fccb847e8d288a1021e01062350de8e8bc50ea481cbbe2f648483c9e1601c0d4d47773e448c460f065daed1e8381248a1c8b8b31478e34397cf812b66e7d16e79efb1876eddab52155df8b5efed553ba8f6b4e966393edb813523e0c7ed1a10a69995a18676f3f511bef8a3fdee70f557be42901afb6326be29c1dd3ac9020adcfe283a7e09102578a63491f08b8da04269c6f4c77d660308893554f5ac3ea4180b1a6c29d0b219081f359baba9aac77909d3308244529b217aa67cdb44143a5743a1d72e331ad4a44144556894b8d435bca7f7515dbf1e5fc4410cacdd267a93da39143c8c0a2445295a4cb6aa03f8f7e6a4ae2862fe36b4d9c26341a294a097a9d253a9d0e2b2b2ba47112d480054e7bc88ab39eb3d51a439ef5515a219da49d260815fbeb26251405d215244993bceb337fa6c851c23bc0691c633055c2c23913d494cd48554088510efd72792b4627c7f23cc9b164415d30aedc8c4192e59a3869808888e286a73575b1c7bddb021384e28c28b37460f0586c611d49dac23a8d2e7ca0a28d77eccafd36b6c4ff4a44356997a27090a631149ea9254e8694970f773bd6f87dba8ced276352c86a4c0ba0470f42ac84ac607a7a86484afadd8e0ff495240ab4c85124b1ce3b9c7eec1952ee4652317bf830d39b3611274d2215556ad5fa1425d1acf390963376ef66ffdebb9002f2c18076b3892e32afc6ee2c9192341b932c2e2e92c6b262cb024862afbdd16e3518f4fb341b0db26c40a3e183ea288a908a914a693926aa24c60647b83f183031d566e7196780a8fb4ffe9895925525510ac7c1fd07fcb8dc6cb163c74e1acde6f0b88c274a975292a60d922425cff32a10004114c5c4694c1cc75e115c0cc5154bcd81b51011c618badd6e980b1d4912d7485f083a21a3eacd6b995f7eb4ba5b7f05d8bb77dfc33ef1785a04004f78c2e51c3d7a26870f3f91bd7bbfcedcdc3cc6c0d4d424679c7121975df678b66e3d83898989532a057db236da153feafcd7b392ced596fd260cdca763d6bf6e0f7605e0c156020689710e6d2d4ac80a9ee22a96359f4ff5f49b41a44a189fb5aa413fa01cf8fcbd503ac6728cd06e78af8c62c74fd4cadff2147c43a0890cec3932a8bf5a6b68361b8848d159e922859f80a510749696b1d6323d3dcdc4c41449e2552c8ba2f00d7915d673d828563f86d14a5b0d7e571bf04b2a3c1d32fe4ef8ed442a5ab56c7d1b00d2493acb5de2346172b2499c28b4ce59e974e97696190c7a7efb7807d76b2ea8caa1b5d6d26894501ddf93e19c42383018ac9028a958595c6472679b221f303135c3d2f232ed769bfe60e08938e468d6ab2cc33be768341a21b9303afe94c1d778f967bc4270cc6b0c44518252099b376fa69dc60865fdcd8905ad210e4eb928b9fa03fcc5fa2a08a540d07807c9f89838de2cef2f80c7341599df1b15d337ab17dba87db302fec120e7ce3befe7e0c1b99a5aa965d7aecd5c70c159341a0f7d3286d3c97cabbebf379b8d164278d6295364e01c32f2f87b8967f52b83792900e71300bdce8aef3d4a52446895b74024c4c93700508e51559a3b8c8516acf139066b29b21ce704da655e611d49a222a4f063ea3031e41b709552685dd0eff749d3b4aa788c3fc7be7ae2104aa28d43a898c2688cf5ec3e52c59508571d9de0cf8008f01ec7cccc6692a40958746e881215124e1a67a56705138ab411a1644a9a0e30da2757e2241ae1ec5f0fba391e0cc4714c932683c160c4df1b2e53562ecacfd71fc3d6838d0af1c8a01f3f2d028089890926262678d4a31e0dfc60f5f943dda9adf0a863bbb9165eb97ab5d667b99cc7259f2ab9f1d3390878d82b018fdf1fd53b3fe0ba1a9b821f9c4ae80608240617446c04910a999422f4045846ee3344107111c2c3dc70353f6b744736ea048eadb40af626a59f084c751ca3816f39b148a9403822e5830529f1985721e975bb082769b7db34d316a6e8f8e6afa814395b3dc195aff5417dad2a403db36f8330dab08761f81c8b11077478ae9452b41a4d1a134d3019fd5e4636e81029c7ccf4245936408506686b1c42444892327af33a07ca6397859058535018838a23a22821cf0bba9d65da2b132449041812e5b1f451ac284c516b822ccf7fa0e974604393ad10aaaa327ae8b9c006aa4e5b3b7f226cabf4a32b1ad6d14281bfb6406fd0234d6396979719489026c319ed9547ad19f62284e3556533a5d515c567095b3a96d8581de255bf9ec6781ef84829a48848b76e5e7d5f9e809dea80bfdfcff8ea57f7d06ca65c71c5e3c23deb9b9cefbefb105ffdea37b8ecb2c78466f66fdb462ddc158067f25aab902995a2d16e112711c2593a26c7594b2c3c1b9911b5f1afb60d210479a9b5622d36309eb900b754e2e4a1661eb2e4d9b844a4b0590da687218a947f7e90148526929e023716501486acdff70c59c1d12f7b608490153b1a08ac08418ef0d4d0d5f82c860992b2d9d9432bfd78edca7695fa79750e5b6884752819238577218b4c5314a1e2a8f04ac1aa365e3a49147b31c0ea235194234b2088a88fc754ef5d6d6cf35585943851a1c2a12a4ae8b57c1c21d6f2138795e7e172ab838e7bee79f8438f4f8b00e074755c55549e5e33ea8431bce17cd6ce4f62752aad2449b0cea1d468d6b23e398e573bc67fa32ea9bd5639ed74b107bb02f0e09ac4b912de210203852f777bf80643c75a7a1e7e84f00d72ae6cec8a2a4ab67a4668784fa991fb62f8fe813706d48300ef70faec96d67ad874ea042638f1bd5e0fa5639cf3a5db7ebf8f884598c8fc7ddfed76e9743ab4db934c4d4d31180c585898236dc4805d756fd73357e34140fd59298ac2978e2bf88bdf4ed9c0564e72ac31c138e798986c511419cb07e7c9b23ecee41851a000ab33ac31a838268e222436608e3d75a9b58624f5c72d91a02451240355bc21cb0728e9952e9797979839fb6c7ab3f3345a13f47a7daf9d90c4d80089f1936879bcb262ddf093a71bab12e045e0d4dac1def1aa92217f49234d89232fb8a44d812872241a2521960217f219a2bc1e0421200756422ca32ab015b8a16010c3fb07ca0ad750a3c2594fddea5c28fd23e967034ec68d3ed501bf738ebbeeba9f388e38efbc5ddc75d7fdecdd7b086b2ddbb64df0d8c73e9abbee3ac09d77decf25973cfab41c9f1f1c1b6df62e03f6fa88e59bdda5ef794a2569d367c6333422240d4439ae865789f03a2a389a694c1229df1b64c13883d3e1fa288d100fdc7daaa7f784905effa4dff3442315e65e22b406e99b5d9346c3eb12441ef257e2e0a3405b5c2aa903953ec9b8d57d81288a302e8ccf42323131e11df524c5e27ba2ca6d597c9f82b5867ebf4b9ee7ec3e6b7745451cc709714c9517915281234011ddc8b8ebbf07a1ca1164edfdab7f56f77fa49448229acd66200388aaf9a6eed4af8506f1dbb1eb7e5f5feedb158087980de6e6181c3d4a7bc70ee2a9a993277dfe165a7d821d872758ababcef77219adb52f630ab1ee8dbad6643d9aad7d784c260ff707d1393f90bb35aa3d0eefb44db427aa4f3ced4f73089118b93fcaead1b0a1dd150542c88a0e72b8a41f08b51d85ccf87d5aeb7e1adab082202bfa465b14a03c0d651a47e83c474a1fdc96f964a51458ff19cedfdb06878c25ce1428e1c8fb3d14a0f30c2b205231d6faa63ca522f27c4096f589a2884d9b369117033c2398ae9ea912035abe2ffb82ca09b2cc363be790a1794cbb927dc28f2b324cae45ee8397780c1264ad0fd61b8d26fdce0a45d6076bb0a6402a3f3c158577beb10ea57cd95e1b4892186d1ddd6e0715353c2421d0ea994263f1bf1d4509d6181acd84d9857966f44e926683419ee1970acacf2e801e44a8fc5066bfa091a495e060a14dc5d8912609c44df2ac87094dd436684ad47b0754802a091839bf5208a2588580d41249efe43b5720844189a812abf3ed0ec2ab430b89b0be4741581b3285a119d9117ea776af612b67c7c3b564804bf827c6c5093a3780218d1f5a509a3c2fd8bfff288f7ffc79ecd9730f070f2ef29ce73c99388ef8c217beca0d37dccce31f7f21b7ddb68fc73ce62cd2f4a1b5ffa79bd55dca10265600c72849489b0d0a93a34d810a1a20ae64fe2a8753e1038991c4991444a890b13f79aa59f001801fdf25cdd604fd9525840b94a3ce91e7b967b88982e32c3d2d71c9b6d36834e8f5fb1441345186312dcb32babd9ec7fd0bdffb43495d3a469599e705699c6251cccc6caec22a8ff5172148f1550a191cf1c16080750615099cf32acbe503ebecb08ae109094455e9f4dfbb40516c91a58860b0f17e48e786e3c06810e03ff3630115f9f488e72386eaeaa52eccd046133965a2a75caf1cfb1e0989c7870e607e0356743adcf5977fc91deffe03eefff4a7e9dd71c710e8f550b69a7335da94274229b8a826b8d229298a622c6b3b5a0e87511cef38ace881e2b61f8a76f7dd773fa007707676b66a967aa076db6db755b8e007cb8aa2a0280c459e53e439a630e85ca333edffce738a22a728344591fbeff2bcfab7d6bdb12e046d8dcf8e67f5fb7423360ec7a9dfdbe5f351b2d9c45255835455b615434548eb34d3d393002449526d2b49128c3115febd7e6ce3cf531d7a52fe46392978360d2f6e53560a1a8d064992b069db36da53131c39741fd66906bd1ebdee0aed76933489d159ced4c404ed6613e9a89438add568ed83a389c916c669f23ca79ff94662192992c4b35a3867284cc1d2ca22512c999f3d8c8a254847a3dd80c0ad7facb160143e36ac6ee45946d1ef574e856fc84b2a2c71fd9cd7cf4795d12b9b74750e4581b086c8f926c1080fed570252a5889524520ee52cce6a7096580a9a49ecbf8f14b1104801caf90675b4c6e802692d525822c0d902b4c69a1c610c58472446c7d387921963190c72d25471f7dd07b9f4d2c7303d3d41abd5e059cfba94438716c9f33e8341863127beeffbaefa537ee81997f2f8275eca131f7f09173ff9b9bcf9fdff7e52fb2c8460eb257f38f2d9fb2edd764aaa13a7b4c2614de9e57bab43795cc8322343255c12c709cd89368df604421d3bfb2b805ea74b776589acb3820e4c6a028712be2a3b5e853851730e9f690f3cf84aa9a0a5313c47524678d13f3f9e5924dafa67b008d8fff10abfa77f4e568dc7f571d70ad0d6544c8369b34194a69e12349c83554727446806f690a183070fd21f7443554e7be56561914aa1e2d0b02f3dc981b505466b0f6d8a63a2385e356fac3527ac659e3462fdc4541d4658ffac3eaf9415927ebfcff2f2320b0b0bcccfcfb3b4b444b7dba5dfef3fec138f709a55001a9b37a322c5913fff2847fff9b3e89f7b03679f7d36323df1a2efb9e79ecbf9e79fcf339ef10c2627274fc879595959e1eaabafe6ce3bef1c51e63dce8aabb6c3311c756b2d2a1a7594eab6d67a0f27a7bf6e0ff683f86037015b5ce05ef7b39d0d654cdfb826bc10702df525ecd88c386665a1dc5643fcc684e7d6ddbfb2c9d67a99f8d550345715a3ead8faeab5ccd6b87ae65ae06c59c470c812438f6f9e2d335a5a3b969797999a9e666579b9d208288a82a9a9293a9dce083f753d935465f29dcfe6bbb21252dfd73079cccfcfd34853fa832ea2d1a4d56a71e4c0fd1eca622db3f34769263113ed162b4b4b2449cce4c4049de50e8d46035d1428e9b3ee260a9a0c36f3d87b15d84b02a5a1c067ad2c0e6705499a90e505533353cccdcd3135bdb9dabfa2c88995aa989cfc218d9efbe1045b364c7ba620ad35563b62910e9d03bcbab1730e1198a46c79cef0d9d1b2fa639da3309a584990824840247c5653503afac637fd0915203c8420c2e294eff9b0d6547b5c02b022e121020a81ef03099946e7bc23e13438895471d05d088ecd4966674f7513b07384a6cc1e2b2b5dce3a6b47f5ddc4448b3c2fc8f38ca2d09ce8f03d77f31f72d94ffc2b7ffba52ff29c0ba601e8dcff15def7ce2f01cf3ea9fd7ec9e2eff395ce2ff1a48998a2fb9fbc7df625c0e9211c09219b1f12d3bedfc50b64359a4db43114451f3d182085efbd191fe7cac0b7dfef33c87d503e313d45b3d54288b22be6e4cc0930ce120957896d9550382925ce421c4714c611253145967b4d91cc5715b5f6c99d2449c2df9e64404aafffd2e9f7aaedf96772b4c2abb5e7e077ceb169d326a0640bf254c823d59430869741b69492c1a047afe7838d28564489026770ceab13f77a5db2ac4f5178b8631c7b7ae4346da22239424ab0e6353cc6d71bf7d7a08e8428d115368848963a02652375255e2825870e1df97605e0a16226cb58b8ed36ba7bbe811df4b0470e71e48b5f60e9d65b3df4e0046d767696abaeba8a6eb7cbeeddbb39e79c7336f46ff7eedd74bb5daebaea2a6667678ffd231bb849955255f6ade4ed2e3f2b1be3c623e3f532fce338e7878b3d981580878212b09412a1244246c189f383bc101eb33a7ecd8f771f38c1aa86b96355074ed4d6dbc64683d972f2b5d662b5a99a529d7321c8f0909332933e180c387ae40893d3d395b3df6ab5989f9faffe2e7fbfaeb35166b44bec6c1d635a3e7b4a795eeecd9b37a39462fbf6ed4c4c4c70f4e8518c311c3a748841d66172b289543018f469a62958c7d2e28a67e5c80cd6d4ce8d31202cc219749e8dc05b62a9aaaaa0d3c653f849451c54494d5eb0bcbc449224e4a1ba835dfb7a959f95c706439d00a9c2710a4931c82ab8415d4c6bbc5a59cfa2958e40d95f80b5586370c6078136507c2a5ca87016152c20967e4cf3e7dec3176c6040a9e3ff851015ecc0c3332ccef8ebee614a21cbeb3c3b96129253e19a5d71c51527bd8dd25cd1c5f58fd05fb80f95cf62ba47d09dc3d5bf58cfa33b077183c3d86ce984b6fd272ffb7d5efe4f1fab9c7f8089339fc45bfff857aabfd7c25303dcfa474fe3e2375c5b7dde3bf209dadb7fb472f87ee5372fe257ffea6e00eef99b5fe271bff5cb23db191cfd775e7cc563b9e40997f0d82b5ecc17670723bff1f977fc144f7fca9339f78cc7f01bff702f00fff843cf02e0d24b2fe5d24b2f05e08e8ffc1c575cf19d5cf6c42770e1e3bf9bbff8da7cb59dee817fe6ca8bcfe692cbafe047dffca963cf6965837e70fc11351618449535f62261295194f844c2980be45c5952704cb49b2801f9a0c7caf222bd958ecf72434d23e0819b0264a0640630d607fc4e78a84e9ee7a149bef0445956a344092754b4db938848a1b5453b5ff554494c51142cae2c8f64d7c7c7078bc318479a36b1481aad49acf50dc0c61ae4b0852bac506e876a8c889564797181b9a387bcb0aad3ccce1e65dfbe7b3870603fcbcb0bf4fb7d9c33b45a2d6666a668b527515184d11a291425638fb363eae463d7645515d38571a976fdead5cab21faa3e2496e355afd7a3d3e954d4cd4a29d2464cb391102981b31a5d640f7ae2f15b61a74505a0bb7f3f87aefe12f77fea53e89b6e42161aab6256aebb8edb7ffff738f3a53fc6b6673c93c68eedc70e1b6b56f2e25e73cd352449b221ed00f065fc6baeb906186d2279fb2b7e808f7df13af6ec5f1c3e68615f7ef5c79ec7e7fef3004943a2d3b3f9edffe763fce845332004cbdff8242f79d9db98534de21d4fe1939f7a0fe734bc7357f6009476a2d08c878b3ddc1fc47167bc9ec32cdb269d337ef42dff31cc6b38affe05c1711a964703c6bd9aac86ac5496da407b92a889b51cfb11f88958bdfcc864149881a84d00a5f367c2f72264b6fd763dfda62364ee9d9f100f1d38c0ceddbb694f4e72e8c081aab25736c3d5cbc3f50045d880375512217c53be77461d5658a25852e88c2d67edc6763a2c2e2e208463696591ad5bb730e82f914451a806c880c597a0226299206bd0be5eafe7a149ad94388e29ac43171a6d2c4e49bfac10c828f213a41364bd3e324e18747ba471c2f2e2329b77eea6e8f66836dab8dc8c9e62378a717588ca81f6b78640e0d9429c1458e3bf17d685ec63384f7208ab1142a0831a6f155c460a290585b144467bed06e961058a21b38f71dabb541650202345643d5fb831a612051ade3301bded4a95e8b279d967f84b0749281f8c34a2181190de853d090e504e6dc0bf72eff5cc7fede35c182fa2ee6d70f9748fa3377c6d64992bb6ced13ef2152e4a33e6aebe0e2e7d2593e73c7543dbffc0de256e7cc2f1452fd7b20b5ffb616677fd088b7f740b3391e0da37fe364f79e767aafbe8bc57fc11b73cf67df0331fe47dbf7d0beffdfa793cb9a63aff81e7bd94f44d5773cbcb2ee41b7ffd329e7ee5ffe4e8cd6faabefff4e37e9d6bde7a014b777e889ddff9d3bcfd45ffca0ffde31741086ebef9e66ab9b37ee077b8f135db0058daf357ec7ed67fe755073f02c0fb9ff74acef89d1bf8b7979ccf1d7ff793fcddc811c8a1efeee41a634c8d5d1688554239d035d2368d1d4df6deb5c73bf2a16f4738504aa04295cab39039925822b4a3d7eb80924c4e091a698df7beac80d668b25cd9d3c210a35ef7a88500e520921178493bb6ef3a83cef202bdee1245a669b57cd3af1206a70734e3c89306443e11941b4d94a4082b91028cf3cae471daace6140f93f4e3810a4904e71c566b1acd36b976ecda7526046ae6bcc889a374e4189cb5be17aa2850129c08ec74454e430a5c31e0c881fb70d2975ce24461ad26499a4c4e4e93260d3f273939acf2124982c8840000200049444154e3f9c5ac7793c46820360ee119fd5b21c46a0e7f70b5648fff95913b263008a5690a5866e7e7303a6730e8d148128cf68266a6d04451f488e801382d0280affeeaaf50fce7cd7064d6df432228f6f5fbf4ffed2aeeb8f966ee7bca5378cc6b5fc7e6eff80e64a3b1e16d5f7ffdf5ecdfbfbf0a088e675a6bf6eddb57bd2fedd9affe355efe9e2771dece8955eb7cc7ab7f9f3ff8becb89041cf8d2db39ff59afe6478f7c1a84e0179ffb3aaefccc1dbce549dbb8ffdfdeca95bf743db77ff8d9c1191adec06546f4e194d9dfa83d121ec46399771e0560423325205c707a6cd5b056de2feb67ddfdab2dcbbb65c500516578c66d3d68d0f8fe95cb96416fbd1a51b2ebacd76fe0933b16e9c6b2ce08847314657f8c079684f54b0e0dcfe3dfeff769b7db1c39789056abc5ce33cf64797e7ea49a50b1c98c714747519814cb78a8cc22858cf5c464cb635eefba0b807c90d1e974d83c33833539ad464cafdf61a2d5f674980b2b2449c2547b92959515cf932f254e09a2d0c3102901c2e24c41bb3545916b8cd128a92a711b53180aa38360564c9e6524498bbc306005b6b0a8a640d78ee558d7c71f5b9d19a46c888e708c064565b6be0c9a009c3655a37559b52cafab8c63441413498536da37fb052f244a62726d3c76b9a4fc94be39512aaf71619c6764b1c237335be15042797f411bacf019532bf08d92928a9dc96a8d942e04c20f9d1e8083b75dcb8e4b62ced9053087f7007b23cbec02a0ef2b467b563878dbb51b0e00e60acbd6789889fe85675dc1d54b19870e1de2d0a143c75c376a3d8e0f3eb3cbcf5e753f9f784ecc6b3fbdc2fff727e755dfc7134fe2d7373d8fbfb8ed0afe66fa2d7c60623441f6ae5be6b9e525170070c14bdec7fc2b2f028601c07b5f743e00d3e7ff0cd9e22facbb1fcb77fdbfbcf4a51fe4ee054da404bd23b7033e0078cf3716b9f5858f06e0bc1ffa1fc05f8ead1deeeb0d4f89a34e66ab35812efa18a3114aa29c0082805e801c4a2442c45520ac33dfa44f5ab2870d2b8cc6852a96f4cac4c7ac110454a4d5c6436182ca5eae35da38549cf84cbc124819a3a4443a3045e873b17e7c2cc7f2ba95632ed62195af8c217d906fadafa23927c80acbf4cc8c17f143e2ecf0990fc0d340cfa991320a6c41c3aa42334db0a6c0e82254a8951fff8dafb64c4e4e06dae2b2f20952f9632f214f0f1c8422bd7a736d7caaa324eae3fd7aeb4f4f4f634c41dced2011f48a0ca3739c31c8483eec138f709a0400c517be0085c6a6b1cf06153946298f4d6d244473730c3eff2fdc7ef808e7bee10decfadeef451d2708b80968e34f80dcb76f4c5d757db3ce37c76860bee6183dfd7b9eb9ee3a3ffefd9787cc2decbce2a7c816df5b7df7a9a37d8e3c712b38c7eee7fc06f7bef425f0e1e7e09ce58e3ffb797ef24fbf4a3e18d0359b78f347ff9a573e61cbc88d0ea7b8b1ea949b5d3343535a19e68cbf56ebf2f0af001ccf4ac5cb32b3ef89404b456059573c01c0896103275039b6e3563fd76b39fa277a5f9501c02864645856afff869fc4a8603735b6799cf5b933afd2e9704643a0e3f33d06a1ea214148c760d0677a7a9a4ea7439665d5e03f353dcdc2fc3c8d923eaf9619afb2ff613ffd290c67c439949424b167cb69b69a1c397c98a228e8f57a2471c4e62d9b18747b44cad1cfbb6cde3449d6cbe9747b4c4f4e52e496b9a3f3349b4dcf50231d51eaf1b22a54f68cf1cdff91908828c25ae9e14ec6a2adcf484a04adb441ae3de735ce31333d8de9f55142a2331dbc6281aba850abda50e5c897419373259e3734525b812c27fb1a4cc00a51354afa4cbfac14372d0e6408c6ac7fbe23eb7ca786102014ce792d0300a1144815f4bfbcd2af73be99524849a143563f008f9d5048151c7ce9c8b545227d352830474925b0f88644991b9cf494a0753d8307db96bb8eaddd3db07c3ca828b0d0c77c7d81e5f4191bdefe8bb736f9f3831d5e77864f3abdff8b3702a3cfad1262182adbd1e0e37b3ff8465ef3ecf773efbb6e83e77e884735465dd61f7bcf7378dc0bdec0f33fb49a04c18c9ce7615f4f69ad0adfad706e351d65750ccfff797efa8bf7f2ea4b77608b23a864c7bacb9e6a9b9e9e6469b1406703a49244c28bf8954dae55d24de199b08c25cb328a2c83f68477ca25d44ba865a2426e242a11a59bedcfa0547180782a94720c8a02e11c0a9f3937be4c59b1fde4458610011e27429d41e0a94dc5906a3396d2cf01c6a29d259202a512720b131353a8a411a0771029ef121a6791888a1d074049c8730d66c808e6a13b1e536a8dab02fcffc3de9bc7cd769575bedf35eca1ea1dce94990c40208110304033883678191c8822484bf7056db115088adc46519c1a954edfcf87ee7ba1d596161a7016af800c8222d00eada8d092800c8184240442264ece39ef50557b58c3fd63adb56b57bdf5bee73d03494e4e9ecf794fd5ae3dadbdf7da6b3dc3eff93d655150f4aa7277ce21ef778dd2385ed9edbca595462b89883976a6a9c0794ca4ac3e1d1c8fa7440e80b38e7669803496acaa41088cd6a8a641b5063b1c009ee6da6bf8caeffd0eebd75f7fd46306950332200772ef29bca7dce6aff09edc7bf2b88f82a363fcbbb958825020141f7bfd0b79d0b3de109691fcc0b94bfce2876e01a1f8d2077f917afdef8030315ef8ddbfc2c73ffe8f5cfbe94ff18977bf94575ef9f3339ed5798c6e5fd2842f44c0ca866a78c1bb1106acddfc9da82c3eee1465197c90d685cfe4d7753e0c40de055ce1bd9903706f88ec7d7651ee1e44c21212561dbef388779f3e2478a6b2eda986c0f4b38717ef29c1dbc96e06531f61256107df413344ea9f10309bf12f89c5617133ac0dc97bd3c4e4acaa6db618ba225e8b88099fc3c12078daa56265253002dd7df7dd1c3e74887de79c138a870d06c1631d955a87c7457610e3c1f8292385568a7290b3bab2c270df1e6ebde516daaa02efd8b33460906734d5264a060fbef070e44880fe0d0683807bc5b1b432a46a6ab22cd08cd6758d89947d4dd3800b557ad7d6d668db061ddd63d578c26434c639d7b5bb6d5bb4d61863d8b77f3f4dd33018041882178e69d9aefe73d90a19ecc3a042e1b104778acaba4c93f5b49fb4558df79e42679465499185a4c3b66e988cc6ac1dfa3a1b87ef663c5aa3692aac6b31f15e3ae80cb23ccf298b823ce665a4b6240866ca77eaf78369d473ae1f7a39a523cd74c7ec71a2723259bf36461eb3368623d5f67f872bf8ca11b8ee2ecce19a8dd1ee0d98ab7fe345fcc277bd926bef982a1ade1c9ad9e6e97b0bde7a63c82db8e9033f35b36ee58257f022f39bbcf0251fe1d5bffe8c2dc73fefdbfe1bbf74d52ff1eb4f3b6fcbba9fbbfc00af7a6f8888ddf89e57b1fff29fdd559bcfc814b737d3b9e5abb5e52117841c866bdef6d2996d5f75c95e7efa835f06e0e60ffcf4ae8e7f2c520c8748a53029f95ec999e817440785b73162e5b1a6a19e8ca9c62364c418a56abcc287dc002976df0fa5d41d7c4d69cd60b84c5614c1d055194269bc50580fc6792c022f155e2a2481025808d17daa48efa945705ea868d8276288f47b99672c2fad520e8740a8821eb2f42536de8f346e04f89d8bb58a26586710c2d334062f42844feb40916cad4517397bf7eec5e3b1cee32255a8088a4880029e043bbd9f8b94f2b98e858dce3a0b4894d2e445c1be7dfbd8b36f6f37ae9e0e8ec7532202607245bebe81d00a3b28112e14c770798e6c5af4fa26eda0447a4ff58f9fe0b677bc837d8f79cc8ec78cbed3ce08501c3d92981456e2bebb8d1a24b9ee1dafe2396f5de5635ff8c1eeb7fff2d7bfcb0fbdf8f93ce6970a1ef58c9720ba472259bff14f79c10bfe7b0c8fc2f8ae2f22c4ff58d8c1fbbfdda7720412f61898b7374d6ca623780e42b5c25898cadb080bbcff17e498f79e412c1013d7791f3998a59c558ae273d65a05ef503400e241c3b422028673b68c6b94a48c0b176c54e6fa11c458c3ac02d96fa5f702ad73daa642a97010a105a36a84f46dc770e37afcfb2e2a9748895230284a6cd3765e7a042825f14e236de0adb7ce75901c21226b8705a904c27932ad10ce618d23cf34451e68e60e7eed6be4c580d5b3ce62e32b5f212b0bdab6461739ce81718e422bcca4c579c340970c0605deb61cbaeb0e3637d6180c8a10fa6f267862fe906d30b1be8040a0d500631c4a79b2b2603c1ee39d60ef81bd6caeafa38b5831d38408c594a35b46369886c9648cd2025dc4ba04ced29896bab5acec59a5711ea9352c0d19afdd4536188610bf8ff4a53e60fc9343203d35219377bf07cbf291abc747be7e6702fb8e922015d6b6244c6d590ca8db8671d3e0f00c8743b4ce288743eebce5cb285a4c3562ff721eabfb82ca3542cae825959836717f4b24c9c0f73827c8b23cf47525303e28334e8404490f14990e410ee743f1201b128e15824c2abc00e3e3dbb203bde36ee564b17e8d6a30eb0d643141d677ff850fe3c2468726d0584c25191d83bfe221ffea2d7cd8be9ed77ccf13b8ad0e7d3ecf5679cd1bdfd96df33f7eeba7f9f6a77e136fbee07c1ef5ec9f037e73e6183ff5fffc0baef8c94bf9f10bb64257657616af7ef5ab179efb151f7e172ffa9ee7f0e8ab35667809effac82b76d5e6df7cc9d379e2e58fe1c050f3a94f7d8af7bdf1253ceff2cbd87ffe012ebdf2b5c0fbba6d5ff9a1dfe27b9ef5342e7fddb95cf2f45722d5bbb63ff0714adf709c9f3725a2ab8fa19420571a6f0da69ab0b9be46a6f330be0911faa52778d2059d81bd933897a0efc18b2ea466797915630c47aa1aad32241aef4548ae27444d9d071ba178524ea3abf35ab592b1105757d7232af511aab4ffec03e82c8f1e7c89141a1fa36a5a293c268eb71ed3b698a6a61a6f820b46b77326d4f4e8457c11a2a32e2556b2bf27643eb20bc970d959fa74a22acf51405157586b4f8b08c029610014931a9fe7d83c43d54dc0cb09506d8b2d72849264554dbdba82320debfff44f473da62085ea82a214fcf13b4beaca96a4a0edde00b8fe9d3fcbb7bcfa33fcc5e73ec865c3e96d5fbdf8b9bce76f9f0bc0f8ceb7f1a7bffb7dddbaef7bf62bf8d1bfb999175f7136b6b9135dcc7a628e6608dc2764076f48f0ac04dc60525c3ba34ac0786303e70c77dd3dbedfbf887d5984e94c9f8bd87d6c826dccede749455ae6a03d7e7ebbddf5a345d10007c88efa134891877ef5eb480f8a97113a10b78f87abeb3ae0467b909c3478e704ac6d0a1bcf7b792522ac2702783c9804398893d3fafa3aab7bf7a28b3cb2e798883f87b22cf1c6929719788d14504f4654d5847ab4896b1b6a1794e1a53278aa9ba6c2b416251c4a3884ce23c384c1b9a6cb27f258d6378e500e4a52156421445747c07b4fdd3698b68d4ac43422936519a1b26d4d961518ef688d031dee8bced5549117628b476d3ecf622bbc4b11926c83772ff4a9b48d9bf96cdb166f23a6d6068622692d999408e9116d45028504036e7aeee49d33c644053e4ecad1a04b8a4baa12ac22ee5821485d57aa6034f848b9ea84407adff55bc76c41a1139193cafae581710345885ae33c184b2cf30c8d81ca0443a075d0fa63f68c3eee5fbf860fffebd76cbbfea2ef7d1d5ffcded775cbbffbdad913fcdd6fddc8337fededb3cdde660ee9ff5e9ef154defd0f8b2325f3fbf7979fff1b1fe6f9bd7557bcfc4ddcfcf2e9f21ffef274dbc1394fe1a3d77d15097cf5a33fcd47fff887179eef444417a13898695a8cb3c18014d9947526f953bc452143ee8eb734d598c3470e31585a6669391a4f2270cb0b258fae1b08b0ad47e7298ae0d10a84ce29cb214a6f84628791ba572050ba20b16739d3a074d67b67b7c2389d17381f2b82c76ab926e618781ce5d20a2003fb8f0c451dfb73c1749e714c26636c5bd3341542fa80e57709cae871c246e53f1422bbfbeebb39e79c0745b6a4949310c799a3d07fee56faf3e2bcec460f4a4c4ed678a4f4b8a6452941dd86f1eaa10f7df8fddaf108a7880160b5c6e619f968025260f350010eefd1e3096665092743c2204ad28e47473fe81f9c0183125180d0c4649ba3ece34296bd30400dfef0eea8c06e78d7cff1e49ff8473ef0b90ff1c4bdb3350baa3beea23ce72cf00d6fbdea6abef5b57fd6ad9b0d8f5ed5fd3e9f0370eac9b4905398be9962192326b2356d0763b9bf47008e55163143f5bf2fc2bacfc87cb7115b8fb51b09db8b5ef1a970ec7e31a614bd48300e1fdb2f63629a9221112e614a616bc27b7f795122b1b56df470e94ee9f4de07221ea5585e19c2f280fd623f1405c3e132626909aa0ab406d31201ead0546caead53d793ae9ab094d03435c9b95c5515de7bf2320f4ab1139d629fce5d1445c0e9364d4733dac7d3a6eb6a4c8b7782acc85172cab8a3b5c6584fdb36e479c861681a4bae0b48ac1cf17852a98570ae2d902f66fb4e37812e78ae330666af4aa6f781d653084196e7bdfc82d99c8afef93b2ae35e92e18ca2e2fae3c1d636d4753d8d6af4ae33fdb95d40d9ee356993cb3629f9362afc262ebb6014b40e9a7baeb27d7de47ff2c47f7915a37dcfe6d3df7bd13d76de6391f11dbfc553aefc7da4abd85017f0e6bf78e7d1773a26910c0603bc6dd9b41b38d3a2636d0a630c32e6ba081fde0101e8d8c7acb34c469b40b0edcab244a8e05410db39bda6a93971bf38be79023533018faeb28295953d8c55065dbd0e0b08b4d2c858991be549b5433ae98f8f22508a2242be0c1e1c129d69b232417f3c22c296520d0da514d659744f519f8c46e0c23dc8950e513a2929074b681dabb347b8a68d34a181b420ef8cdf30269f3cd4791a6bfbf34d1f167dd4fdc3e3452945dbb66caead853a0b930aefc5031180fb8ab83c433706e13d663040360da23298a5926c6384aa6bccb08c49641a75e9a5473fe888f022b6226602275ab1a40d4d31cdf1870850772103b8f533840e6ff996cb78dd2dc17374fef9e7b37ad16bf9fcc702a6f19bfecdebd1173e921f7bc693bbedfff693d7b2a2045f7eef2b78ceaf7f81d2575cfaec5fe0833f362d40f3be37fe28cfbbfcf2181efd0fc0fbb755fe92dcb726c1f9973d7a55e2779940551ea625c5a1a96b2693314b8312effd69f122ee2449b9d9eacdddbe1ec4f1c84e8c3f3b1d73669f9ea2399fafe29de8bcc442a64ab2b3db2faa2adc29f473d18ff47dbe5646c2e08a986cbb7e640d21049b1b637491a354c601e0f63bee0845a422bf76a64358bb995434f504854067813a6e3c1e412f8f22b1e04c2635a6095542078301799e5355154dd37498fde4d12f8aa2db3f251a0ef38c8df55158eed728303e429e02046086c9a869c8b282c6d453057c07e3eda87d64de60dc66db2db946f1b9baf44c7bcfbaff2cbbb62745ea2863587fdd767d72b67f185231bbfbd6f807951b4c15fdd6f60c00bbe5b76a7ccfa5e4157b9fc1a73f73c33d76bee391e5f35fcd3f7f7a3104e96489d6057939448c46d81632a511127cdbe27ca00515089c0d65133bc8901038e7d9d8d8603c1e335c5e66656595a20c73566b4d47a7b99da89ef6a5a4268ce70ea534c3e555f61d3893a61ab3b6b6118b5605162def050645218377beff76cc38816480e1b808ff0bbf69caa5159657f707cfbdf7643a303c1913e82f454cfed552e3b1086ba9aa31990e49cfaac7bab3b267159d1798a6e6f0e1c3344dd5d533dad8d8084c40451960bd7d3632eb91fac4ded554bba4699a6e9c2d8aa28bb01e6d2868db96222f42c4d640632cc23b9c833ccf38f7c28beef78ec753c20020cfc05abc14782910ad4538172c5cd9434b670a56f672c6b77ceb510fe94d0badc3798973122bc2b1a3c93cbf35a16265481c74c68171083bedd02ffdd8e779298b656cb6c7c13de2aa3fe6faab16afbbe2e5bf31171eb53b4e988b1381ef6b32bd174a45dca2889ccd9ec0c2601a248eb6a9408ad33e02d0f76ef6b1dd8bd61f8ff495bfdd1e67de131f942f48eeada932e667b67531ea13b6093025634c0c754f15fafe31529546d80a0102a2e2ee703e78aa33a9bb77d9e1673cf3b6695103852832ac31344d83c462bcc5b412a5028f759e0d5142a0a50c1538094a7c5996289578fd05755d332c97188fc75da26eaa469c26a8959595195853dfa049bf87445cd57daf4d8d508a3c326948a1d03a4406aaaa221f2c23658b521a76e0be9f57a2b77bbef306c06c9f9033869914b2a7041d1de3db19053daad9796ffe4eede927f227e3691a75f2917165caa7722272322b019f79fe83f9d0fb1c99298281e663942958c1d3efb18647ab5679fc531f7cc2e77d40762b0956a8c9b312673cd6d8c00aa3523d8f985f8347088754aa5312b3ac201519abaa8a33ce3c0b08466eae8b1dd05c16ef83deb2688a962a23d70a0fe4e59033cb25ce845ee43660eb6fbfedd62eba381c0e3970e0005959d24c2651196fb0ae4167ba8b40e6598e5725f97019848e3966612cceb33c74537c241e68d0999c81c469ad71ad01e539f7410f0ef7d0bacea1e1bd4058a25121a8aa9abc1882080c8aa1b01f5b6adf1c8f2476371bf3c49452344d280c09e1f96459d6910ca4b9238d1f455e04728d38960c87433637370244493e1001b8cf882f734c9ea10fad05eacf48dde4b5c22b891996b86189289739e3b9cfe3822baf3cea311bf6b356ada1858be92a1196d025ca4d43db21cc6cbb8448632db5f51c99ecae78d8c994f9c972a7e57bdb00d80669325deb5c5780452870c6d3b61502180e02b7bb14eab478117792790fec1476b115f6b3281c7cace7d96dbf4910a0d4a6608bcf576c9c2a9e528a18668e38d0600104c53ce250fbd7d08790cc57b54cb014e71c999e427fba28800fb9113e1622133e4c1869c224dec332d728a9689a31d6d481a94848847718639938172af1468f7faad20ba0324d96652c2d2d75509f642424ef7fbaa650d5334077126346dbb698caa254d64b369c1a09d349ad4544fcaf738e8d8d0dce18aec4eb755d9cad1f21399ec8501761ea6d1ffad554f19ee967f13908e74866697f9bd486cea073d367343df662e3a4ff5baa36dc37fefa7dc5da080f3b491180939504fca467bf80273dfb05277c9c07e41b23ce3ba490a160d5de901733da5c076bd12abceba9226e3f420931a5c9b691de56a025c110970aa58eae1704d744725ef62526ce4682062fdc94394dcc6e77d6b9e72f8ccee58365f6eb026b2da3d188a669a8eb9ac172c19e3d7b82975feaa34e0fa138aa434705dad9166b3d6551b0b4ba12f3780204311f0c5915aa1b079552b84499122d8c34a609919c7f2726555531180c585959c15acbc6c64670c80c87ecd9b387b6b50b21415d8432419ee236795ea275152ba39bd3c2f1784a1800f9258f6474f8106d3140d73546670863b04581cb0b38e300c5996771f6b77f27173de77b199e7d742ee1cb5e78cd3dd0f26fac2cc2f3ce7fbfb7248d2d89837a4a031ad778c7daa1bbb1ae25930a99498c71344d15c378aba13052a64f8b17f158655ec99b87c6ece4cddf8af95eecc53d1603b28b00cced9314ca8e1634ae962ae400b8985c2adc2c9c2929f9d65a8aa298512ce7db968c819440de61caa5404830c686c455958504ba16708eb6adc9b5a46d27386b903e44fa840c0684ca033d80b78e4caa8ec2d3a676588fd6391b1b1bdd79ebba9ea1b3ccb240919714df541db7af08cb14c5f4cc4086889104efe93c67c6381a5375c9b4c61872adb63cebf93e70340897e8dd3b1f71b17da3ca7b3f3391cec38e8498a63dcee3f4279349f78cfbf7213de3545f60fef9a7e5baae3b63687e429f895470a2feff939c04fc80dca7252881be3302965725d65a26e3cd10a94c05b480548d3d112e784f28d027451cdf0a469b9b2cadee39eaf83bd3868571825e94d3130d85459b8504df24ad35dd78a2b3029d81d45950c8c763068301836148580e3cffd3f38bf46d015b5c9665e48392c9664bd584f14de93cb085b5965473c04b8117815a45498d6d1abcb49de27fb21d9279cc4182305e2d2d2d91e77917310c06ccaccccc99d1f9e4231435cb4342787a7ea783e3f19430002eff0fbfc4dd9ff90c073ffb194637de48b3b18e4790adaeb27cfe059c71c515ecffa66f62df6597912d2d9db4f3eef412dfd349678b5e9ea42ca40e9b149f3449c26258d0d194812427ebf27c0cce03b8c860e09d41cb506c24d78ad16444a673968703068301e3cd0d5282e9e9f022ee24f38aef54395ac4eed2538c8e71c0dd0dbc6c37837852c6929268521229c1eb267a2c31d36b9b7a7cfbf46d7dcf735adfff9352d2364dd7e743342115460bbf655936d36ead356409f7daa29508b01e15ab65b64da83e4cc4fc32558e95520c074b78ef994c265455853396bd7bf706bacb581d3c715207d6a16084a630b489d0230015957725252e56da4d616beb3de3aa89ac20bae32bf7ce83d6689dcd54239f8f002cf2b2f7ef6b77ffe77f676b9feb2bedf3fda283f8f49ed7ccefddf769df9c7fc63bb52f2554f78d9459e8d1ec35df17a5aa1abef4a55bb9fdf6bba7791ed671eeb9fb79f8c32fa02c4f7ebd92a3bdabf7d57b75cf48e8afd63558e7c932455e94aceedd0fc064bc19fa2cb18f2bc00bbcb781994a87fbab107867c05b363737595ad913a3a0dbdddbddd36286e7b33831dc03c20b8c9f3e67a93469244d7f42650c86192a8b114462f2ab975b94fde9281cc45a8b901ead335696f7209c6763638daa6a585b5b63df1943840810cde0d4084a39d675d1cfee3a449f1ce0e4e81632d262a7dc8514a505b6181df351c67e44276d2ba5643858a62c8608e939fb9ca5fbbde3f1943000ce7cc21338f3094fb8b79b719f934ee1e9b18ba489b09f6cd7c754c3ce46c0bca2b993ec3481f4071381c77b833506d35498b6c69b36145789c0aa50446596e9c37b8f350fb000f5a10f4a29bc48f48a6666fdfc3393bdfd771a088db3331184beccef37df261101749d5226a7cf4e8a90e89be779a8d06b1d2acf504a60acc17a878a95828b3c67737393e170c86432e9a834b5d65b5868fa8aa031863c53f17e4443210dee3eb0791031ec659e315c2a4378bd3591e9c3926b41d3d6641113da9890d49ba93ce40f18db79b2f7eddbc791f535969696a8aa98f0160dd5baae595d5de5c891231d34683c1eb3bcbcccfafa3a93c984a5a5258aa2984e9c5a331e5548add1f15e2523c1c5eb2fcb9251d550944b38a938ff610f63fde04190596c5f3bc3a2d47fc6291a911466d58b1c745e7da67d21cbb22ead70aaf48bae4dc9a8b336d0fe596b19e639023bfdbdd7865441d8188335d3907c3a56c2f0cf1b2fce7bbc0b10aea22cc3f6f8986321a64c4459864dcf99c55ebf7b5b26939a6baeb99ec1a0e0494f7a245acb0825b3dc74d31d5c73cd1779ec632f6130d83969f40139d912b8ef2d1e63023caf2807acecd98f108ac96484c5818f84152278e38548d4320770000020004944415458768fd21263c2fbe4bc076b41cba0656f0373099e76b7d5d9dec17e766ef514a21714383f47839b82734a82b10ea92565a6a7eb8c45662ada29116e14f7173d7c7ea8bfd2a263a1ac95bd7b303e90246c4e2a568c03a9d052234432d4f7b2e98fb0b1b141590e11626ac07418fc702b395136d034c66459363327847b23167ece8a8b50ac14e1d4e479a2703e3d1c8fa78401f0d1fff4785e3ff91fbc66f092073e4fc3cf37ffbbea7eff22ee46e615fced601fe97b1f92d1ff4cdffbdb1f6b78b6c3c2d2cb97d966409f56684c91aaa0283afc4c31bd3490278e7ca55497e0b510833e27dd6fc9e3ec43cd8e415152b7a1f26edbb6a1404f3c4fae05b840f939994c585959a18c068b6d1debebebe4912523cbb20e92646311302903c776aa68db6f5b5555b46dcb783c4629d5415deaba9e495c2bcb412c8667bba89e521aa53294d2983644129cf721c1cd5a9c83b60d157a55dfda5e20db3de7aead7eeef9c7db987eb3764ad3d9197642c4426e0a676bf0c100484645da3ee54bc02c45df8c21baa0edfd0842ea3f30cd31e81b82fd88e789cac94c0286700f6ebcf156b24c73f1c5e772e38db7f2e52fdf81738e33cf5ce6118f782837de781b5ffad2ad5c7ef9434faa57fef4f6f01f5d9aa6890677aae6ebd07a4a6d690e3a9c6930a689fcf83e22f4e33b8008d578a327bac8035431450db61571728a63d9e8b85122f0e97907c6b548145247f6226fb04623142811147dd9cd0d6efaeef55fff68048468a3e882105268f2bc4438416dda08eb54082283900ad4c0abababf1485307a516faa4210a92f4c79ab40c6c3b3fccef9be04f33d0c6b49ed3837c445cf0e49ff1d7fce9f195d97ef39bdfcc4ffee44f321aed8277bfb7cfcb5ef6b25d6ffbc4273e91fffc370700289850c80aa396a96d96c81366447493d7ae9bf480dcc7e523573fee845e446b2d6f78c31b8ea9df6db7edf1f4df673deb593b6ee7e72a252f1aba82d21315a18e8e72eb44d2578cd49c57a45bef6727281b0b672d828bc1e20842a71c7a815239ce19b4f4e4daf2f5db6f45b81ae51dc2872260c618f0129969c0619cc1e1c97480be6452756dd75a53470ee9a4406e857d4cdb58e41ae17c2c451592f9028c4560098683b196a22863944270f6851772c3673e8f148e95a166b4b9c6687d83bd7bf7a29562329930284aaaaaeaa02f791e0a7e49ad3aac3f808f918764108c4623068341a7cc3be7ba75fd9a064aa9980711a230ced8993a004ae7089d615a473658c222a88ce7a1973c92d1b8a66e4dc88f306d07535af40cd379fbebfbcf567837635cd18bc485f6d2e52d40487e76ceb1bc6f1f5fffda2da87613ef5af0b375005211b0740fa49f46206698907a3d7ebe7da9fd29b290f64f351a52627632289552e4e73dfeb8dff7ebaebb6e2609f844dff7ba6ef8ebbfbe86473ffa62bef6b5dbb9fdf6233ced698f23cb347ff557d760ed98473ffa52aebbee2b3ce3194fa0284e3e14e801592c6d6bc9b2a9873af4b19488ef188d37a926232693113803f8e8be76a1509d0b634228e3e039e3c0599483e5c8efa9b67188387c4c8e151d4e67ce784d49bf732ef22d010317f2eaa4d09d27df63a383232cb7a646a2b0dea06586d402672205a7f374597ab2ffdea5a4634fd336e4990202e569558d1140d35ace3afb7c84d261fc3016293c4aebd0501bf2aeeabaa61c2e07e203112215d6859c8113b707a6ce00988d9487f161361ab8c509e26d643353e968f1be0a8c777ced962f9fb0e3f164e91d8be4da6bafe5139ff8c431edd397c77dcf7f396af1dbfb94286138b0facf9c77e1c778d89e2fb34f8e1624343ea0fcdfdfe4a69b6e3aae17f0e0c183331482a7aaa441aecfa9be1d663a7d9fff9c8f1eccffb693477d7edbed3e17ed9bd6f715c3790f6ef212f53dc67d085b5f294e495e3389a3d66dbd8ee48d8e4a6716f72d8a22f4892ceb924a8510ecd9b327140813a2331a979797595959e9f0a549914dd4734939ed27f9d675800fa5e30e068319f6a09447908c8a45c74ad796f649d5359552c1bb16b74d502281dc72cffbcfa15f686bbb67deef5ff37d643b7626e6fae27c7e467ae6fd7376ca7a2f5fa92ffdbed18730f5e141f310c67986a81391939d046cada3aa1a8a4271d34db773c51597b067cf32c361c9d39e760577dc7184a6995055751769d9ad7c233cfcfd630a21b8e28a2bb8e28a2bb8e461dfc46b7efb7327fd7c8bce794f499629dad6d2b653e3520815e16982a5e132e56029d07daa2c30fea8a0303a012d2e94b154e1fd28975702eea607a9e9c0f87df1bd3e2fa69b1d8b08a64a74db56119297de7313e1913161370be34a6778c8a4246ded6fbdb70acf1422e85c883ed6758b351e10acadad31d91cc77b9945e53f3aa694242b4bb2b2983a4a4eb25ed68786a6e58eaa786eaee98f51334402bd3966ea9c01a5e469110138252040491a5f52e58eead17fc5606399e13f5dc9dafaa3b0c7d1b1bef807d7f2a84bcfe19b9ff22096560abc052143396ce7a045f3dded3b31089c9f2d5864363639f8777fcb573e773d7f72d57b4ff2553e20f3723abc88bb91a91236ebed9daf300b71e03b86e3f63ffbc7e82b900bdb8398196017c579d3a02b90f8d8fe90cb10364f3090a41ca681bcaf40ce2b96a97dfd4f8900ef71629a240d50964b1d0d67d33401e36a2d52059cff912387d9b77785a228c9321d3c6442638d0fc5c3b2a992afb5a66aeab86c0047990f3a369bb66d4355d09eb29aa04cde270c7bc4f8c76844478d2766e9ea9c172042b5d2c31b2356f290a4d8d6218958e70593c98442673b3ec3fe7398bf972114bebd84edb75d39030b9273fdb18b72a4cd7b5022a0834059675824fdfedd7fd68be04061250ba362f7a6781f12cd2793311b1b232eb860ca50b7bc3ca4695a9aa6a66dcd3deeb832c6a38f528ce9539ffa140093afff25ab173c9bd7bff8966f689baebdf6da9376aca35e9f874c2ba22d0bd0391ad2065a6b7496d1981a634344536b8d509a722099540ddec1f2f25edad690e5251e8133a0d4144f3fe52548787dd58302a5073ff5bc6ffddd7586fe746c17201459ae13096f077f04d0524ef305124942fc1e7e5c90602c121f90c03bd7553f0f6357c66452d162190c06210292a9002d02ac8d06438a5c7828ca6177e864f6a893e476ee7bf8b71ba3763228859caabf52ca196fb880077200ee4b22712cabbb917bee60b23ca25a1e73e6d95f60efe85c0edb7d61b23c06514671d3f5239efe6d8a473e7c0521a789b2ce096a2378f8fff1529abaef6d0d96f368639dec194fa5dc18c3ff3ec917fa806c91d3e145dc496694b519ccf4ac873f7defcbfc72ca0d58f4fba2f36ee751ed14ce05c56ce671dd53acb9e838b5a59071728c7cf788cedb9df0f130c57727a3204506fa9e1cdf36334641e2774e93615dd7a14857169553292032f13899a8ff2a5c57702c2497d675cd683462389c4e62896922c09442eec0781cbc60fd6a944dd3cc443492329c929ad3b5e6598e77f15ef4b0f85dc444c8ee9a032c48538d9ba804cb5eed83ed0b6a4df9b7c50c434fba5f9d3ab1c0b8ea1b807d4330e50074f03031ddb6efa59733dbcc1a70f3fcdcf351a1997ed67b07fa46e1a288c07d497c3bc24fee627278886a0e624777cdaccfcc21cce6edf8ea4e5cbd064be5099fb3fafa5ff3c2efbe8aeb271a33b884377ff00f79da19e1b84208def133dfcf1bfff24b9cfd237fc8fff7bcaff2dc67fe285fcbcee1b2ef7ccdb6c7ac0f7f1d3d78d8cc6f37bcede5fcc05b3e4953558cdd017efe0fdecd0f3d667f779e3fbffac55cfda79fe1d6afacf3036ffa08573ff7220026777e64db733ef6b18fed9ebd195fc74ffde04bf8b32facb3a43d0f7afadbf9e01b9f704cd7f7ae174db8eaf957f1a9830d937a85d7fce17b79f137eddff5bd544a53140320548e353644074d6b9854817d66b8bcc2f2ca0a592fda2c04d46d7a07c27218d2a6093b2e16b04baa71f71e76be94c57d3aadf7533dfbb83e8ffac6a48802b3ef736a57bfb8d6bca431e75415c1e9e1783c250c80526cb227fb2aeae24fb2fea8cf63062dd24a0e3fe61a96cb09e77ce1c91c69cf67e2cb5d7b3d1ba7f1357cfc1fef8a9ea86918dd7ac166a579d21d7f463b38a34b00028f3386239ffa14473ef7398ef80c9e7235002ffafe8b79e64396397f55f1ac5f9cad31f0b2175fcabf58915807b9b07ce02fbecc9fdcd0ecb84e48c56ffed825dd31a4cab860afe53b7f2584619f7ae5c5bce4e29c23e34d7ee2ad5fddf11c4793e36dc33d25a7c38bb893cc7b7153d2ed3c46bfaf14c51d6796e743edf390a0fe36f3e7dcae4d6972488a735ffa8680f781d1c5c5895088c8ffe45c80b4448c79c2d9278f7bfffae6a14ff3cae1bca409cbc4fb90e7195aabd080b20c13187060df19b4d524d07e0a11aa8046c57575753540948c47e9c00434582a71ce921539d578421b0b80555585f7a1a264d3345dc1afbe029ebcd9099ad685a821d07bcedcefa0585755c59e3d7b836151d7784f072b9a529c2e86f5f4ef4567543055d653c87b91f29feebd9d0bb176cfbbe7fd4fe7ef1b1a09dad5191e7e964ed47b3f53e579511febf7f179385192be5178a210a0939904bc71cb3f70e89fff804bb323a85b4a1eb767ccd7fff19f67b679d21977b374d727b9aca8b9fb6fff1eaef8b7ac5cf4cd2774dedff88e1750fcccdff2d97f73295ffca37fc3b73ef3d7f8faa77ea65bff81c7fe0a1f7f7db8befff7714fe5ac5ffe7bfee2f90fe3863f7e21ef9c3bd615575c0138eeb8e5cb7cfb8fff066bd6b327b2db5c70e5ebf8f88f9c09c0daf5efe0414ffb697ee8f6b775fbbee7913fcfdffdc2c359fbd26f72ce137f94ab9ffb1100def45d2fdaf19c49defa5dcfe4b3cffe5d6e78f7330038f2d5f1315fdf9bbee55c1ef7df3ecbdb1f7b808d9bdfc1b9dffc7ff1e23b7e2f6c28222c45cc8e5cdd381a213083c1803cd75d75efaaaa684d4d9e970c0603969797c95460704af021a5328a7c6b342efc45c89f561059d4164b7f7fd983134dc7073fd3f6c5c711c7403dda17d9cb4dd05a07af3fc4b134478abc8b96cc1bef27fa1ede1372b436de7cf3cdf77bc7e32961009c75d107597fd417d87cd0418493481fbc89edd298bbbef9e32c5df425cefacc6318dff6148e98b369dcd1bd415216143ae7339fdee4e0c1afa1b4c4fba0001827b8eb88e665bf72266b778cb15d097b87731e77c6050c9f7a11e3d13474fde96befe42ffffc667ef767afd872ae3ffaa3eb7973158e313cb08f77bfe2e1fc4954a2b75be79de565ffedbaee18977ec723f9f93d5feb965ffda43dfc9fbf7c0d2377f473f445c99084d35f3ede36dc5372ba4700a6099c531f4e186403e4a1af50f523015b94621f0a6385896f0a11b27eaa484f2de8bee1d0635ac022bdc489f0e93b2ce91cd855886e72f53e948177de069d56a810ce760e6701ef703a8599355555758c3ba95d4971940a52b29b7321a14e4a3583e5f41d8f9d0a455e3c3863699a362423c7088094925c298ca9998c372323488e6d032cc33947518472f2e3f1182144a02a5d5ea26d5b06c321b568182e076362bc390ac859efa9dbc030e205082ff0225205e229f3826250629a96cdd1049d67082452c79c0414168ff7224012a560ffd9e782ccd8dc1823758e5419e33ad090e25cbcdf5b27b4f988c2c264e09e211522119e4e999002850fd867130a08757dd2da98c02d913d03400b89f10e533734d606ae741b52b4fb2c4029aaa3e5365ce7b1edf358dfaead73c6c1c93000e0e45502befdba8f71f6e519179d0b7037e1fd18cf6c732e0013709eb5eb37b8fdba8f9db001f0facf1ee2b3cf7f38000f7ffeaf72e8df5e064c15e45ffb5797ce6efb9c870270f1f3fe2bf08e9963250810783ef1fb2fe551df71985b3ffa4a00d66f7c3f2f78c19bb8e970608019dff505606a00bcf1b92162b0e7612fa13ef213bb3e6792d7fec39d7cf2c3dfd62defbd6078ccd7f72bfff475cefde167f0d6b8bc220f75eb66bbca5623d7c5ba1b4a866ae1795692e7355956d0b6352b2b2b216f2020f231b6c5798f5639528671c8c5445d112172011e1331f1db29ec0bd417ef99a10d8d2ad03d26024159945d7e92920a6bb73a5e4ed63b785f90d3c1f1784a1800773eed1f31654b36095e339b9b40b5651587fffa10e26970e8f04778f0f221ceb8f199dc555d88f13b879f4c53303625520a6eba29be74de21a5c038b8634db1f1c7ef64543c2456ff0bd865ebc07b817192aa6ae1b270bccf7e6973db73ad55d317a228144d8f3569a7759d08c1554f2879efaf8775bffcb2473090f0861f7b24076fba855ff8b3f18ec7f9c8d58fe3fffedbc37cdf430b8e7cf2cb3cf93997cd2cff874f54c7dc867b52eeef2fa2d866229885374cf1d3aef30209bcf001d3d96355512a789e7d2c2ca58b3c789e09c55f42829845a8981c6693373f9d38e614242531b55384c9cb3385f4288222570e34b6ad4015581f28f1eac906b956483cca070fbf3301c6436471c9f3022505c6b5646541630d32d3b8080fea94406771c620840ff49852e0a5c03989d459986c83058f242578a90edb59d516a932729571e0bcb3b9f5861b70c6d0d816d55614b9c07b835639ce7aaa7accd2d2124b4b4bd46dc81b685acbde7d07a8ab16bc64b431c6b48ee5a501a3c998bc18609c6534ae58ddb32f60de45c0dcea3ca3ad1b8a3c4349c5685ca184a41894b46d4b56e4312fc0531605de4b1aebd045c99ea5bd8cc60d32039515580fb66ec8a4427981d47a5ad5721eda85402a85771ed7abf7e09d071718a192172f3062130d8fc8020468150d12c2331f8f262c2f2fe3adc3b506328fb76d3042a4c44989b316ef0cc25994d6d35c1167306da42f94a1009a107d6f5c3f0938fc3288b4abc6c4e2694a853e9fa22b5ae1bdc39d0428d0c94c025e1f79ce185d0feb0777ded0038727d8cf1f66bdf897277c5e3ba3cc8aaece4392fdfa78a0198227bcf0bf72fb8bcf018201f07dcffe717ef46f6ee1c5579c8d6bef42e567cfec31ec586c14de2fcef3d8f18cdb3cca63b93ee33deffbf827b9a85864642e52547bdeb1582c2bf4fc087bd1054ae5585b761874e71d3e32ca6825e3712d42843c0092fae03d98787c15fbfdcc956c236efb75fd9263f34f754b6460fe72b71c7436521082b31e217d170d981a3c5b13f8fb11d95301fe73b4b1e274703c9e120680cd2dc5e680765063338b34211cd60e6bf2f315c5da80ebdf7103fa159fe2423b64f586550e999d717e07d7325c3d44a263390800498627a276193ef279d4938cd64c1521e77df0a03b87dadcfd44f19c1fba84efd95f70ded0f01f7ff58bbb5e07b072e6793cdcaef1aab5a098fdf29bbfc047ae7edc8c77fe68c779d2edb7f3137f1114fd8f3c6776f978da704fcae9f022ee2c4709e1ce297ff3d08fb6b5d18b6a49e3b217e0133da7081eacb4effcb0d879917bb09ff0cf83703853e14c86350db4c444de94d43b876d95a048f9360a9ca70bd8a54ab13e7992a6e74ff87984433841eb5abcf118e7c8a5c6bac0b8627da0bf0b05685abc14681186b9b6b50c87251b77df8d31219cbf5486632e150346d584f5f52328a5d8b3670590dc76fbad6479899492b22c514a45c6164b59962c2d2d77d102b2607c1867b624321b63684c8b17d012987f545906a540059cbf17818460dcb45827103aa3d025aa2840289c8ff70d31c31c68db9d9368b74be29e56a48db4b20242b695032f70228cb34682b52162322c871445419167882c63696980766310a1d857db34345111cfb250a82c15ed5a04455b043d9baf629e8a7cf5993dfa4c423ac2a0b6bbce7b4b36461eb33686bcda7e230fac5770eb1ae6b06363e5c4bda73f77f9015ef5de1bf983ef7f3837bee755ecbffc67b7ddf6a72fdbc7abfff4667ef7fb2ee6a6f7ffe48ec7fdca5ffe2706675cd92d7fb5b63ce4823d005cf3b697eeba7dbb3de7d5df720e3ffcab7fc3477fe6e9408000edbd60784cd7f74b8f3f8b97bdf9e37ce8954f01e04b9fb88e873d712bbc2b3959faf673a2be75ce8308f49a42063e7ca154703840e0dd9749f10f051aeb7ac260302014d18b501f41302842f95ed029f74730adc0d5590bdde7a2f138f880765660b73803b618003befdfc10285ebc6f094efd33ffe2208e67d3527e758e4feee788453c400f8fccfddc4b93fbc9f2ccfb8fded7773e10f9fc357df712b079ebc971b7feb2b3ce4e75aeef8bbbb68d71a264f343ce6c0451cbaf35b763ce64fbef5a118bf8fe595824c654c8c627549602c8c0c0c73307ffd4594d75d453fefc1fa54b9f6d8bc4defff9deb793ff0a8c73f98fff8efcee5fb7eed6bbb5a07f0f82bf773e3dfdc7042e7f88dcfce4e42f3cb27ab0ddf08391d5ec4ed247843a7df812dca94f52e24befad97569bdc277386fa523163d4517a48f98b0add4a253c363abe296d67bef2986255205531a095a49a48f952e9d8b9e658740058f6f87e5169d57daf79358450214493c9ed124f4d500f508cc3d426954ae503e55a5852cd394b128977341716c8d21d3923c0b3500969706dc76db6d10abcc2aa568269e567b8450144518128d71282528cb322897b6a5ad254e296cdbe2bda7ad6bda3624fb7aeb228b4f4cee8b1e760468ad4212b254644ad3340dc243a6742850e643656495e568a5a91b8352392b7bf6b0b4bc17a134ced1411105b313eebce2dbc7c3cf27fef6a34a29b13879d6bb3a1422008b55ec0f5a0a849328a9c8f20c6504a6a9116d83352d388316b31cffa9bff69382e77354d2ba3e53d0b4cf4fbd89fda269e998fd7c90a669b6cd03b937655483596f208b63adeffe0b1fc6858d0e4da0b1984a323a46d6e2f3cf3fbffb3e3ceb855c7fcd7fe6151f7e172ffa9ee7f0e8ab35667809effac82bb6ddffc7fffcf778ce33bf8dcbaf3e8f473ceb35c01fccac0f3900e05d83dff3487eef7fbdbd5bf7be37be84e75d7e19fbcf3fc0a557be1678dfaeda7cb47326f9e10f7c947f7ee1bfe3e2cb3658cd05e73ffd6dfce91b9e704cd7f7f20fff39fffcfd3fc2c3df6218d072e1535ecb07a201e07dbf02faecd8da4f7a0d7d2d24e4e363240c8177a0542255b018dbd0b6357535a6aac68c36d6c2f898952c0d57d059014884cea2129d0a7149f0291978fa29bc0431ebfeef2be05d85ae6d65ea50093b6f593527c9ab300b139c4296ec51dfb1fb7242feb1cae9e0783c250c005b19cce7e0cc67ee65e38963bef496afb0fad055f63d6d19f136c1d90f3b93af3df62e1ef3b247a01e2451fffb2b701403e005ef7f290f2a1a4a0599f4e44a442b57a085a7f1436e164f063f2dcfe47d84db3ac0821bd770f6bf38a66bf9fcb55f65f97b1f0d6cc5d22f5a2775ce2b2e52fce21fd627748e8d39e7d8fcf2c96ec3c994d3e14584ad83e7228ffed69d247e9b08419ac0acb5281d135b11786f3be54ee01159c7f5d6dbd9d34d3033134774e37b1bd67b8f372d38113e232c48005ac67747f838d7a58975d6c36fad45c859a52fc045c236fbf61ea06a6a9aaac63a8f90a0d181d5da27feee5827a01890972564399d274d68c042d3c2b044df29c18baeecbb5012eb5dc7ad6f8ce930ffc3e110296560f3f1d3e4e0244dd3847bdc7b4e8b94d194df5096e50c9b91695ad03a14b1923216a311944b43f6acee0b549f75034cd937e6210f8bc2edfd7b39650a9ab62529de336ded1960e94bda3f411b4c35094990f504293cf564c4300b5da1efb94fe768a3b1b45d5279f2e6f7d7cddfbbbee73f6dd32f4e677b49d6272a27b512b007c60d1475b8b7ce83b160a2d1dd18a84c30045a07ad5f8c4ad9eef0db8c0be5194fe5ddff70ddc275f3fb0ccffd4e3efab9af4e7f78bddf76db79b9e2e56fe2e6974f97fff097b7dfb7bfbcdb73eae123f8f5f7fe3dbf3e77de63b9be6ce50adefaa14fee781d4713215437664dcf333b5cd675cd78b211aa06475a5ba5244dd3301e6f065200a1c14b325d920f4af2e532be6aa9ffcf7fa6c8de827940042364fb04e25d480a326c23c9f0eedee7e8a449390f8b20778ba27cf755395aff3e1d1c8fa7840170f15517b2bcb24cbd770243cff8cb35e73d7110f40fe5d1938c6c5260328bb61aa3c7473de6dd8f7c017a4932d0924cc704c318f24ef8ea1548c901013b1d27abd678b4b10cd78eae580aa5b9a8747c3966eb9e7fe9b94cd60f1d755d92332fb9000edec617eaed3beb6e8e7322fbeea60ddf48391d5ec424bbf5a06c855448bcf433637a52a6daa60ed522f1185353d7138c693a1c76534d22b4a6ff7c670b42d11d771a9af6313726ed2585402989ad2b840a155e05013fea840b386d07246fb4f0a112ae71082f90b102ad234eb0311270f7e1c348ad298b82ac28c8f39074abb32ccc7fb986c908331ab1b1b9cedadd07695d50b29c80322b686c4bae342818adafe1b1645946d33414791e683f2715e3491d8c89ac4048c5c6e638541a165383c146484b9665a861817702573952697289404bd5e1f2712142e011e133feb998a39165194a853c06634d8c44144829198fc7b4d685bc071d30c7a1b8f2145e24e614e4fec4d6f7f6f7fb4cf2a4a708527ab4211a13fb8f0f89e66ddb322c0b8c6d188f2baac904ef1d83224309c8f30c7ca0364d709d942cd8e7f04f6de81b0a091eb5b84f4f2141a93e04d01570eb1b327df6a113959395040c04c53ef6c5a0e4dba8f09bb8ec88a564a1399a47f701399912fa611f451f646a84a67eba755f2120950bb0d633994c984c2a9c6bc9b4ece0432982608c09ac4242e36c4d652aeca667797585a5e152775ce703203944e104553561636303630c65a6595a5a221f0c1048ac0b63c594ad27444c7129d29642c73d7b212e1fe5ce00317fa17f4fe6d4c5f9c8ddf49edef3723c86c7033900a7880130beae423c0ecced2d1b7f3fe111afbb88afbefd4e961e34042768971a561fb1cc9d7f7590b32e3f8376ede83cbf938ffd052365304a9221514245dcb00ce1bededb2244824858acb7b4386aeb98d40ebef569005cf9d2cbf881bde18578c7cf3c9af191dbf991b71c444acd4ffcd0435891e085c08f26bcee2db700ecb82ec9777fe732fff49eafec782dbb39ce89ecbb9b367c23e574781177f2986d27d3016cce68f0b3db64b1ea2dced03435f5641ca01b00388a2c167f91fdf34e43d1de46a850fcddfb1045903e78ac9d09caa4923214b9b4064f801b61234da40f09791079fa655f299d4eb2be771d4280178a62b0c4d2f22acb2b2b2025cda4e6c8e626757d04e95a6827083fad13e0ec3497c1031be30ae35a5c59d2da86c13050f60d06036cdbd0b62dadb320254591638ca51a8f91528624e04985c74c954b1ba04326d612182eafce28a47da5bbcf5463aded0a92a5edb22c0f502821c15a84500c9656180e97f142d25a170aecf43dfa7e9af0bd5d3f5ae4719fff2d79dfa793b65c032bdfd10000200049444154d0ef1c9992e45a621a435357b8b64549105e91e9e0e594627a9d5d81af58efa0dfce45510231f3ccc596e564aca43a0b424c0b8c85a4f893473b78b22b01576e3055f45bdb3300ec96dfaaf17d3f71f2fe285bb0f2bb5422d3b8958cd4300628ac3558ebd0d1280dc6b0c23b119003de608dc7e068db1a63039f7ed3344c2613ea6a1c58c60683aedf3b67a85c83752d593542ea9c95950381d8c17b8cb331774a75edef5eeb799b58cc7d1ea7f4dfc7fb2204ef44e574703c9e120640ee4ab4d488cc73c1779c4bf628c1f9af3c137597e221573d08800b9f731e6bffb449716895faf0c5473de6de7fff63ecdbbf872ccbbbcc7e2154b49ae70762871081bfd7da86d604ec6f7df06ef844d8e2836ff93c1f5c701edb56fcd49b16872b775a97e46d6ff8f4c2dffbb5068e769cf9ba04c7b2ef4e6db8a7e4747811fb32efc1dd1e83bf785fef53611987f2a0f21c7c60d1b1b64560d132e2b49dc15981dc324b243a4d17e0a949b1c49268387dccde1d96452c6c150c03a14262ad4204e7a73131b026d391a793954a4a9f844881394d480ddb2829311e2675e4d6970aa5735cd5504d6a94ad291414798ec8b30effef8dc51238f79dc8c03aaad6e07586b52deb7545d3349465192af20a4556947861b07e8417827238e82205891d492aba3a05532c7a48f60bc9a93e242447be5d630255a9731ee782d21fbcde814fbb8e5027ef3dc3a501fbf6ed232f0a9ad646e521464a129447f848e71af29158a0f4cff79745f099a4584bada694827d8871bcdea2ccf0ded23635c25b320dceb69836b0ff8c2713ca41de15069aaf79d057f6bb73ce452d76eecf619bbec7b16f44a5effde8c27d41ce3cffc17ce87d8ecc1453cc888b309ffef718396ad52a8f7fea83efe5569f5ee21770697a7f6cca6cca15525a604c8bb32dd6b64c26938e165788f0ee8b843088509a10399844c745dbbd3f5a6b269351203f90122f9203a1c65a83522dc3c16a60001302ad12344780f7344d4d96c7a272224502b78f682c96ed2c8874ddd3e2a9d37b375bbbe35496d3c1f1784a1800173efe7cac346cee59a3b8a46462462c5d3460b95842ef9594770f29cc903d8f3e93ec334fe260f5b0a31ef3fa17bf94db276be106740994e0ba6aa5538c9f0c593e6121c2128c771c5139fcfbfff98db9e807a493d3e14584e34fa09a57a2ba025ac263052867b16d433d9950571344c4bbe32dc63b64a7f2cdc37ea2a29e2a588a7e39fa8009f7de078fbf694105ba3f11598224022f046d6b024c45253ce914de238991372111c8c00814c3d7524abc541c38ef3cc6eb9b6c8e46689d057ace95158c85a69e90ab1245809fb46d8b6b5d87b9cfb38caa1a53962575dba210682d190c96032e370f98ff6139a4ae5ad636369152b2b2671fde7b6ebffd8e1076d79abc18624dc3785441db5066397939c498a9a29b94dde0b50bf7b9ae6b8aa2e8b6c97aac354e48f2bc0c89c5ce519443f2a565dac6301e55a8bc406745b73dcc7ac953a423fd4eef7b5a5e84b14f70191bf044e179cc181211ba221c58a89a9ac9680325a02c326ad7e04c83f70ea9a6b906a9b0579e8722414b4b4b33518f45edecc376e6214be9b77eeec5fcbd48c5e34e5614e064c9939efd029ef4ec17dcdbcd7840b61589105bfbcdaec760110c7f2142f5efa22870de44478b051f22499d173fd61ec9744e966bd63636d022eb22b45214ddb64d53cf18bcde4febbe48199c249bebebe465499e17d377440142768502fbd7d48fb49e0cd90eff7f6fc83722fa703a381e4f09036078f385e86244be5962cb065d65b8cc516c940c8e2cb172db016cb5427df011dcbdf9081a86473de61f5ff5de7ba0e50fc8c990d3e145dc2e841a123567e125f303ad8c55acbd0bdce942f52bb586b452ad352ecba8090aa192227a967ce4d1f71d75e78cb718706e31465b4985941e1c6815614188e8ad0ef876292545390c1e2ee23e4262acc53a8ff116ad8302d7b6c120514a91e565c0c16739d5c6888d8d4d56575731d6a3b3829b6fbe3944ec08c7523a98315a0b848ad5678da5aec60c07039aa606e1a2375bd034061bbdeed60baac6207546268247ad6d024d683158c246ae7da4c47981ca328400e33cc619b22ca72887816f1f89ce62e26c96a175a0283536b00c09a9115283b0b4c6520e0b9ac84634182cb1bebec9beb31f44dbd6946589f13d836eae605662f798871fcdf7ab7ea1b869f5df3e0b90212bf20e12a45430c09c0f1cfe7a30603cda8cc70a98fd2c7a26110ea3c36f094e9470fd01e214949b84895ea424a475a9bd30f524260cf5bc4130630448d94569524d83e395939a04fc809c02228f5f2976b64b844dc6a9141a996994f69c71e630e60cd6d4754d5b87b928cf83d2ffe033cec43bc76834623c1ed1c6f727d345e8c7919d0d1fe03c5264205ca0211582a6a9f0ded254559747331c0e192c2d23a4e872bac27be3f122561c9f5ef9aeef51bce0995ffbe34ddf703fd53dff494e07c7e32961001cb9f1bb58d65f67b9b81d5d1c22a30101c695d87a9551f32046ed996cfa0338a1b9170dd107e41b20a7c38bb893f48d98a404cd2676f60a3cf5a208c13fa57031a94c29150a4e798bf7d3c9ab0fa7983fb610824c892d4a171070a72e14cf9b552cc37a1fb1a94a2890416174085a63685df0120fca928d8d0d8aa26075ef7ef2e12064d7594f1bf1f9366e5b3786a228685bcbcaca1ed6479b21acae1460b1de61da16e71c990a89b84551444f7f86ad6bcae190f5f54d749e311a8dd079c9caea5e8aa260cfdebde03d77dd792795abc8ca01d88073ad9a165fb79d710201cbab9d42088d7116e37ca0292d4a8c69a8aa866a7d8dfdfbcf20cf356d6ba9ea09c679b456782119d70d322b1132180f175cf410c6eb9be82c671c214fdb79b7d2f35a141948eb9312bd1bd9923c2c3d5286506828c0a690cae3a3a1682225daa2f3a6cfd427b628ed3d65a1bf7f1ff39f969387bf8dcf36f5f194fc6b628423455e8e9149738b9cd424e09e8cc7630e7dfd10679f7b0e597e4a4cbd0fc8b6e210d2e39d0dc9fd21eb89901fe53b635d6b85d679a0215e0a46b152d1486e2d5ae52cafec617925d45368ea099b9b9b8cc735093009747935a022bcd07415ce5322bff70176678d231f94289d4fdfcb08394a4c6cfd361eaf6cf7dedf53b253c4fc78a3e97d391d1c8fa784a9f6f2e217b9adb99c7f65fe982f1efcd75c39fa5f7cf6eb3fc8f78e3fcc0d9bdfc10faa5f65cd9fcdab072fc77b78cde025c0039ff797cfd3e145dc49f23ceffeb4d633ac274966bc31226046894a65c8ee152895511603f2acc43b81b50e2f14d607eefab49f1701a79ffe42cea2a775364074944466c1d32595c2e2827749844462a488a5ea03263515c2312e14d10bed1832289728ca21e73ee462f69f7d2e3a2fa82735e323eb6cac6f50570dde05968da218608d412b455dd7ecddbb9722b2e2e0250e89170a1161468168c561aca7358e6ad2b0b2bc87c9a46665752fadf51c38f36c56f7ece3acb3cf6675ef5e8eacadb1b6b6ce59e75fc0831f72313acbb184825c426aa4ca4028c675c3e1f50d3646350ecdb86e689dc70b851392c6382c82bc1cb2f7c0196c8e2b264d4b6b3d4e4884ca90598e50e1b8756b689a6068c89595ce7b1ea22c594cec9ba5ecec2bd9f3c9bddbf58b45e2a372efa35118fea686a0d61a5bd733097f4067f0b9882e5a44c3d957e4e72358f3c6c63c9e3f2574870ac0a63324b4d6dd7b00d3226629fa903ca1c72b273b09b82fcda4e1fd5ffc13fefbe77f957f78e7c7b9ed8b777c43cef380ec4e76d25717af73337f82e899973d6a4c07de0536c1a6f5181b1cf95265685d90653952866aba4ac60ae646609a40a6906743f6ef3b8bf3cebb0029b2e99fd490c6f248099c65191287f0963c531499c639c368bcc9fafa1ae3c926936a44dd365867f1585c28f3779c92ce1f2445fde61d47f38ea253556ebae9a6e3d2390e1e3c489e9fa81be29e9153c20df1cc5ff824cf04e081cf63fbfcdf27f8f9f1deb29c3dbe0fbf7f5b35623c793fef3413f0bfcfbb85037e9bf70a8f356fe79d0ee0edbc5b4a24bfc37b9cc3dbb7f11e2190f2b7798f7338f756fe4408a4fc2dde2b05f0dbbcc75b9c781b7fd4b6a77d04a0abd4da8370744a947014450129b8eb6557b5b1ffdd62d02a232b07386b68da7180ce081931f796c4ee331fdad552e1bce9bcc93318ed983f8302a5b32ea2e0620e005283d4586368ad45e71983e190bc2c102232c56c8e834739562cb64c93c882772b1841ff3f7be71d6f4951e6fd6f557538e1c64997811986ccc082044551c400ae8269ddc59c5dc4b4ba2beaba6e7877575f7615735a3f06f4dd35ee2aacba2ae81a91a0a8e0480e33c00093eedcb973ef3db14355bd7f54779fbee79e09e4199807e673ee39dd5d5d5dddd5f584dff37b84106ed14952fc619f5aa58a49bac451176b5cdf941fe2298b356996089c664321b052d0ee4454874718191d67f1b265ae5f69caf6eddb51ca450cb64f6da552a9303131c1ecec2c33333348e9e179599131145e56fd53fa2143d5219234268e12b01695c17cd2d4a0e394a1b1312cc679e642a7d0b7e308a3ad4b40d60283a53634826db6a90f0dd34d522a61cd29b4b2e71d9ff739e059d99517ae5f49cf6144831474a5244af9cccc6ea31b27485c14c00a8d15c2e575f441c6062903fdd1a5fefef67bfcfb0d8272b2610e27cabdfd39cc2ccff9b8bf06c083294343432cabeec787ebff876f2eff2aefb9fbffb2fcf0e720e4238b3d656f917caaf43b8a33f4e46e41835cc2f0e06dbe5faa665e806fb2c47de318f8042032e21197e09f7740b2df8a038a647143c6ba268ca3fd94a0bb118dc62c511421ad73f808631148a454349b4d3c15e0876e8df07d1fb2a464bba02cf0bd97a9a9293ccf2bf21ff2f7e3238511e8d1e078dc2b0c805cbadbb6d1ddba95fac404def030e27ee23df7c9ce25571e339f1ff3024602c8aa233a254d20ac4048a754e8bc688870c7c92c7d5497bc7cbeef3cb8f32000166c062b9056e34bc121ab1ef91371679224c9bcef65e804224bd6c431e714642e466084405803423ae51e10399fbcf41cb52516690c224bf0753851dba39ac455ac3559c44058e3927e4d166e36094a089497d17e5a8936c655ad15ca55c14d0d4845a03cfcb04a105450ca234d74e6fd8e33e68b002ff4f14b5e24630c188dd586c0f389bb1152409a44d4aa2146d788458a49bb0ed2643325513a6f9516cea818191961667696ead030d3db6739ecc82349e29828d14c4d4d313e3e4e9aa6cc365a846148a3d5a12b63c6f7db9f5a7d9876bb4da3d1a0d56ee3791eb5e111972b902474db1d3c4f3a0621abd1da8231784148d5afb16cd97ec8a11ab4bb6cdc780f9d28a65aad2084ab103cb668119e17e08755666666189fd80fcf7611880c4225e7ddfbfcd3f185433e2f7704e3da99f25db45b28437d06825245126f5ea741a01c47b87045dd8c5ef87cf62721f7ff969fbfcc0834083f9c4380f24840b92ab0520acff348d2f9c6e99e284992b0e9e6cddcb1611df5c347d0a311d75cfe3b8ebbf644561ebfffc3ddbd47a5ec081927c48e94ff850748311f46a35429c19d723b02575831fbcc8915b20f59360285e8c17332524257a3482245cfb3ae2a35c6c26a06d7ebf52dea76e946110112df0fa9545cdd14219ca3c166eb6f27ce2a17478eb5c819213dc37b626262c17cb4d615f78ba208a504691a93a6319d4eab785f572a15eaf57a11adce8febaf485e6ebb1ce5031761f4bc201b8ec134a33b9beb0fc47be0d1e078dcab34e8a4d964dd57bf4ad568864f3891c5c71f4fedd043773c93f7c9fd1251f25eec106b2705945e82c666e1500d5e0106d758613166be3292e3170580b518b15051109847c544dc99542a95819e5d374686348933634014195e266375b1c2797c0c1a8dc6c3223d4777a94d823549767f5dc979b70e295c7ea7c814dac4d17f22321a50814117e7d23605a390d6b59355cd006b1006a22425ac56a9d586104a926a4337ed1686e0e8e878c17ee16834fb1291336887e77905a34edc8df07d9f5a58617c74884e7b8e56ab854e5cb5e0d4e4c5c59c77d8588bf40394e753cd12733b5142abd5627c7c9c56ab4510040c0d0dd1ed7609828030ac32b565926ab5cad8e2258caf58e9221a084813dadb6798de3e45e0f9802ba4661084be22ac5519a90fe1d7aa906aa6366e4218cbfeab0e020b1b36dc83308615871c4667ae4958add26cb6e9463151a74b58ad3a8ad3ccdb5d9e7fbdb9912fa662e0f391efdb5f09b82c2e8a347ffffc984c3341291fad34428a0c6625c00884b49834c158811483fb58364aca0a7a7f94a9fc991f9f7f2f43a2cafdee6739291b13f7551e8c24e0b96d0d6ebeec562e51dfe65727ff14ab0c95f610973ee67bcc6ddccaab2f7e33c73eed18c4aeb92bf6c91e23f7f539bb0fc7e5467ec9d82f6fb3d64089ba54790121924a45144672efec0e9e29844b2276c5fb926ceeb8bc80bc4278a3d1a05aad6611e6ec7459142ecfad2a2bf6e5aac1499290244901d7cb8f2bb7538edef5931308210af6b2053a41f6f960271bef8b00ec615259b408e52926fffdcb6cbdf807e837bf95030f3c10597a407757be75d0418c1d7618cb4e3d15353c4cfde8273174d2e1987430764d7a92e66f6fa375e395e84683c9cb2e6366ed5a5e74e79df7f3aaf6021106e7bde8ffbdecbdcfa81b338e6b638c835dd89ec741656de42f9824491c165248ace8c15a841048e5bc009d4e87438e78e44fc49d4919f2b3405912aee08cfb3bbb0f50dc13632d2810a9c218ede238ca7794756942d449109e4509e7ed1712acc9f0fcc2197fae98130891f14618ed223d380696d86a5c859bac188e70f49fc658629d6285c0f7438220c4584b9a25f6e60a66a3d9760b8427104aa254b62864f49a9e2749d304690dbe147802922476d10b29f182802a43f87e481a7589a30edd52b133213d9acd364323a3686b58b26809b3b38d82b5a7dbed3232325260c96b3547113a3bd7a452a9d06c75e8460962668e581b6caaf1c280d1a161561c7204284b736a8a99eddbf1a4647c7c9c6aad46d4edb275728a2d9b37b3dff2e504d580c9c9296ad52a07ac3a18d294d9edd3e8d492684bbbed78c31b8d46e1b153ca9f47e3993d11c55fee99e86dd99997bfbc7d81b28d466486be258bc0e41ce9723ef6df5a8b92c24596c4fc45ba1fdbdfcfe033a82ffd8643ff339e2449e1f12f331e15d03828e03f83aa93de5b79a09280933865dd9a757cefe6ef72f9e32f61e381eb19df3241b559c35aa87586b9f40917b3e68edf71fa85cfe3f987fe19ab1f7f24ca7fe02a02a7a9c5f3f6cca8c83e79e0a43f6f67101b567f84300cc3c240701e77af47499a29f3b903224fc0cfdbcedb8fa208adf5827316ac4825eadef2bb274d53badd6eaf486549ca8509f3be3e1cb0a24783e371af31007414b1fda69b68dd7a0ba6db464c7699bcf4e78c9ef438468f3d1699c1497657ecd414cdf5eb597ee2898cac5e4d6d62d855decb8af7e4b85b322a2da924626218357b0073575f4df3a73fc5d6eb3b687d4f91fb63219b5284b2c72a334faca3641c1a12081d932606a1350249a0c20cdaa1909ee3244eb4f318f852a1a442f9397da5c18adef9c0923bf72ad5faa3622266ea709f08c03a480939e5614e3ba7b2fd1579c12632960777a3328f3e1625044668b44d31c631bbf841401c07d8c825a459010885f361db02e283d5f498681c38d65883494da17cf97e4ef1a85d827006e749538331108415109224c3674b29093c5528885e38df0b043d4f937bf1bb272fd669011bb3d21990d2f798de3e431078d42b352af511926e0bc42c5dd1ea194f5912f2e8d862520b49ac494d4ca55205ab69b7dbf852213ce514fc2c7c9d24119ef448e3042b5cdf8d1044ed0edba298b039874e63eaf53a2b56ae0421e8b6db6c9b9a2a3c64ab56ad224d535aad16e014da6d5bb6140aaba7822202219547ac139acd26b5fa30491edd61c7cabd3183b9f3779500ecc4e426e33c63be2712a31de5a9c97333705833818367b9e771c7d8fe7e3ef3e2e916629e92917b11730521bf96e29e678a48be6fae74b43b9d2202e0dfcb75a05f1ea824e0388ab9f6b2ebb870fa6bfce225dfc7ef04acb8e53004d05ed240c5017e1ab0f2da23983a742317bee48b6cb8783d7f7ec55f70ec938ed92d96a0b47d13ef7cd5395c7cf31c75cf72c0695fe2071f3b092104df78f78bf8d8cfd63271f6d7f9e6599b79f973dfc4ad1d8fb47a049ffbc1d779ea12c76415377ecf9bce7a136ba6623ad1307ff3f5eff0dae31601f0d3f7bd9cb3fffdf78c8f28868efe38977ddd658075b7fe6287eded93874e7604edebdfbe232740a5e2ee59b960dfa0b99ac3f0ca9224499157e0a883d50e3df2fd45fba2c8d1a2c6714cb55a7545d44a4647cf6878782b0cef8b00ec21d2dab081cd97fd927b2eba88f437bf41262946f934aebc929bdfffafac78f14b587aea53a84c2cdbbdcc1d705483c0f4e59723820039bc08ffd09518ad41294c27c126295ebd8ad51a6915dd4d1b695c771dd3975f0e802d3df0e7bde2397ce5d22bb975c3cc8209f7ae679dcc8f3675f194a16bc679e3f95fe5ed67acdce936ab1b9cf0d8538b3674743737af1f2769afdde5a5092138eeb8e3dc62aa13aacb8fe175e7be8f739e75f8bcfdaefa7fffc85f7de422ba9e4f9c84bcf05d9fe47daf7b02001f7bd6a9fcc79626007ff8c3b51c77dc6300417de235fcf247e766fcf0c671866b4741e60a96ba28802a2970799f720f81ccf8d70b6f9e34996ed9e3af07509e07d63ee22762aedef7bf3e05801038061889ccbcad164d127748a20e5114e1ab80344ad1d652ad56a956abf85ecefdae91f858ddc113a08210b4a63137e7e03441156353a430186dd1260593513e7a3ec23acc75924418abf1a4422a95f54ba0a444eb84c00fb05610c509427af8a1ab8cd989132ab53a20498c75d5810dd8c4b51b063eb14e41980c3f2b8a91c80d0ca93c84ca2ade4ac75aa4adc3c57ad2430a85a7429aed08cfd324896564c97eb07d8646a341a7dba15e1fa19b682686c7d978f7dd28a5a8552a98344608ebaa750268e30a9f65d58f7d29d03ac5cb832c588412842a338a8cc65a43b7d5a4d36ccc83bbd4c2c0190c498c4e1214192fbe43d0b8088b3608a9a95402e765c3e2793eed761b6d607cf97eb467e61042d06c3659b468117333b34829a9572b44518417f8bd05d696e05332ab0d5abc136d2f413ccb17915665b02ef704daec3fa57c5263999d9963d98a03d8b8fe0e940069359818251549b78befc92cafa777ddc5f39b2de665769e7ccee7518dbc064019a6548e04e6dec9fcb7fe24c3344df1fdd045a7445ebdfae1978d376ce27fa6ff9b9f3dff7f18de36c6b2b507b0fda049a2912e5e2bc04f05332ba708da21075e7d38db0edec29567fe88911f8e3271db3b38e08f769d1770c199cfe0fa677f99db2e3a1d8099bbdbc5b6ef9ff05eae3adfc1983e72e25308df7d19d7bff4486ef9cf97f2e4677c92ad6bdeedda38e3d99cf8e9ebf9d2098b69dcf10d963ff1af78ede6af00f0e2f3fe8b5fcf461c5ef5686deeb5fd6fcf7af10edbdb270f9de47364d0bc29cb8ea132bd399b1fd76f34e4bf95e7ab10629ea15d5ee7fb8d927c6ef79c390efa93470efae1436531c62eb8c6b23cd886c1a3c1f1b8571800d7bce35c923fac81c929ac74f482d21a74a743e7273fe5b6356bb8fbe49339e20d6f64d14927212bbbf646e4645ed3bffa15ad0d1bd8df1fc63be978b4b5c83465dd19cfc6b69a1c72d92f015069cab6df5ec3c6af7c85e8aebb304054629c78da6bff86977ff4b11cbadfd08273bde7bf7ec987c79c053d77dbb75872dce9bcbd7deb4eb70935cc9a356b8a367efbeee378f9dd1fdaed312b1fbbf9da4bf8f3e73c8e9bbf70031f3963050077ffe02d9c717e8b5fff760d470efb248d5b38fba493f98b65d7f26fcf59c9b93fba8c739d168410016bd65c8ded7b5cca93dc454a5ca292b51aa3e787f3a1f422d2a6c0eb963d95c50bacef5a1ec913b16c2ae6c00ed9b78397155aea743b681323adc1a2d13a460a83b410780aa44092d26ece102751967ce994f9f1458bc05ab66dbc1b63607c7c9c4aa5c2f4f434d82433ce1c1568bd5ea53a548334a1d168a0930890047e25c37df73c3e3a4d1db42b4b09f0bc00630549eaaadc4ae531343ae6603f49c6832d847b5cb421892c466611a081a3e21695bc7a6e1cc73d8f949574e32e415e2917c7d7efd88f3cc6964c30b664824d9b36d1e97458b9fc001ab373ceeb8fc52429ca53f84aba0a9e59f4215fecf2e7d12b25b259db33564d79b1eb7f6e734336fb274abf5b639ca3c13a06f11c0beb0a6bb9dc9b348db15d49dc6c128621b3b3b38c8f8f333b3b4b18049951e6eedb8e3c7ce5f1dbd9f3274d96cc2bc8c62e3f5e60adc1269a7abd4eab318792aec27492c604be4218e73019749e02935cdadecb2f5898049c2b1a3905683fe6bfac5c9421472e0172cf50fc73f9f9753fe5d2d3bec7e8e42296ddb6923b4fbd89ea749dc5eb96d119efe0b72a2c9ea931b3728adb4fbf915597afc65af8c5713fe0c46b9fc05947bf70970ace3ffe6a0b57ffefd38aef632b7b49049f7ce191c5dfe75f3fcdf56739e7cfe1677d82e9571f0d3885fdbdbfdbcaf2d79dce05d9bec372ba38ee0d274df0e257bc9537bff42c5e76d63376abbd7df2d0c9a0dca0fe79b2a3e3dc3ebd686b790ee6fff2796b8c718e944e07dff7191919210cc32221bf1f1e58ce23cadb291bec499214b0a19d450df2a8e4a0feefecfa1e2879a43b1e612f3100929fff1c9214133a254025315a298c102c3aed34667ffe33e4edb773ebf91fe0c037bc91e5cf7c266a1746406e0048a07dd75d24d3a6c8a4b7c0dcefaf464391602c8064dad0beeb2e7207a12e2d784ffee3a7ecf05c4bc67ae1b34e6396cad293766b5b2136e51d9fbf85b75ef7c4e2a7b73df5095c361bb96b49b670fd4d9318d38f1576b2df63cee46b3f7e3b073ee3037ce49e4f03f0a1377e9577fee26e8e1c7696bc3f7c249ffcfe3b38f0691fe2dfeef9e48056e64f545d0a3fd79466bf279ecf37fff928dadbaee2f5affe27d676156965151fff8ff7f3e4c51584100c2f3f8e6ffdf57338ff47b733b5b5cbcbfee5d33ce686cff0899fdfce867b9abcec5fff8dbf7dc644b194e78ac2c8c8083ff9c94fb8f9e69b070ff00e64f5ead51c7ffcf1d4f778a8d640d57f9e38e68504639c37da922284c4f77cd228c6571e7ee62d8d9298a8e3a835952748624b63d6bd90bb9d96539cdbaeae40ad12e2ab0a524250ab41e8639a4db66ed98212ce5098dae6daf2900814499aa03c81c4c1702abe2bd46485442885b5ee452f3c9f30ac608d71c5bfe21489c0578eafdf026e6e6f45000020004944415426abfc6b458fea11e62b9349ac0b763caccca2215e919ceef8e20d7e103aef941792a68e5d288e636ab55a91b8d66838053a8ea3e23c8eb6743efca87f512c4bbfc1ba23dcf93ca3b6a4b096139d857009b46e21552e77c29628509314ab1d13931292344ea866518424539e7756086c50ff07f7d5455e2c8effd01de3da8aa2887abd4ebbd970069050a4494cad5625494a58fc3ec85179d12f4746ca9f65a5a50769ea8d4dff3896db2eef5f3eeefec8039504bc6e7a2d7a44b3f4b72b58ffe49b19bf7d29b5e92166566d4518452d114caf9a64fcae65d4b78e70e7136fe2f01f3d86d649b3dc3675db6e9d6367facf22aff72ed1f30cea9cb3de496a2ddfbdea6a56850b9fe1f75fbe9e175f7a31dff9cff339f4fc4b98bcfaa3bb6c6f9f3c7432085f3f280fa75f61ee41f30633ebe4bf455144100428a5181919210802e238a6d96c323737c7d2a54b171c3b2802984b1445743a1dac75f4c7d56a755e0e407f14a2fc8ee83fcf4321535353ac59b3e611ac77ec250680d1065dafe2772364928027493d0f154524f7dc8dae5559fe9a5773d7473fc65d5ff90fea071dc4f8631eb3f336e9a95d06f06a4720a4c71f168d01a0561c898cbb5cbb64090678ecf40ce1f0eac268e8370076259f39f3c97c66dd3ad66d5bc6376ff8d56e6f0398bee91fb826781e97ad1c2e7efbd4a5570160f51ce79e7a04abcefbe94ecf3f76d8b9b4b7ac029c01f0e52d2dd61f3c326f9fd183de466bcbc140d900188c4cbfe0cc6770fd995fe6b60b9f4ed269b2e9e68d005cf0f27309def8effcfaf9abb8f97ffe9a67bfec1bdcf1e33f2f8efdeeaa57f1e3ff3994e6ddffcd41a7bd8a577ef20b5cf2b61534eefa6f0e7fdebff0b77fe89d3b5fd8f34978ce39e7ecf41afbe50b5ff80200a79c72cabd3a6e4f94dceb2d6580b029716c0b661e219cdb589bdc8b6df07c89b012e939b6a5c6ec0ce0cad00b636934b7530daa0c0f0fa3aa21d35b36d19adc8cefbb7c8d6eb7cb70bd860802aad5aa63d8d179d12881d119d3108ea79facf09831600c08cfc70f428220a0d3ed12c7313ae9797b5501215268ed606083162fd7e780288ab0d66663200b7cbdf2149520a4d99cc364bff943611162ee76bb542a15962c59c2dcdc6c81594d92846a1012c51d87fb67bef7aa9fa26ed0fde8f7beed4cca8b753fe385f390397e70ab9d5154f103fc4a852008989a9a6262f97266a667181aaa912669e1392fd70918d48fdd52fe652fc7479493c86d8f2d241caa51abd588db0e162895e7e85da1c0f0f79f33ffcc696cfb7319fa3d87f931f9f8e789bf838a0d95af33cd92c51f0803001e9824e0364d54ea112d6a136ead333435cae6c7ac4768c5925b962253819082ad7f740ffbfff61046ef5cc2cc21d3549a351accecd639ce3b653f5ef7894bf9c9bb4f031c04a81c05c8e56f8f59ccb9df59c7d75e7438ebbe7d2e8b8e794fb1ed9f1ebb8c377eee2a7ef8974f0260ed6f6ee2b0c71f0536e2ba49c3094ffb138e7dfc11fccbf8d3818feeb2bd7df2d049bff1bc238579d0dc71d177bd60ae96dbced97f72084fbd5ea75eafd3e9b86ac5e56377668480ab66df6ab50adcfff0f0f0bc776cbfa3a4bfff831c1b0fb621f068d03bf60a03e0880f7f882d5ffc1269d465ffd79fcd862f7c8e95af7a2d33575cc1aa37bf853bdff73e963efd74bcd171b65d7a291bbff18d5d1a0039d258e206c13782b05aa15a1ba5d59e857b6e019ca25f012af52abe11ccabc7772f1ec0b75c72396fc172e5975ecbf39ef15eb65d7ffe6e6d03f8f15f7d8de3feee870b1bb5291f7ef1095c79e247f9cddf3d6d173dc8203abb947ce2e6fb0ef64effe3afb6f0db8b4f05633049caf07e2160f8d82db3fce6b90721041c72e65fb3fddc1722e5eb8b49fbfee71c821082d1552f4027efe7fc671f844033bcf279c4731f768a517e926c7cf349588607eccee729a79cc215575cb1574c4430a5112e00e785846188a804e4b49f89d1d8c431edd46b55d23822ea7648d2288351395aca24d60863097daf78311ba31d0e5d27349a336cbf7b3b41e0e1fb0a30f84a521919264912d6af5dcbaa830e2289b5c3b12be1603e26c55841e0d7d026e94174d21484f3b68795aa4b2cceaa1067760ad652e403284f2085831ec17c2f553ebd721c79ff82638c415a59305404812a70e3f931054ca4cf9b5c16297b05d3ca4a6919a39a4bbff25a96f97d1f8cc32d7bebf3fe151e6ceb92a60d10063e8192e834a6d36e62d3184f0a7c4f62b475791b4622a48b18ec6c31dce54299e3e6f38f62ccdcbdca39f887868698e9b6c15ac230a4d36a53097c741a2f50cccb864e5ec42dffbd7cffca18e0f2f8f45386165d1d30b6838c82fb2a0f5412f08a9103f9bd9604b321b5a11a332ba61056b0ec96e5ccac9c468b9465d71fc0a613d63373e056fc28246c07b4c72d4babfbedd6b5bceefb3fe1da97ff39871edd602410ac38ed8b7cefa30b23c86ffddf0b79c5f39ecfb1e779a4b523b8f0c76f2db6bdf97f2fe1da179dcde19f4fa99270e093fe91ef3ffe28ace9f2cee73f95c95810373bbcf1a3dfdfadf6f6c9432bbb7aee7307c3e06d655ace1d9fa31fa653add6a956eb94214483ce5b96200858b468d10e0df4c10e95c19d7aa014ff41ef92f2b64783deb15718005eb54ae5a8d54cfef0621a57fd86556ffd4b1ab7ddcaec2f7e0e6ff90b66afbf8eb9abafe6d60f7d10bd7103f56376aefc8323b5f4b37f02f0cd5d54039f2737a659ff779f64c3f9e7628189b3dfc3a19fff1700647c0715286afadd7bb236c1135ff369b6bf6102387fb7b6e9e86ede76d936beffdf87d32f5f7fdb93f8ac7d13b77ceae5bb3cf3cc6d1fa73ef1aae2fbab26ea7cea8e39fee1b0d1e2b7b93b3f4d7de2d57d4796427af91f0e2580b0aee2aaab12ab4188a2001859d5508198e799ab2be942c6c2418f6a32e331173ed666b8df5208f081f0e8edc9e24ab3ecbc6cbad68eb927aff4a594471854b14a834d10c22984491a39d61a21f17c85b60613c72e715780149ee3ecc782b1243ac54486f1d111bcc02563b65a2d5a191d6510044518d3f77d749210c739d5a2244d9d7287d6d81c3e62259e1f1056aa785e409c2405a35381294d35d6588c1428e9a175dc639a1a00b789e3b8483acbd9612a958acb41302eb7a056ab65c9c63d9c69ee15f37d9fe9e969962e5ec4b6ad5bf033ba3b97409ad16c0ab3c083967ff67baa06f573475eab4121f8fe08432fe4ed22010a89af2458436b6e16856072729289030ea0353b5b14c6d27182ef8790da62051fe489bfaf223243d20a97b857ad55f1029f384a09a48fc9a23fdae0725106e08873c853d918eb1f8b7e25a57c5c7ebfcbb0a07e232e67a92ad70578b8e584658fe3b2b53fa23bdc249cad902e4910b1447414dd7a1ba4ab9521128151d6cdeb6d15ea768413173f6eb7cee1d556f3a9ef5cc9a7fa7eefbfef95254fe1a25fdd34b00d7ff8782ef8e1d50b7e176a94ffbd6acd802376dede3ed9273b939d396216eefbd0f4e5de6e7b24c95e5141ebce4f7e8ac9cb2f4735dbd84e97ca2187d2ddb2c5316818830e0374e03c8c2849d26eedb24d45e6f9cf3e956a383c6daa39f0036fe7d81b6fe331bffd03875ef07e4c9a559ff49af38fd98d05d624935c3fd92dbedffafd7f60f880d7ec725b2e775ffc16ec91e7f1f8e1f9345cbf78fff378c7354fe2f7df7a17bba279de7cdd0f79e5333fce395fec256afdf5675fc9479efb366e9e73c92a49e316fef2b91fe1959f7dd72eaf095cf8f9cf3ffdcb62a2cc6eec202dbc6bf518efbe643dc618d6ffe8c38caf7e5d6119c3424f687fd83e5706f2c4a107bbd8c79e22b2e0022a83d39cb8f1eb258f0aa108c20a7e5801a168b7db8e12d3e2bcea52a004ee9f84c0734c3469dc754c344a607582d50ecb6f4998deb695a9ad5b90c2323a364c58f149d2884eb7c55ca6742a3f244ab48b55488f443bfe7aa13cd2d490688b178484b56a01dd48124d9c6d33da66464c5641da65943a037027ff72aeea1c2f5a561a7ddf67686c8c6aad46b7db656e6e8ec9c9c9020294b3cca4690ad652afd70bc3207fbefa3d38d07b0e73e5b2ff5f2efdcaee200ff7a0884359212e38b7656f5b0eab69b59b80216ab72072f74f18ebee75a6340f0aa50fc201efb09f0e7cd4fb4da7388c9706635d8e0216745a78f3e338c50f2aa4c64503f2823fe57b158621d56a95388e171479cbf72b538096b9fefbd98206793a1f28afff8321279e7c02af58f74662d9c5eb868cdfb98caeed60a446c5ee995491244a23eadbeb8cdfb194f6d2695e71c79b38f171273cdcdddf27fbe47ecbce14fc3d6ddeee8e41f24894bd2202503bfa28c435bf471cb082e1539ec4baf7bc87fdcf3987cefabbb052a2a288c60dd7b3ecb4d399f9fd35d89507eeb24d8933022419e825e31a2f8a5675532cca317de49ea5bc5852e9d85c3e7fcad1bc6fbd0b1daf58b1829155ffc88d57bc01936ce5adcf3e9de944214c17b9ec442ebcd261c476b62d97cfbdeb32cef8d2e716f4fff4bfff01cb8e3a86a73cb6b75894997f8e3ffe78a7609894ea7e47f3dacfff8e373e6b45b1fdc0e77e868bb7fc03af39f938a220248e43feecdd9770de73cb63375fb12892bdace575dffd11d7beeaf51c72cc2c439ee58053cfe7a2f71ec339dff804af7ff5db78d2a73cd2ca817cf9eb2f2d8ecf3f554961e94fb4bc371e8247b6f488417ddf73c6ad15589dc79e0c5aa7349b6d74dcc1971694c4c3c3e29459ab1384b1a4695c248b465182cb27706036ad13a24e975aad82941e4992d06a3500176910c2d14f8e8c8c600cb4dbed0266e3b0d780f288a38e6310aaf8844105ac248913d234250cab1840899ef2aee9b1be8c2c5edcbb6cd17bc67abf5948124cc61cd1ed7669369b28a5a85403baed9653963b0eef1f8621b55a8d76bb4db7eb0cec7abdcef4b66d2c5ab13fcdf5eb014be83b232708022c3d3c6c3f0bd0a064e0b207bbbc7fff7ee576cad20f172a0c104dc6e6e412341d7312546b35366fdecc7efbef4fbbe928192b950a9d3842794106ad9a7ffe41109a41b2c3b9274c46092b083c459a4762aca41377181919a13d179124da45024bc64ed9c82917172a9f2bffbbecdd2f338694c7a73c6ee5b601526de64509f604195d3acae9cf3a9da12b47f9d1a26fa3ef31c88e222562d1f513c4f5041b0a0eb8e9600e587b08e12a8f974dbd8e273efd6486170feffa04fbe461975d7bb0f72c25f7e1909de1f51feef11974fff694f7c743257b8501e00a0f251075d9fcfdffa173e34d6cf8f827d063c3dcf5c94f00824d175ec8d8e34f428c2f62f1294fde659b224becd3380320d5f52ce46c20eda2561f0c40da720a84d0daed430f0a234b21e7375c71236f18701eaff647fce277d70decc3ceb6e5f2fe758313c2f44ec2ddbbfb103ff1ecf3b8eaecf376d94e518934570a00af76389fbae8177cb8d5a0db6e20b01893128c9dc097bffbddccb39a149e50806deb7feb149d0c26347bd7d599b2e1b6cfacffcdbd9e801313136cdcb8f15e1db3a749813fcff32f7245ae0f978e00e9e5500989ef5758bc7482d9ad0942381cbc3680717cf02a83bf784a38fa4cd744e1d56e765a04cacb20250e6a213104ca7966a32cf2e50721d46acc6e9d22ac56b008925423958ff22442821f06b8125112631c75a9e779a4c62290a0355a38051e614158a452542a1566a7a60ac56fbed7bca7d00581e3c91f9b98606ac35df8beefbe2f3a88c999ed2c5ab4086da1d96c323ae2e832ebf57a010732c6b068c9125a5bb76649c411c3b53a491acd1be3f2f39a7be2f3284159b9050a8f763f377dbfc2df0f652b173c935292a4865aad4ebbdd264e62961f76189377dc91dd6345105468341a787e0061886eb6f07d9f66bbeb8c97d222bbb31c85fee840af4fb24844d65a3b8fbfcaf350346118b07ddb145a6b962c59c29289091a3333743b5d2ad53a366ee30715badd2e699a52a9548a823f7945e31cca93472d8a246ea5a856ab74bb5dacb5789e97559eee718de7e39f477c72581838689a148eae384f0edf534a528d2f1be769cf7c0a47de751877e8dbb9be752db707b7d29e6d93a60963c93887b40fe788a38ee6882547b0ff21fb1354825d37bc4ff6c93eb9df923b1706c13777a5873c12f40ed84b0c80ad57fc128cc5db3e4b7a431b5f0a3a77de41bc6894f8861b49eb354cdc61ea77d7b0e4057fcacae73c67976dda254b684ba798c4c630d456d42627893b396345be6867056942c5545b315da9e0e10c87569625ff4815935d7be1f92f73b54b0949176bb5437458c769ee8a28b9eaad0b30c1797b59d2e2fdc5ece63464fbefbf3ff7dc73cffd6aebe1933c06751fc742407d6494c6ec14519410063e4af8a47144aa5342dfc3a49a4ea74325ac2195228a12bcd0a352a961adc66aed70f9222f1e96f52cfb9c9b9b63acd964f1e2c5786108d2c34611ad5687348df17dcfc140fc101586e0f99024e86e4c12c5f8727e79f924717090200850d52acc35e63d0bfdcab4e77919d5a7266d37181f1f676ece15c7da3635c5b2952bd9be79338936d46ab5227f218aa2ac2a71c6959fe1fead756c427934c32d04cc3b7ff97367896bfdfd1db42d370006c1dd8410e854179531474747496767514a3137d7a45aadf6ea04e485f44a068731661e0b50deee8ea21083ceaf944fa7d3724c1fb58aab39d16c10843ed5b15166366da2d56e2085c7dcdc1cd65a4646466875da24c6122a8510f30d266001c4a73c96fd06511936558e0c94eb85e4b501f2fd0ae89452c4719c199e7bd69256a9851cbcfa600e5e7d30a771fabc6dfdd18dddddb64ff60cd9777f762d3b1ba33d2107e0be44261e197a87933deb6db903098e388ad6f66992b08a1745a49e8f48537418628210962c265cba8c89679ec1aae7ff09b589895db679d69d77deeb7e1cf8e9b773caa7df7e1fae60ef945cf977f3c115e6c82a7c019624eea293d8554315c641a4843302ca8a4faf3d396f61eb4d34d1774e273b8b722c5ab468def7152b56b07efdfafb7dcd0f8738f4591950b69b790fc2edeb556aa86e151b6b2c5ec6ccadb158b455a43aa1561f466b4b9cc60c0f8fa26dcacccc1cf55a056b7b3ced0ef3dd4b865508aad52acd6693a1915166a7a711cac3f33cc25a95217f0804e838a6dbe992341a58a90882806a5863687898d999393060942c2033c618922422e8b6175483cd1162c5a3230c0857d3a0d198657ce952a6a7a7088280466396c5cbf7a3d3e9b8fc8330248e1cd55ca7d3292ac9e6922b91beefd16e34a9d52b9834d921446750d269799f7e2eeef2bee59c815cb12dd37fe6e7504a11a706e905d446c799dab4092915511451a95488badd9ef73c713021ebc9a22ab2dccda859bff29f2bd071dca55aad62b52bf8e32b181eaa92c6315befbcddddaf2446f9824eab419468c6962fc79b99c5e8088b2daa76f6e3f6cbe330c800193476f9eff958958d979c52b45c40acb74f2f2f629fec937df2f0cafd51fe1f0ae97fb7e4bfed2cb7e891a477c05e62001cf37ffe896dd75dc7d4f5d7d15ab78eb8318745e08f8c30b462254b8e3f9e45c71dc7f8d147e3ef05c517f61ec994fe053f6bb09a4ea785d12946c70861b35d6df67f8667a6ecf5cbe90ee74329fadf05bb7a398c8d8d0dfc7dd5aa55dc71c71dbb75657b96e49525ee6bc2b3a45a1f062be9765a689d229148e5a3758af2438c312c59b91cb04c6ed840942654ea4318a3f1a544959262411414b7b9877a666e9691254b89d20412e791ae54204920cd8a6a196d8ba25c2e674411584be807c46982d506e97b1944c44501e6e6e6a85787320f6eb93c5fe61946d3ed1a2a9520c3ffa7a014d69ac2b3df9d9961686808a1dcf74ea743a55229bcc1c618c230c46415a173b851c1339fc485b7a91f6f0e3b0f090f4a082e2712e7e7cf179572e12e6b2d427a484f1177bb8c8e8e62d39476bb5d24d5e68a6e1004044105a35397472d1452e6fd5ae8ed1f741d83f8fa73184ea7dd444ac950b50236a539374363768e34714648e02b9412c449ec0cd66e975aadc6dc6c07a104c6f42052656acf3c876247d194bcafe57d728330ef7b7f9fcb7ff7c3a9f654e97663d6aebd874d9bb695206486e5cb1771f8e12ba9ec83feec9347810c7200ec58eecf9ab82bc99c42d6a0d374de3bc4c154179ef791a777ec2506c0d2934e62e9490bf98df785501f7cb199422f84cdf84f35691c652c324e61134220a4cd30ec3dfef085b0882c0290b73d4019c9bee4070cecd3cccccc4e7978f74e718a77bf32b73ba2ad45f9552a431e4648a25613a353422f240cabd44687493b1db66f990460d9410783d1dc7dc71de834c10f15028dc471ca1b7a308d79908dac28983590e89444c7984863d204df57aef017015a5bd234a5db6ed36eb759bc7831d21385b2293d85315ec60c93641529731854a628e2a83905166b75c12a24a58034a156af2004789e6276769689152be8345b244982e779854191535056ab555ab3334ee9979224890bac7abf0cc284f67fdf19d6beec59ca15d4321c665e24201f6721a90d8f30b9650bda5adadd2ec3a3a3186318aa0d39b894e72087ae723208a9dc5cb1f399a376f4de2b7be2f37e1963b026c5f33c6a618014d0989d636e763bc21ac64787e876bbf852628c066bf1fd80ad5b37b364e904b333162915da300ffe53ae7150f6f0f78f1f2cf4f4e7dbca2c4ee536cbcfa58b24b97b6e91bd7ca53d483a9d886baeb9956a35e4094f380acf9359bf35b7dfbe996baeb985134e38826ab507292d8fd79eba8eede9fddb270fb6dc7be57cdea3d2bfd41510e3cc41829de71d14363f9f98f7d1c3acce7f0e75e670cc21c742f4f40b6b353a897bef126bc1680c90a5172d9047a2deb1571800fbe4e1933c1953d0833aa4694a12b591ca814da45438b53eb7aaf324562785674eb8e3a52db73d3f02504c461e4d0b8b18f0f76ec23a9058a148748c928ae1913114826663162115b5d13192569b992c29d64acbe4dd9bf0438fb1f1a598a44bda76ec55bd5c8d1e2e3bb5864aa5824862108e63df645d5319f63bf4cb49b189a3fb44a29447a01c7b0cc24515d2344547115638a5b85aad82e933008501ebd24ca4f4324fbf218aba284f10759a8c8d8db17dfb76975c6a25a42971ecd88e86878789a2a8f02cfbbe8fcc8c826a35244d928cd73ea4d36d1523be33ccffce8c82fe9c85fefc9632aebd1c622ee7c654ab55108246a341e887689d309a1900be1fa23c1f8d20490d5648d24467f4ff16250a12b3797d289f7f50a422ef93effbd4ab0e0a35b5759256638ec017d4aa550406292c462720144a40e02b9aed3622ac6449b97a1eeca7acf4a7693a8fbab57f1cca78fefcb83cb253c6fc97f31eca51963c39db1573932e42b50789b59675ebeec1f73d0e3d7439ebd6ddc39d776ec618c3d2a543ac5e7d08ebd66d64edda7b38e698431e45efbc7db24f76438401bb1343a3cf69d0fbb90c65056b1d95b6b1a9735ce634c7591b588bb0f93bece187273d54b2571900dd6ddbe86edd4a7d62027f6404f6e090ef234104ca6916b96336c7f85b8d3629be10d96f64f4a9da99018567b1cf4b2a72e883fbda8300896c820268b0d2e51414d09847b6148e0928d902e568c0e031b085074681f091c271ff572a35d23841654d34da6da417d06c7789926e56c5511245098bc6c7d8de9c4518c7b99f2725973ddced761be57b10c78ebf5d4a6704eac425f98a8cff477a8e7928c80a7e698bd609edb6467a1e42bae26339238c1f041863a886b55e1449b86b772ff52c0f4149a2282a986aa2286264d118767aca29b716b64f4f1354aa0b2825ad7509bf3a490afac8bc00587e7d799ecbce1255178c7d1f56bd9fdbbfbc5fde8ffcba613efdad1182d1d131e6e61a5829b002fcb082b582daf02851a78b4d5352eb8a6e09e592a20d19ccc659503b7bc416e05ccb350ec2c063dbe4165acd06a12fa85543a24e8b66d265a45ec313d0d11ae5f518912a950ae4ca7a96d49d8f41d9f8c9afb90ccf297f2fdfaffeb12fc380ca90a2fe8842a0bce2983d0d0614c7091b366ce5d8630fe5d65bef60d3a6194e3bed71f8bec7cf7f7e0dbffef51a8e3df6486ebae92e8e38622561b80f0ab44f1e65b2c0e6ed4f02cbbee66a44b15ebaff727abb32b2c01893e50319573f27a329362623bd30c6ad8f9422590ff065ed0db267bd2d772149b3c9baaf7e95db3ef441eef9f6b7e9ac5ddbe3e8ef937d9e947b2765afa0b5199ed7f6143b8b258d225aad0671d20152b489b018e78554cec32b8c4521085430afa09753b41458894116c5a4b41518931b0179556089523e527a94cb95ef93c122005f7a48e1610c1814955a1de9f9b49a6da42731682a759ffa50d5d1b36a878b977868e1a385074281e8b1f52825f004f881220c43d20c56e3143089120adff3083cbf50fcca74994208c7232f009362b284713fa3194dd39456ab8528157fca153b974b90c3655cf267a55241c9bc72af8744e12b0f212cdda8437d7c14212c8de66ce13dd65a2315ced3ef092c86344d0843bf50cecbcfa645825045b56f636d61862d8810188bb0a093d4b128e985301c2144918b90a629691af7e68ba4f09e7bd52ad3dbb7e14b45b7db465843b3390712529d10a589abdc5c8213395a4c05c6ce9b3f791fe7416a84cba7c83dfabe27a9843e61e8b161fd1d24dd06be3098a40b26a1560da8063e9d4e0721044912b9f702866eb74dbd1242b70d3ac54ae1223c4a219522b3a6403850a036a6184f67e42e7c37977300cacf423fe77f7ff40240057ef19b927b964f4b6b43b71b13868adb6fdfc4f1c71fc1e8e810b55a85a73ef578366f9e218e3b74bb115a3fb8ce8e87624d7c30ceb16f2d7fb4c8eeaba3853130206137d761a2a843d46d13451de238224d5df14b63d2cce1d8a39cde211cf9112e7bd6db72175259b408e52926fffdcb6cbdf807a46f7e2b071e7820f23ed0719e74c25758b56a294f7cd201d48743ac069185918d81048fe726df224560ac2cc2424208d24693a9cb2f637add3afe6cedda07fa32f7081142b80899708b769aa424518754c72861f10385d5b89c80d459d856832a200e83b1d365c9f9d925f94bde660a8c456b1c0f6536b76fbcf1c607fd9a1f36e921a4fa64214bd2e0ad3a63fe9108e911061e5a48baa9a61b371032c5f32da9ee3863c17705e2d25697e94eccb2835773cfda5b9cc744240813d3edba6ada16851784b4db4d16edbf1cd5ed127522aad5ba7b81ea845ce712995719219df28e467902cfcbea1008813406e12b8c557463c7d6038e1ad6a699f2e72984e770ee08e8463161a54e1c6b9492287c48053a72356cbd40626c04ba8b353a4ba874918b91d121c0604c8236319d38a25a0f48744c16f14566c9c3d65ab4b1ae3fb2045bc9a20c6090c245ab300e7b6fb5a01a84ee7ad3cc7b9df1ff33053b0000200049444154e99379da531d83c415c033066b4d069dcbe689f22033a4ad4df0654a1237b0c663d39d6b597ec8e174db1da25823bd8c565382341a9b687c2fc0688dc90c1a54cfd8b0d652af5588a2241b9b2a5e258034a5b16d0b73b3dbf085464988d3988a1fd0e9b69061489c457c526b181a1a42678106df53cc6c9b228dba8c2d5bc6dcd414c2f3b15232d76a17f5178cb02418bc20c40881c4a2f23a16b9875f5a022f98e7bdcf8d37579f62611e401ebd2930b806120b5248e224a67aef66df832ad6429a26743a6d1a8d162b57f618ea86866ac471421c472459c1b73d5dd2d4e2edaaf4fc3ed927bb23031fa34151fff9d8ff5cf9cfb3097bfa7f06b5b42eaf298923649643d6835ebacae6168bcdebbbca1e14b9df987844eb1dec4506808e22b6df7413ad5b6fc174db88c92e9397fe9cd1931ec7e8b1c722b3456177a53967b9eeda399e70f2011cb8b2e612eac831ac822815ecfff4b389a33277b7c38ab51a73c4a79c821f751fe0ab7cb8653e7b494eea637482d649b1e08a2c329027f53a4b1a57042a53458dd9398402c0649cec2653947a217e6779e4c6c0ead5abb9e28a2beed315ad5ebdfa3e1db737894b729aff9b150a10980ca39f243198182125ca7a68a3315a38af75aa096b43c4710b1dc50cd53c462a2374ba2d94e791641cfc335bb7313c320a26837968537a871b8491ae76841518e1bce35658926e84b529caf3d0d642aa5d413d21098210b4757524c47c361827328b02495cf50d89b42e7ae4ab002b35523a784c71ed562085c2f3200caa345b335948d8591405738c711cf84e99b7e47eea1efcac074771f6a88b06482bb1e882310923c819ae724cbf33239ce49876630cc665fda27582b492c45a341e18832f05096e4c3d05be52a4c6804e326f7fe645cf232cd6f553a7a98b60e06046d20a3c4fa25488d109dd6e9b30f0095480d1098d2ddb69b71a586ba9fa0a6953a430484f228521f47d24bd8271dbb76fa752a9e00715f77e4c34466b2416029f999919174df22c956a952833f6b096fad050615ca51953509e94a7fa603d039fed0190aa790977d9bb43053e519c20f6b008804d5ad8ce249ded35543c856e4dcedbeea7d3a4cd4dd8ee164c340bf5dd2f6396b66fe29daf3a878b6f9ea3ee590e38ed4b7c70d5db79f1da0f72c3a74f01a03df975961ef36d9a93df02e0a2f7bc840ffdf40636750fe0829f7c873f9e70e652dcf83d6f3aeb4dac998ae944c3fccdd7bfc36b8f7394874208bef1ee17f1b19fad65e2ecaff3bd371fc5857ff3e281ed00fcf05f5ec779dfbb8e7bee9ae3959ff931e7bd6055d14e7fee4c395a78c979af1d785c3196bac9075e71323f5efe2e7efcb1d7b22f36fce8150b6408e379cf8145a3759a31e165f98bc2664e32452f0e99bfa37b47f747781f0d7ac79ef5b6dc81b4366c60f365bfe49e8b2e22fdcd6f90498a513e8d2bafe4e6f7ff2b2b5efc12969efa142a13cb0686970789c6278ee0aa5f4f66056c7a9cd2da0a9a5d8f276cbe98a4ba247b54dc3f93a6ccac59c3cc0d3710051538f34c00ce7bc573f8caa55772eb8699058bd9cc8d5fe7ac97be976daa8abfdf93b8e83b9fe2c0d03d78ef78c933b9e40f1b082a92345cc53fffbfaff2a2a31ddd94eeaee38dcf7901574d014b9ec0777ff0390ea92c7ced7de8d9ab78f72577f5f0b3bac1098f3db577add1dddcbc7e9ca4eda215ef7ad6c9fc6853174f19ba669c377ce02bbcfd8c9500bcf3a56770c91f36bafe04abf8a72f7e853f5b5dc313127c1f993ad6978fbef854fee9a71b99d972230889a7c25e825e6ad126c914a41d87b5f3c5bf8c0976b0888c2fdece9fa0fb64c7e2ee7de6bd16654885c41a8bd616b445fa194e5bb82c5be5fb5893627145b4acaf68cc6e636cb44ebd36c2ccdc2c7e584729c1eccc1c634b26502a7649b6264fceecf5c3180731298b3106219da2a6ad53b39d87d7a756ab11b73b85d7777e726c0fd7ed3cf1d231d0ce4b245548911140480fac70b9272a9bd34185683a41088ba702c060748ad602b9c00565dcb51417e4147c6bd3622c73d62b502e2a207bb4b6c57d28e513e8ccd3648c86123da6cb9b21a35b15e82442601036abc48b4560c018e6b66f438535941762ace825be221196acb85996e390e51bc4dd1863dd2218843e364de8440949b743bbd522ee765cb4ce48242e2c2ea5471abbe2698e1ad5cdcfbcb81ad9bda8554377bf2cd06cb274d912b4d6341a0d8220208e636ab51aa9490af626c822ac25034066f7dba4f3f313ca9ffdcc40fdb90cf93b248e229aad3623a3e3f772e63c78d258ff2ba6affd1a47fa33a8f5154e1c6db3f5d7d7cedbe7094bb6519fbc9aa3c3886d975d09c7bf9ae1554fdcadf62f38f3195cffec2f73db45aec0d8ccdd6d86165fc0d4f21732f3f1eb19f30457bceb9f39f903df2f9ef4ff7eec79fcfa038773db85afe494333fc3e435ef746d9df16c4efcf4f57ce984c534eef806cb9ff857bc76f3578a737dff84f772d5f9470120deecdaf9d5fb0fe3b60b5fc5934bed007cfba8bfe3f2bf3f9cd9b59f65bfc7bf9ef35ef0e3ddba9e9d1da7e30dbcf38c27b2f58c2ff0b3773f6bb7dadb277bb6f49bfc594655df775c8e1360736a4edb7b6f5bdc3b5651868ea69834769efe2ccc2bb199c3c4f6927e85224f7014f90bf951267b850170cd3bce25f9c31a989cc24ab04220ad41773a747ef2536e5bb386bb4f3e9923def046169d7412b2b26b2f8a942161a0b8ee0f4da6a636a03c89b50ec2921ac1e48cc71bdfbb94d9cded0c16000e4a60314b56527bca2a74dc7b609ef6dabfe1e51f7d2c87ee37b4e05c7f79fa1b78c6f7efe06f1fbb947b7ef2b73ce32f7ec9cd173c1d80935efb013e78c689780236fef2ff72d8535fc38bb67e17804bdff26c6e7deed7b8eedcc7f1bb8f3d8567ffc52fb9f98b4f9fd7f69a4fbf80afacfa187056f19b50c3ac59b3a6f8fedb771fc7cbeffe50f1fd3dfff54b3e3ce6c2ee73b77d8ba5c73f83b7b76e02e071af793fe79f71029e804dbffc570e3bed35fce95dff09d638ecb60c5873c1d97c73e5ff01de0c08ac10cef32fb24c1c69e9a726ccc5292e4e94d763fe7095a232e5c069505972a6e0e69b6fe69c73ced9e53d1d245ff8c21738e59453eed3b17b9b582b0addd525d5ca4c41320821119ecbabc874517ccfa35aaf333939c9a2c5e3e8b8433789181919214d131a8d598647c6885383f2156110924611699aba736032c3d9208442031848658ff73e4f28ce936c45a6f03aa88f870c02e29959301a514ae0b4d6ceab1721323c39b8173ec6901a8db016a96466286639235638e55a7a80331a9427b12633e38d53fd5dbb796461a1473297a2e014002a5bb95c34c2f5d514dea8bcef00568a928921c19215c953d99849a48030ac1077dae8240263f0142e51cda66863d9b66d1ba38b15c361cd8d6feae68a53f81ddb52a7e38c2897446ad0a9460918aed789e32eed4e8b6eab8935291241350cd0494a1a75a9547dac15f8be5f5468ee76bbf859e5649129f1391c27ff3dea264451c492952b3071541871610957eba85eddef2a330285cd14f92c6724a7f7ebf70eefe89ef427074751c4d0e8085279a4c99ec302b4e9a62b9838c667d572806db807a73d6f9fe50074c058666f6db0e9a62b76db00f8c75f6de1eaff7d5af17d6c650d388acf3ca5c59b7e7a0f5f3fcde70ddf6ef0b3cf1f5aecf3b117b8bf0ffd938f32fd8a6301a7b8bff7775b59febad3b920db6f584ecf3bd7275f78e4bcefbd763ec2f42b1f53b4e3b61d06c0e861e710cdbc6db7ae6557c7bde2c46359fcd73fe36baf397eb7dbdb277b93ec58f9cee9305c4439db5b647a7c1651b5c2606dea163693624c0ac262ad8318db2c0f4a646c85d6e2be0b3530c7c45afba8d03bf60a0320f9f9cf21493179e25e12a395c20881ad0478dbb6d1fde18fb879cb2407bdf5ad2c7fe63351bb3002d238248a7da414dc7e7be6f4b3062905a981cdb38ac637bf452b3cd8c116b254739d25aca646d2497b9cd34ffee3a72c3847be705db4b5c3e4f18bb1d6b2ffd3ff9ef52f3e0bfb85a72184e065679e58ecbfdfc96713cd7cb4f8fec1efdcc57b3f762c00c7beee9f597fe807a16400ccdcf2259efb89216eb8f94f19fbec0e2ed4a6bce3f3b7f0d6eb7a8bca92b1a0e85fa7314b65e9e38a6d2f3bf384bcf3ecf7f8d710cd7c843489008be7499ab77f933ffbec087ff8fd9fb2e4dfdf8ca72a857290ab485228a4271ce4a404a3e8971d25f0b889baf0d1dc11ffee8e3e9bcde60e06e591258543a434c4424ac7f4a202ac31782a406585a3e234264935caafe2fb3e491ab365d346c6c746181b1f67767a0a9d0a46461713259a28d6a82064e9b2e5cc4c4fbbda01bec21a5b24860a2111f494f49c5dc79233b6985e9130e53b4dd85a28181932a34ff48ec93dc4fd1e5f257d100a83445ae3203f59f26e2f62e4727930a064e0603726c91604899761fcb1024d4ace505518b1f9905a8b14ee597435096c36ce16838302b9f1cffd5716817489b1b84b0cc38a339aa4eb90cdbcf822f3a8d7ab21b3b3dbd1718cc2e2f93e51d4c1480342a1638b30364b9e16e82421b56e915342a1538bcca03171b78d94e04b81e77b082ccd99ed189da0b271353a019da204c83083270967581987689a67d0449d5651980c40c711491c2384425502b66ddc4810048c8c8ea0b5c60f02666767dd2d36aed08e10222be0e63c71d63a23ce1883d757313c1ff7b2f7bf1c1d2a1b074208eaf53aedb673d4c83d080234d7b22c69dd0a73533bdfd102db3be81bb73317f622b7bb4a7eddd1e6677ee65d9cfdb44fb1fefc9be0f4cf72f080a8b13b6f6fcc536bf9ee5557b32a1cbcefb89a3ff679ff72a857596a051fbb724a59fe4d88a2b49335f30da19d1d07fcfff6ce3c4ecea24edc4fd57bf435574226e19408080185e001222121a01ca282a05c2a2b2a0a2278022bb782b2c22a2eb2baa2088aebed0a3f2ed11545017551414405b951407367aeee7efb7ddfaadf1ff5be3d3d33dd3313822464becfe793744fbf6f57d77b55d5f7e6d00377e5bceb6e60e4b88554f4e4e74578f669a71859dfb6f21b786c8b66741eb3b699db3f1b4d9d30d0aa58c2b992264944dca863d334b3a2660e3fcac597e5da1f8b9b2fb5f6328b826a5a0946bb35765db229af3b369ed172124c6a482b25827a848e63f03589efe345114a6bd272091d3568dc73377ffdfad7a8cc9fcfacdd769bb4cd950301430365343ec619db014d80c5e99014e59d0f27aa05c4497efb3973bfab7f65d0f5a169f5ff6d5b5438e7e647b8f4f53bf0f04d67130ddede76bf3b3f75345b1d302a00dc39d860af6e17e01cf6bc8ac6c01dcd6d69fd318edaef42bef0bb3fd1eb757e2857df7f0e77876fe0f66dbac77cfe85d7eec3171e79844756f5f39d3fde39c6f5c21dace517171dcb56fb5fd434af25238f72f40197f09f77de419fe7268ab058725ac224214d72cd5f9ec1c38cae49ad75bed6584c16aca3334d607382f732ff699b0f126ac2c240e8441ea83e7a2ff8be4f582c3038308c9fb9b4dbcc6f3cf07d97c35d5997d5a55c64cd9a55543d9ffe2db660d5d34f33383042a154218e1be8d087a0401ca778ca05fbc67184b106adb41b6851e48154b900608c25f0fda6154d650b7d728d7ed3054c419eeb9dac1a6c76f7b46a7cb5d6585720200b3876e9679d07946d390fd9a2324b4f69312ee621b32a79dac515183376a1d18ed698186bad5bf09b3c72db0352543e51657efe8a51edf568ec8ccddc6adc35f07d9f30747ef9f5da081e2e40cdd7d0b0d60958da362b02371a0d5416308c49b1409c15c2aa542af8bedfcc3214f81eb5da08cb56fc833469a0ac4b7ba794c5c392e05c7894d5344c9c3d67ee358e475f8d7175203ccfc3a499efbee7b9a271c65d9b5a2d6ad65d68a409e572d9c50f684bb55a6d06ed36334859d314f07cdf0733d13f3ca7d505acf55ae4db6c9682358a2294f69a42cac6c0d0882519a8423849ac980506ebf0e400c91ac350f7f4c7bb4f2cda9c775cf6737e72c6fe807301eadba64cf736a7f0d6a487b7bcbbc1697ff8d698ef9c76c3635c73c4f63c7afd4798b5cbe9cdcfcf7ff95c4ebce2ffb8e5fd7b03f0f05df7b3c39e3b77fced4eed4cc6fe7d05ae7c6480f76cdfcba3377e64ea2fb4f0964b7f8e77c6feec7a58c2bdd77d8cee49e63c61e3a6e9ce078c6afecde81ac15a5096a49134add878ad56e014ad3469261f286c96dbdfa5285718b4352d615ca3d6053beeb6e934e6cc94cc531bcf68390949e8110e0ea17c8fb454449904b4c28421ba11e30f0e13978a686ba9fffa2e9efed6b7a614003e7ce5760cd47ae8ea2e107801b5c4a3a7a248521849a01c4272db5ff0ac4f9e30d65a5775d5e22673dda65c743b2ef9d9d738fe1d6f66e1c70abcf8d527b4d56edfffad0f71e8953ddcf9c0716ddb187f3b7ef64dfbb2d5bfdfcaa15b9427fdedfffdc0375878d62d133e3ff98777f05e9bf0cbabdec9a1075cc8aa3f7eaab9cd5acbfddffa306fbcbac2cf7f77a473f350f0e9a30e658b0bbecb41b33d1a59b9bcc00ff1bd80d44f6934926cd140a615f632bf3b179c93c9efe4c1bd792c5fbea8508c16f91975ba1201602a5cd06b6be62567eed49ee72ac87a01c6bac04de7ea5120cc023a87878729978b8c8c0c51085c5e7e92146b359bcd9ec7dae111ca5dbd04619178a886ef0568359a3ecdf35c8c0159dc013673d1d3da25ad6774e1aebcc00dd0da090cd66d44799abceaa3cb0c935992b2fbc153da2d38b3c07083721604eda19476c7d6624dc85d8c8c31a0326dbb76fd33f9fda80093dd6bf95a7ebc462a77fdcbcfab5134776e666e324e23e56501f1766c5bd65aeaf57ad392e079da656b520a3f2c50aa9459b5fc691ad52a61a049e308e7c562d1da293ffcc0a33652254da058715581c362884ddd35288665fc5083a708fd2c19421c914423c4f511c24240da8889d398c073751542ad31494a6a626729f034363584618124718b7e9ba4b8580745d2889bcf7cb1584461499384388ee8e99b45b511b172e57227fc284b4f77857ac3b98b856138d6a54ab9e0e2bc20a033d5b7af05909fcbb1711fa3ca8a344d59bb762d73e7cdc5a258b972e546930568248264b001412600d8e67fee25316ea7d53568a42475cdc83a940178c78d3fe10f6f7927dbef32444fa8d87affaf70c3a57b00f0914fbf82dd3fbc13efdb66ac4beaa1bffe57f6bae8019eaa6dced77f7245f3f3f7fef887fce1c877f1a22f25948879c1dee771e3240240a77626e3cb579fce814b1672c5365bf3e243ce043a99addb73f4253fc53feb40767dfdd9dc7be32727557c091b0fed5cfb804ced6a46c7fdd4604d9acd2d292636592c978787efa27db5cadc78f2405eedf2fcdb0463523459f240a7adcd7d129a8a9bdc29d3c517e6717393f77953e6792100146a11360c49c3002f6a34d3437a714c5a08519e26a847443ddd784983c1dffe76ca368fbafe3df4d91a450f026d093dd58c0bf795a561cb3ca6f6029bcff54ebb694ce62d9082694cee6f9adfecbd3b1cceb5b71f0e4075d957b8e19a23c63c080f7eefa32c3aed3e7ef4a79bd8a53c7a4916f584fc7a2862bfde02f5c15f11f6eed3dcf6c95f0ed1fba703987ff6e8efcd9f3f9f6ffee141f6ee71b3481afd8d536f5fc58d3f78d1b89ee50b33cddec75fce9a13b7003ee534a7caf297ef9cc99233fec84dbffd2e2fae648b4265f8d4ff0dd373ffd12cb870b4a56d775cc83577fd1f8b7a8b942a25ca5a435680832462646055533b88d628039eef72a0e7ab254d6e3e4bb285529e61484d107c84c97126f91477e36a3c15d2db338b465ca73e328cb10a3f28128621d56a95356b56a17d45a954c2d71e51b506e52e82c23085de3ee675f762ad476c5356ae5a45a552c0a40de7d2a20c41109244b9cfbfc6aa6c21a715d67ad82421566916d4ea70d75a81f69a76d7a6e0973976b6168a0a82a059802a37b592bd6a0d4aaba64b892bffee35850eb2eff95aa13d9ce6de8cbaf2a4b6350dedc47339c615a5e56e6ceeaffc564bf5044df6789795fcf89bd636a558bd7a35da26548a151af50445ea3214f98a284d094245b556a31eb9aaba3d952e2864d98b8c813465d5cae5d486472814ddb98a6a55b0315de512711660ec65c1d979d0b7d6ae8a773d49f094f39ff73c8f388e09c390382b9e9634dc22be5028b86b949aecba78148a65e23826f07d1a5144b95084d410964ac4719c598ae266dd82d61880fc7a061db4f6e3b303b58b0530c6a07c9f356bd610359c2564a3c102d506142267f5321692946645b74602f5c409027196cb741dd61d7e7901975ff74b2e6fb3ed8eab1fe1359fbb6a6c77b2f3f7e636fb07ddbb73e52dbf6b7f186d16436fbee4fb6ddb69e7ca95b3ed6117f097c32e68fe7dcd7913af6dbbbf5bdfbfe9a21fb744bb09cf159dfce4a7fa4eab303fd685cfd5257149435c555e9338f71df7dcbbd4d6b955c0242a4bc9e0674280c1cf5c338dcd3313922552e8dccfd4e6c7925b62271edb4c59fcc3f34400487d9f340c08476aa0156918643efb16bf5a23e9ae60b442590b9e26ae8e4cd9e6aa9d8f22f22c255f13f899595be96c0076fefedd90070780724189699a1227163f49a98d4c2f0d68fd1fcb296e3e176c832b4ffa04fb9c777373db43df3f93bd4efd3537fee916f6ec1b5bcfe0f437bc80f3affe23fb7df0e5dc77d5c778c1a1e737b7ad59b366ccbe4a291e7ffcf1319ffdede693b13b7d823dbb47d54a265ece9fd774f192b92e46e2c11bcfa57bab7f696e7ff07b67b3e8037771eddd3f608fde2cef60e61fbdec6f0f8d69bfd03397fbeffb0d80734f201d5dec684ba015e54a37da73c1859ed234e23a8d38a210f898dc1fb8e9cbe7dc29725f704f7b6d27c4bebebe8ee7fab1c71eebb86d53458d2fa0d2bc67013441b9829f141819aea1bd80d858ba8210740d3f0cf07d4d9ab8457da95462f0ef7f476b8fd5ff584e2d4e3028b67ec136cc9a358b8181357455424c6aa8d75d412d3f4bef996beff3e04f976848e367da71d77e996ad4c058e89bb519b5bacb35dfea0692678ab18aac626d48ad56232c16dcc2316a108d54d962cbad58b6fc69945204051f63623c4f1106058646aaae5aadb6142b4597c6d624680ffc209b386283324e23deeaf39e6ba6f38944198bb1a3e9802da3b9eab5d62e68b611512c1689ab556751acd5080b3ec56291fa4815dff3b0d6590ebbbb2b14cb6592468335ab9613fa1ee552914221a43a3cec7e576579f0554262128aa50295ae3e2a950a7f7ffa49aa4343f4747793a64e0991da84c0f7d02ac52631a411d61a1a914b8317780aa33cd23826362e2b52e807f87e80d73269d66a352ac552b3b26fb15824b275cae512836b0728145c06a07abdc6ecd9b389e27a967ad3e5e7cf83729f7ce2097a7b7bd97cee3cd60e0e8cb9b67e56c938cdac46b98b53a7c23ce3ab0be70294e779148a451aa9b376595cbd89e927d27c0e889d6b822b5660204eb3057f92fded2c6ec4061aeb9ff12c5a7b2b7b2e3e8991598770ef61db3e0b072008cf8c4e9a7f2704e4027c4a9ab8ac3d189b950855e84c91e45c825397b8824cc3af3cb4f226280733db6a73fa6b1adb5afd7e9406eb35838795b22de37ad324d95608d814d71dcf0b01c084017e2341594b522aa11b0d543d21a914098646f0a288a45c445905cac7db69a729dbacddf923541c91789a0057d534cf376e6d96df1b70c12679f05e4a6a53620c516aa8a516f820005f5ab40b173c3108c0d65b6f4dcfb6e7f1e73bdf03c0e3d79dc2a1973f40d1d6d9e990b3b9e9e451d3eac2632ec67fc1ce9cfceabd9a9fddfebb7be8f614fb7ef106b63fe40876bd5a6167bf821b6e9a18683c19579c763b075fd56a9e35987819a71cf26a56c71ecad4d1735fcaf77ff945777c585e7aeca7f1b7d989530fdeaf79066ebdfd36ba3d35c17f0ec6ba3a189b8c2ed80d2440a552a6a4031a7184afdd83d74862e2340f0054608d33c7299c4f7596d85e691fdda6d2f3dab56bdb3e8c4f3cf1c4d81ce1339236d9978cc6a496b973b760686810303cbd6c39a1a7334d6fd4f4a74e6c82b22ec033c9526ef6cd9a459aa6d4a208c8067093176ecaf3b82b8cb54eb3af54166f9062adc1b3baa9c1cffdcbf3c5629aa66817f43161d06dd598b7be2aa548ac419b94b054a4511f72ee7ff53ac57299e1a11a5e186402c9681a4ab260e4c4a46ea2f03dc2c0274de351ff7e0cd6b88ac1b9852ad0a3992226688bb4228a1b148b4556af5e4da552218e637a7a7a28964217bcab5dd5e320082894cb602d036b56b166cd0071a34a29f03026a15a759af6248ef002ed0a71f901b55acc9cbed9a015c3830368528a85006c0cd65941ac312e6620d559268c2c2b46aa413bf3b706ac07364b679a5a0349e26a07a8b15aba2449882257fba318baa260ad8b73630c5114e1fb3e8d38c1c429d618bc3074957f63b7480fb2625e8d468342a14018864d8ba0effb2edb90f1c72cfa73c16abcef7f6b705ea3d170f752bd4e582a4f101a3616eaa634bad08fd31601209df059bd3afd4aa89d28f4bd9a7bef7b68ea1da741275fe8d6e06c61d365b26b3c9deb3f5e0068b506e449214cdac0a629d624a82c465069ede2ca32f7206b1456198cf1b2b12740790697b9ddb900a96606416705309990d18c25544ec99327586e267460e271741a4b36c575c7f34200200c204db15ab9d47a718acafc7b6d5e8c07850a3ce8ee63cea27da66a91eef7bf979eae6e822024f00b785e88525e262d8e1f88f32a9d2969da204e22e2b841ba663455da7beefc33efe9f05b0b4efa2e0f9ed47e5b35e97ce3f8a51db9fa677f9cf258a0bdd9eaa287d74cb8b9fdf28bb9edb7f78ef94e5ee5d85acbdadab0cb2b9ea6f89aa6b9be1df5e115cdef8dff1da514f57a9d46c3b9130499f5242814295b4bb5368c4293663ede4d13795684c9b9cb769ed457af5ecdecd9b39b7f3ff9e493a30bbd1948eefa4ff3257727705579d121f83ee50ad4a3116af50669a02815b20c37cacbb2b658e22402abb1f858a5e8eae9a6de70160257ccd62d303d1da0ad13f426ef9b0b7e554ab90ab178f8fe68355767f571e920c74c1a5930b9c9023d6d565c4e07990639b554cadd248d2a699a3052add3dfdb4f6dd5203dbd5dc451c3dd434ae3fb01da737ea66992909a5cd3e46209c069fa730ba03559d6086b51ded845a82575c1c74a65a950030647aaf4f4f4b8a0de20a5d2d3c3aa7f3c4d312c50d9ac0f8c21ae5659f98fa7b3980097a922f07cb4561893104511954a9938c9026a1b0d423fc0f3345d5d5d0c556b0c0d0f50f003c282469b84d4c4785ee0cce9c6429ac74db82c43d81493585775384f0b4b96ccc01a4c9aa513b52e3386e78d06d27a5926a96a75046b2d6131a4dc5dc218436263aab5617c2f447ba1531f644b5f2a1600002000494441541a35c82b1127602dc56291eeee6e8606471819aed1d3ed1212d4eb75baba7a308d688cab55ebb9ce8580388eb37a07a3dbc330447b2efdecc63801f76f3d9f5bfe9f21480aee01cddc199c76b2e57d16f8187b3dbc7cc9fc0ddc6b4178766915e27325823129691c3717f92a8b616bae22d2341bbba165467359e4ac8158e379c6657d33495391942ffa555673a55935d8bae424e83ce5706bbcd1f83a239d8f65535b773c2f04005b0c49c2007ff5804bfde96927c1f91ed6d324e522a65c4415bb98f3c6c3d9e675af9bb2cd65279fccb2d5ab51c6693e73dff3341b93b552cd3ce49e1aadf49947a227d6305228b078e51429de3628a67933b7d5e4345d769ca96da209de49deb969acd956fefd6c3f3dae8086522ebcc70f0ad4a3183f28a08390281aa65008a8f4f43252aba2b475d95314cd81206f17ab5059b0692756ac58417f7f3f4f3ffdf446b900d83064c54e5af03cdf9de3d8e085455454a3bfbf9fc1815544718aa77db4b27859855f6b8cd3e22a9bd5118849d2067ea051267045a38020085c4c8c72b52054f69ee6bda6c8ef16930dc8f9606fadcb32130401665ceef6f1da5e638ccb7093ba367ccf234e13a24683ee9e3241a144343ce802c6b587f602c2b0d84c035a2c75e30710fa3ec626245183a856278ed3a666be79deb22056ad7d172ba0d2e633e13ad79251229ba094b5944a256cea82675510f2d4238f50087c962d5b466f5475ae337142ad36429224148bae705e234b77688c1328acb578beefd685b885f4ac599b616c42bd5ec526715393a5006c9299c3ddc4680cf84aa37c854eb3425b262bb2a69da5c68d619e4bb79a1d569224ce02a435a6c5d20250a954a8d7ebe441e3d6bafb22288454cadd4451031fdfd565c8c6d35cd81b1e1ea6afaf8f95d938a9b566c58a15542a152a950a43434394c38955dc5bcf795e9f209f687ddf6f0a2a9eef536bc4636a466c2cbcf290a378e521476de86e08c2738e93716ddbe7d1668a89344dd1243895ab72be970667a5cdc75b0b4a6b9476a99e532c364db0569124d99ca2dc67cd18035c4a63ddd6429127a2354d57a4b6fd9f440ad894d61dcf0b0120dc716746d6ac262e94f0a388c40f5cdac94201131660ce6614fae732efc083d9f6d0c328cf9b37659b873efcf073d0f3f5637d4d70d36e8b51b37ef3c6d70aa346fda13ba19aee1ea38ed34eb9a508c322b52876f9da719f29e581ef1386ce2fdb95e9762e3feebb1a9b05b1a68c0a1f9d58b66cd9f35a027f36b12d81b6363fa776b4526f6c2ca18562b14c39ecc2d806c38383cef0920546690d46593ced027ad19681c1d5282fc832cf68e25aec62343c1f132728df6bba70b5130072cd0f9916dac3059a5a9c66bb1a57dde0adb3c1b4c5215f29854df33807b7ddf3021a714a6c628cb154ba7aa8d51b846109f0a874f7e187250acac7e0512875a13dd73f4d40a802b40ad051a655c638df50659ba96a9532d9a4034d0d91324de1d6ba1cb628e5dca806478699bbd91c962f5f81c6a5ee1c1e1ea6bbab8bc1b503a4694ce079142b254ac502711c11a7297ee8913422149642a14094c404810b9c0d0a21716ae899ddcb9a556ba98d0cb9aabe71429c180ac500cf186c12a34c6615c5593c146459ca6c33bdaac9ac1b26d3aab9cb6428787e763d9cc62c8d130c6ef276597c5cfd01a56c331350a150689e13ad35811f6263e79663b0f881b3e60c0e0ed24862fafafaa88ed4191a1aa2b7b797388e59bd7a35ddddddd834695eebd6588166dad0ec7e0ac3b0e93a66b2f4a7f528c22f144993044fe92cbdabf06c30d9fc22ee3f9b3e535fff6cbcb679d57697fc019b6bde7536b734d540605392b8814922fc2cb65267d66beb34af99f26fd4aa67acc96a35e6ae9c6e3e70638c710aa9cc97df5523b2284f372b8fe78a0e5f1957eb241b570a7e00ad31002d6b98a96eef4d65ddf1bc10005e72eef9acbaef3e56fef13e461e7984c6d0201645d0d343d7d6db3067f7dd99bd7021b376d9856063ca02b19131954031d6fcee165c4edbe850a34239005a8dee0f6469b5f2f7aea05aa15422b596384af00ba1f3136f4454babb195cbb3af352c9cc6f5a659672afd9863035d68eaeb9edb8d46679f61a6b200c3da228a1502c8089e8ededc5a629f56ad50da459f566a52d78591e7f6519aa0e512e7711aa00e5392dab6eb936f9206bad1ef3fbcd3d94c21a9b2dce94f34137b82c33d9826e7c869d560bc0984561a671274b4d1ba79652a942a9d2a058ecc21a4da5dceb52a0ea80515d794c33efac2ee0970af821600c23236bb136c59814a35c7c8313164cd342a694f34dcd17bd36cd2609a518a9d7d87cf32d59b9ec1f602c6bd7aea6522a337bd62c464686a8940ac4b17363a90e0dba6c38a147e0794ec8020c1a2ff0896b0d94f23158c24288978920b55a95244928178b349284346e38e18e943431183297489b65c5c8ac2dce8569540b97e6826116acadb2670de38416574b20695a37d234657070d06589caea1628e552b71a6318181ca41896dd671692cc55d30f7c3c14d52822c952fbcde9df9c9ed9b359bd6c19beef53a954a8d56af8e3fc705baf7dbbcc3ff96beb366b5b04d08d946ab5caea15ab99b7c5e604e1f362ea158429706997ddb898656ecb1fc12ca7cae8e2dfb951bbe28da0d568d1af31599f725756afb502fb28f968a6ac733154d6290a9bca42a59af3d0e867d9989e69fd8db599d7c1c423da98c790679be7c528d4bfc71ef4efb1c786eec6f3905c6b3afa6aadcbcf0f99ff5c26c5b7fae0363571d964ab6d66321bd7badb6c9a5682fcc1d5284c1603306bf666d4ea35ea8d88eeae32711c91d41b74f7f590ae5983df7cd85cbfb44db1e8ac98d268de7661729c1090d75c68f930fbdb25c7042fab949a1a83e7fb74f7f6107a017123228dea18e334bcce97db9257496c2411aaa629842161e8b4bd699ae06581dd4ea9ac9a8be2dc775365b381d61aad3c1a7182e73bb78e28751a6badf568106e1b21d5cb2ac85a9b89984ab90c3f68b4e732d07475f5e17b052c7e66f90093e22a525b307634a394ce634e3c0dbea1642a2e4b907679ed31c9847bddf5696c555a93590acae52e468687098280463dc2f33cbabbbb191c58833229b1712e3f85d067a4360cca10662935ab232304a1cbb91f25317e1010671a71cff3e8eee963f58a154ecb9ec53ef8ca09cb264bc56aad729977ed683ad45631d09ae681030aebe50b66770cf55a83a45e73ae5081a19199d37d5f63b3c25e4110303432dcf4c937c6d0d5d5e55c9b12e74ad574f3525970776631191e74352656ad703143c52c9350ad5a6f2edadb65fe715626afe99ad8ea06a49422080277beb27a0e9eaf996669960d42a3d6e0fabffc80644dcc1e0fedc3b6bb6dcb963b6dbea1bb256ca44c15d4be512c54f331079a2b75cd38a5943118eb9204d824c9ead1a4139455ade4092226a375ce6877aec62b35f3d7d66407339d8d78b814d6d704eb162ade845787760bf82cf0d269d48c530e6a97862bd001bef2d1784eaccffe29abb35cfdcaf94a7bae521fdac3a0488d75019a950a8d28c2539a4aa94c92a6284f13968ac4519dfe7973094b45a7354c0d3e1e3a2b3ce4e3e10521da9fe81f2c4c07e7fe03d95ad78346047e00264df1fc8038b604850a5db3fae9aaf4e28525172cac03940a30d6557b0db34c2eb5ea70d367de2a8f24b5a07db47669d9f0345af9cd0c2ece5ce091a2c0f7b1da7d2755ce7f3ccf0c6495e7f6cdfe19ad31da656b304aa1fdc06571c0b569b547a150a254ee220c8b24b1c5f78b90dde38d865b4047b17b75939146eb00ed054e5365703efe894117cb04c5327e58c00b42ace7619587d11e4639ad798a25b5ca150234ae2099350a6b3c2a956ea26a8da18141d246cc66b3663334b89662e0e3076ee11e45ae5a6e100404814714d53126a5bbbbcb05c1a369d41aae10576c51f858a3087a66b17cd94a0a8502854281465c4769e76293669a7e4fb9f3ee6b2f6b6b74f23399c93bb586d4ba180985cb7866acabee5b2e97098a052768e9d189516741c0f9df699a522c1629168b2449d2ccea64ac2231d6e5d8f60340133752a22445699ffefe79d4ea0d56ad5acde0e090cbd7dfd54defac3e4c6a51da6f4ec879f07092bae26ec65a92d4a506f68380200cf17c27e42549d27449a2c3226063a2abab8bb9a5cdf966e54b9cbec549dcfdb7df8e0a676d685ddcb4fb27081b129b3d9fa6cdbde88a331ad2a4411c4734a21a4954274e9ce2a835d670fcbd3c3620b7f3bf312ecbe3bedbaa54e89460a0531f5a2d909b3acf0b0b404eb55a65c58a1594cb658ac522e572d9e510cf5857bff8994e33cd9e05483285b1cbd6834d5da10d936b22346441c3ce6543834ac9a3e8739452e029b7945779f5d696c049e37c07535c7ac4c02f6043f77ba44ee3ece980200818acd7a94575162c58c097bffc65162d5ab44ec777e79d77b260c182f53e4f1b3ba31e1ecec5a6c9b800acb0947fec2c3fbe5fc61a8b523e4157486fa1c2c8c830f5ea20711aa135144a1e264ed05842dfa73a344cdfec398c8cd4b02a20c1a3e07959c619779f58356a0d4aadef329ce07c4455a94c0a8c440d50b0767080cd66cd66646484288ad0da4369b7e8f4b5c60b031ab14b2f59a9b89a032af3f3ce03d7fd20cffcee8eb75872c35a397b1dabe670ae43a3957c3d5086541b088b286b48e286f34d756a75775c6936e1983c3565e8cad02b0f8c47bdde406b0feba544518d24a93bd798d4e9b98220208a534ac522b5468db050208e6bee9ca496b217105948636844262bbaa5612462debccdb3a0e59852a1884d63d09a72a948757804f7346a94b14d4dbce77928cf0958411030303448dfec390c0e8d80e76a7058a5083d8f5a14512815d12886ab2354ba2a586b59bb762df3e6cda35eafbbfbca2842bf401445c45142d01732d4a83167ee3c962d5f49b15864b3feb93cfcd02384c5023d5ddd0c0c0dd28813b4ef530eb2ead3233566cf994bd448488c65607888beee1e27502ae8e9e9a1d688a856ab747777a3954b895a08345e1010558749d394d0f769c4315d41800a034c4a56bd78e3238e63fefec03f78eca947a8bca887b437e2ee3b7ecbc23fbc8c6d76df7243774fd808d9d8d7324a652e8cd958a2c66c53d834b3da258d2c70d7b9ebb8c8a4b196fdd6b55bfe7eaa807e6b469ff5fcd79bbdb0cef239361a2d9b1dede8f666e6bccc65b2f57526ac3b9e57024010040c0f0ff3d4534f1104012f78c10b983b77ee18a94f983ee3cfd718a9398554c563aaea8ddf7f347866f4fce74245fef06a9734d16d1ff33d4b23cb075ea974a3b134ea11f56a4a14c534929452b9821f16d87df76d00f760ad0b0b162c60f7dd775fa7ef3cff99ae512f0b10559026382db22e512866d9a0229c5b4c64280441e6dee139571334be1790d8240b1c7519659ad9839c8327ca0fd0d922d40b030ac532811f6081388da9d7dda2364e0cc62aa7c1d71e9ee7ac3e5a6bfc20c00f4653423abb725e7b205bc03f134366cbad6cd1a0023cdf6230788d3aa9b1993b890f2601eb39e1447928e3ac01da3a0d398582cb695fab83892984016121406b459ca53075c5ab1471236dd13e392d76524f486cecd2917a50084a1863a98e442c37cb98bbd5963cf9c4e354ca45d6ac5943a910e01702d60c0c522a14b0b1b3b829e342e03ccf47fbd939d16e513f6bb3cd583b304ca95462a41e512c9551ca63d5aae5f4f755881a11e57217c55289e1911a41e0512a77b162e54ababa7a1818584b4fef2ce22401e5d1376b168d38a5aba797c1a1218ae50a699a323038c4ec399b512894181e1e462b9f5abd41bd5ea7afaf8fadb6df01e298356bd650ad56d19ec7ecbeb90c0dac6d16555b3b34481886f4f4f632323242b158c4f35d5c4462527c3fc4f3523ccf23c8dc89d234c51a85d61bdf1c30b86a88076e7f901f7ad7f2abbd6ec57a8662b58b9fef7603834fafe05f6e7e2fbb2e7d09aa3cf67beb3a9fb5ba35888b83f0cfc6f9f7b7d7967b0a5265511834ae9022d636ab91b7bbb5c70b01eb72ff4ef75919df66ab3bd0f8d77cedb029af3b366a0160e1c285dc75d75decb3cf685effedb6db6ecc3e4e3b25ac3f0af0c95cb89b7746bb47b0d3636969c6e94fa845e5189ba123cd2284d2bcc142174161335a9d7e0ad9bf458b16adb3249e73e9a597b270e1c267f4ddf5a1ddfdbbd1a33461a597b0d2db71975a1d74650e797de95601afdd80925ff524862436cd4f035d2128b8cf7daf82df26814bd2cc10da7a778daf3c10f3eca1094bb3a7dcabb5abb506746fb193ab1c3e8e429bcfa6627c3b3560b3ed9d105c6a51168f5b2f4ec9bcaddd6b4fcb677df3c7ee1302edd2283c93d40aa5369fd5b26094e29c2dc654eced9dd3fe7b21d3a375ccd8d89ef7a0ecb3eb41bbb02bbb0067bb0fbbb28d5bb9973a3577a1d7836ab54aad569bf05e10361c1a740115169ccffe147b3f5391b5ddf7c68b04e3f7e9a436caf7ab149e9feb8e7561a31600f6dacb55c7bdf4d24b37704f84e7330b172e6cde4bcf2572ff0ac2738f3cef82206c6836d438b42e6cd40200b84175633f8982d009b97f0561e620cfbb2008cf17240b9020088220088220cc204400100441100441108419840800822008822008823083100140100441100441106610220008822008822008c20c4204004110044110044198418800200882200882200833081100044110044110046106f19c0b000b172ee48a2bae78ae7f5610a6c515575c3169f96eb97f0561d3419e7741103634538d43ff2c9ef34ac07995441954858d91a9ca77cbfd2b089b0ef2bc0b82b0a1996a1cfa67f19c0b0020e5d285e73772ff0ac2cc419e7741103645240640100441100441106610220008822008822008c20c420400411004411004419841880020088220088220083308110004411004411004610621028020088220088220cc204400100441100441108419840800822008822008823083100140100441100441106610220008822008822008c20cc25f9f2f2f5cb8904b2fbd943df7dcf3d9ea8f20088220088220081db8ebaebb58b870e17ab5b15e02c05e7bedd5ec882008822008822008ff5c162e5cd85c833f53d64b00002704ac6f270441100441100441786e901800411004411004419841880020088220088220083308110004411004411004610621028020088220088220cc204400100441100441108419840800822008822008823083100140100441100441106610220008822008822008c20c420400411004411004419841880020088220088220083308110004411004411004610621028020088220088220cc2044001004411004411084198408008220088220088230831001401004411004411066107ea70d0f3cf0008f3ffef873d815411004e1b960fefcf92c58b00090b15e10046153a4759c6f474701e0f1c71fe7e0830ffea7744a100441d870dc72cb2dcd8941c67a4110844d8fd671be1de202240882200882200833081100044110044110046106312d01e037dffc375ebbcf5e2c59b294c57b2fe25d1fbdacb9adbfbfbfedfb67cabab43159bf3616d6e79c74faee336db3bfbf9fdd8ef8ea336aebd9b8b61bb27d41103af3c5a30e61e9d2a52c5dba94fefefee6fb438efae273f2fb379c7d2c2fdf675f0e3af4cce7e4f7729e8b71c7a6c3cdf3b974e95296ecbd235b6cb3c794db002e3de958f6da6d8729fb79fe5107b364c952f6db6f097bef7b2857fcf4a9b6fbb5b6535ff14b0e7bf18b38f7bbf737b7e5fd78e51efb72c1b71f98f4371fbff6080efae2fd531eff861edb4dbc9a4b4e399297be7211fb2e7915effeea4313f699ea3ab4d2dfdfcf4e8b3f3fe6b32f2ddd69c25a685dcea5206c083ac600e43cf9a3d379cbe7ebdc78d32fd8a92f041371ebd73ede76df9ffdec67cf7a079f8d7e09a3ec70dfb95cf5c49b78e7b6dd1bba2b4d92c46ee82e08c28ce6a4efdecc49d9fbfefe7e6ebbedb68efb2689c5f7d5b3fafba77ee5a7fce1a97fd0e3ad5bbbe3fbf2cfe8dbfaa2bcae31e7f39e8fefcb894f7d6cca6d008b8e793f6fba7021afd865db497fe3035fbe9e8ff786000c3d7a3d3bed7b0427feedff3aee3ff2d44f79d3feef65f1676ee1ecd76fdffc3cef4b7dd5edbc70b76339ef987b3ab671cba7ffc889d7bf70d27e6d0c5c77e2817c63f8eddcf5ab53296858beac3e619fa9aec3785e3f7019f78ebc87859580b8fa273eb3fa0dc0d7c6ecb32ee752103604535a002e3fed7b9cfaad8bdc221b401778f53b2e6abbef7efbedd77cdf18be8ff71f7910fbefbf1f7beff306befda735cd6dfdfdfdfcf4b3a7f2ba835fc3cb5ef24a2ebaf96f00fcf0b843019a92f3faf42b5a7527c71ff42a162f59ccab0e3a9e5fae8ea6fcfda9b64d764c49ed41ce7ac7ebd8739f252cdd7709c79e734fdbe399ac8dfa8adb386ac94b59bcff41bceb9337b63dee766d4e76ace3b9ec3fdfc0c5c77daeedb64e7d1bff9b8f5f77388b3ef21b0056dfff11e6ce9dcbef4762002edf7307fee3c9e1695d836b2f7817071db03fc7fff7c3cdcf6d3ac27fbc7b31879ff36dd28e472108c273c9f8e7f5d16f9cce41071dc87efb2e61af256fe4db7f9e7a7c07f8c5a74fe4652fdf9bfd962ee6f527fe1c80e35ffb1a4652c3a1afde8f63cf758ba4a9e68fd6be8cff7b7dc7d8fc373afddddfdfcf8d179ec0c1072ce6a54b8ee2b6151317941db109e75ef330279cdf46bbdc66db2b97be8a6dfbcb53363b3b5bfc03d4870729cc7969c77d871ebb89d72f3d99833eff93318bff56a2b5abf04a9d17f7a6f1772e5bf5328ed8ac3861db64e7b8d39c30dd3965b27bab1d69e3ef7ce8e6bf71d27fbc9342b6da993b6f629fc730d935ca38e9233b72ee0f9e00e0afd79dc58ea79dd871dfa9cea5206c28a6b4007c6f658ddf6fd5b5ce0dfff751c7b0dbc5b7f3b95d6733fcd71ff0e283cfe6983f7fa1b9fda6177d889b3eb41d838f7d955d0efc10671df27d5efbf5eb619cf669e9d2a56db55153f5eb2b47be8bf0d41bb9fdf01d78f8da77f3ba23bec45f6e3b75d2df9f6adb64c7f4df47bf89075ef379eeba7a0900034fd5e8dd6ae2f14cd6c655479fc49c337ec8775fff421efd7f27727d9be36a778ea63ad656b639f073bce68c1df8c43d2771ce4b371bb3ad53dfc6ff667dd5753c75ce77e0337bf0f015bfe4156fde86cbee5dc555af2cf3f96565eed9b232ad7efd78d77fe547e7ed0840ffe96eb03eefe8d7b26affcf72eda9fb2108c2c643ebf31a2dff283f7aab1b3f061ff901bb1efa318ef9d3a80b66a731f4844bafe396479f62bba24f75790d80affef02713ac0e53cd1fe3c78ed6bfaf3ae4c5eb35c64e871b179ec52de76ec7a337bc97438ebe8a077e7a32d079beca59f3e0bff187e0206e6c33774db66d3a5c75f4ebb8faf1c7796ccd1cbe72c72d1df73b70df7773d835bfe5434bb79cb0cd29950ccb9ffc1bfbbdf3620653dbd62ab3eabe4fd077d0873af4a3f339ee34276cbef8edd39a53a0f3bdd5eedc476bff976a6a18b8e4ddec7fef53a8be1771e6e597f19aad2b74623ad761fe9b3fc903affa121c77095fbae4013e71e77c5ef39167762e056143a1b6d9eb0c7bf70da74fd870cb2db770f0c107b3dd16f3f8fd939d4db3fdfdfdac58b162c2fb9db7da9c792f1a4d3fb462e55afef4c7df37f7fbebb2e594b40252e6cedd9ae5cbff3ea18dc998aa5f0bb6dc9c3b9e789a3981c6c42bd862db452c7bfac169fd7ea76d931dd3822d37e7d6c79f62abd0eb787ea6d3c6689f57326fcb9ddb9e8bf16d4e76acedbeb7f2ee0bd9e31dcb78e8f7ffc91673a77fcd467fd3f2ea176ecb97ef7f94cbf77831275d7f12c79cb91b3fbfe42ef638b69fbfdc79c2b4aec1837f5fc62c5f37ff7ee3823e66bfef5a2e3ee62513fa2e08c2b3473ebe8f7f0fedc7e0f1cfebcabbbec1072fbc8a2706123cadf8f3fd0fb17cd953cd7d3b8da19f38e425dc3af760de71f8eb39e2f5fbd2958ddfeb324eb61b3b5afffe678cb1e3e7b9fb9f5ed66c63cbf98bf9c75353fbc2035cf7e6857ce980ef70f3891353f34db66dbaf322587ef3cd5379eb7fcde5c1dbcf6bdbce278ed8892fae39843bbe75269596f973fc187ff7f73eccf1dfde853ffccfbb27b473f391bb73cf253fe7ec17f64ed836d939ee3c274c6f4e99ecde6a4775d9556cfb927fe52d57dece65872de0915bcee480330d8fde7371c7ef4c761d5acfd31796ecc4ec2b3fcef927ace62fbf38b9e35a68aa732908ff2cc68fedadbcec0dff3eb505e0c83925ae797a9853b659379ff1d45abefee35bd966dc8238c73dc0001ed626ebd4f674fa6568f52b5728c60a0a93fd7ea76d931d939aa6603fd57979264c75ace399f3b27339a177273ef0e3279f61df141fdca5877fbff737fcaf772c976e7b12fadee378fc1babd8fe842ba6ddaf7cc2ce3978e9ce7cea873fa27ad48b296bd19408c2c644ebf3faf663cee0b8eb7fcf312fe96f2ef25ae934869e73d33d1cf6cb9f70f3b597f38acfddca03b75ed8f6b7a61a8bc68f1dad7f3f1b63aca71406e7236b4d6df29dedf46298d2c6537cf457abf9e657b75ba76deb86e215477f8ab51fde19982800009cf8c59f12bd6b094bde1e70c735a7b55cabb1edbcf44d9f64d9a9bb00e316adb6c1a7ee2df1e36d7bd6b9779de784e9cd29b06e6b87b0e75528a5f8e86b9d7568bb03cf65f8f89d80f602c0ba5c87375eb00f7bbff5a3bce6d3bf9c62cf49cea5206c40a68c0138e5e2c3f9dc5bcfe1a1c186fbc0c6fcecab674fd9f0e90be7f091afddddfcfbb1bb276aa4db313bf058d63053ee3755bf3eb06016e7fcf071001ebff91cfa16bc7f5abf3f19931dd3597bcee5fd578c0e04034fb94963fcf14cd6c6293bf672fe8ffe0ac0133f3ab7633fc6b7f94c8ef5fdd79cc1f5a77c60dac737fe37773f65676e3df354b63cec30942ef1ded9f771de571ee2c843b67ec6fd7ad385d773f67677b0f8b84b184e2530581036569e8e0c2fd8d22d00fff08d0f4fef4bb6c1fd2b53765df45a3e72e1bfb1f681ffe9b8eb339d3fa6faee74c7d8c5bd21fffdf8a0dbefc71317d2a36d9c47ef8ea74cab5f4fffef19d81dcee2655de13a6d9b0a13afe4fe95a3f1558ffcf822bab638a6f31754c8fbafbc8db7a8efb0efbb2e23ea30dd3e79fb6729ce3e60c2e7434f5eceda9d3f4ab1839266b2733cd99c309d39655df14b3b73e2fc1eaefcadd3c6afbae7bf28cf39ace3feeb721d365f7431a71f7f3a9fda7bf329f7ed742e05614332a505609b433ecbd7577d92535fbb84aa570493b2e3e2a399ca43fbf8ef7d873fbdf303ec794d429184adf7388d6fbe6cc7293bf499e31673e0e27d9955f2b8edb6db3afa544ed5af13be7f3527bdf56d2cf98c4f52de9eabbf7fc294bf3d15931dd3b1dffc1ffe7ce20778c5a2b3e90e60cbc597f18d0b5f3ae17880d0e26c0000022949444154266be35ddff92fdef6a6c3587ce9e6ecb0f454e0fb6dfb31becd6772acddf3dfc505bb5ec619b74feff8c6ffe6dcbddecd9afbdeca5bae749a9225276ccfb9e7ade4fb734703d69e49bfde78feb5f89f3c92256fb988dbbe791687be7abf497d6a054178eef9fa278ee35f16efcdac2d67b3c301a7013f9cf23bd6d439ef6d87b2a2a18847eabcfd826f76dcf799ce1f537d77ba63eca59f3b8523dfb094af6db5050b5ef341e0ab63b61ffcbb8f73f07f3cccdfeb73f9affff94cf3f3c96200be76feaf79f5e73eb34edbae3964119f7e720880dd76db8deead4fe3ce9bff65cc6f9964251f3de608d6c41a6523f49cddb8eae6cf4e7286005de4c35ffb058d6317b1f43d013ffff2fb9a6d025813637b76e40b374c4cadfdc0e5d7b2d7999d85b7c9cef16473c274e694c9e874eecfbae1cbbcfb6d87b36f1c90789bf39fd77fb9e37726bb46e3d1c11cdef7bef74dda1f98fc5c0ac28664ca180041100461d362b218006172a6ef8fbf69f28e9d77e2827bfffcacbab10a82f0ecb3de31008220088220080057dfff970ddd0541109e05a6550958100441100466b4f65f10844d878e1680f9f3e773cb2d9d73090b822008cf4fe6cf9f3fe6bd8cf58220089b16ade37c3b3a0a000b162c60c182f67970054110844d0319eb054110661e3ec07e274f95c75610044110044110844d018901100441100441108419840800822008822008823083f0fff5d817a88bbf75a7945d15044110044110844d9cbffeea62f5ff014ff15f27721276d50000000049454e44ae426082</data>
+ </image>
+ <image name="image18">
+ <data format="XPM.GZ" length="95012">789cedbd5973e33ab3ae79bf7fc5179b773b3a783452649ce80bcff33cbba32f00109c258e72d9eee8ff7e20bc495a93ed1ae455b5d6526594ad47c4984824003225ffaffff9cffdf9c97ffee77ffd5759b12a14ff11012bfef33fee78387cf97ffedffffbfffbafffee38bdffb43b9dffb47b9df67f3afffd7ffdd77f0f77ff23fe63b4f4bf098f42cded56a735d02c34775afd765bf348735731f23b9a797bd0f7f4f578c2ed76abdfc2f5aee66e47da7d7dddd0dc53d7bb9abf813b1e5d4f35f75b165dd7ed6bb38968ded0ecb606ad9ee60bcdb23d68a3fed309775a9d4147a71f5e6aee769c8ed0d7f7883d4ba7cfb9e65edfe3baffc37bcdfd0eef4a9dfe50b3d5edf7340f4f1b467e01ee4b067689a9bcbc0fb65481132e3d6297ebf6943978d0e1bafcbca7796075b9ee5f71426c713d1ee51658a5d7f973addf8e6df5b9d65fde211e207dde26b6b9adcbb3883deeeafef99a9d0e837e720656f5ebf616c7c40e873ed11e951afa2d8ec016a7fe4862012e0e895df4af18104bd45fba0debeb19cae3568b21fd01b1a0f6dbe0418b6b7d97a266a1edb3dc246e83f39666a1daaff55338e04187d2170d6b7b1d059add89e8f428cfb51877346f110bd2c79566a9d2737d7d1bacfa83feef1093be8b5db06abfee5fc989bb02f66112f7d09ee19d664f950ffbd5f6dc6d759509ebf40c5cdb43b941dc17da7eca5273bbe6e1ade6be12d817d2f72dc6b4bd54bafeae3560c2d2f95f350f1aae34db8ae11fb4fd769d960b7f51b6c00321f478e55a3f5daecad7f9336d0f5da1f4a7ebcfb47d7527fa447fc6e03a7ff942ec0aadff528f5f572ac6f5e709f75aaa3df05f2f60bb8bf11ef6897b1cedd7f3a1d7b65b282fd7fea6d71b38189f3c6858db57256b46f96542cc303e85d1b0ee4f75d5b0d647f6c6985ff7c49cf2f71a867dde34acdb9b270debf6668f0d6bfbcbce1bd6f667bcb1aeefa26a58f72f386858db9f59f75780ab6bcdfd41cbc17cac883b0cf3bdd530ecad4edfa5eb75fa3ef9c3a79ae10f8b9a2d4a2f1b86be376b86ffc9cf1a867ecc9ad1ffa2241e405f59dd1e9bfcdf4bc3da5eaa9898c6bba8cba7f1c9ee88497ffe45c33abd51a717e0b06c58b7df7f2676c16658b3abfbcfd286b5ff09dac4126c0e1bd6f61193be6cd682fd68ffd153cb81037ff34aec3a987f17c4d281bddf378cf9b2d330ece984d8437925f1a0c560efc7c45dcc87e28eb8cf917e8fd881fde537c4341fcba861b4ff9698e3babfd1b0d627ef13937e833a7fad8f6f60a7ddd2ed8fdac45d7085f156e644fdb925e60ed6b321b174b43d65b0e781f2bf98af97c43dd8475511dbe85f76464cfd0dce89a9bdfc9ed8457fd951c3fabab86a18f3ef80d873b5ff08a83ebbe5eaf69536710fe515b01fb5dedbd82f1c11db34befbc4dc41fb79cd18cf2c24160cebdd59cd188fe28ad8857d0caf6b26ff9683d57a82f974496cd1fe658b98f495537e35df70dd20a6f1afac867579499f98f499df11bbf097fc8d311f89ed0ef437ea36acf517150debf9e0f386f578f3b461ac57981f8ed5b2a1bf67e2ae8dfd4640dcc7f5aca8d9417f42620be9b30b62e660fcee8939d6c312fa76eafd404ee5d5f658a6c43df26f2fc403f83363402ca18f12eb8363b7b03f8913e2aeabb9ec10933db9d41ed500ecaff5feb4c7d4f60ff6007fc9fa7c007f6e13bb36f657f07fccb21cec270a6201ff5d61be32b5bf82ff7689a97ff901718fe6df0331d9173f2796686ff9d0b0ee6f84f16276cfd5d723aacfeebbda7e7d9fd842ff8321f100fed6c5fc619301d0fa0a8819fc4981f1e77d55a3aeff8c98f45108626163bf8ff2b9d5b6d13fd4cfd57aa5cb0b4262b26f21893db267cc0faedaabf39b670debf633ab61dddee4b861ddff4034acdbebbfe5d7ed4d39f100f9d327621b2ce03fb89a00186fd883e8ab19a919ed176a7ee8f4d5b861aca717c402fe33cb1b867d9f124bec7733e85b287fabe777f8425cafaf09b147fe0ffe41691bf6cfb66ac6751137acf3b3c38675fd41493cc0fa9c5c13dbd0df7048ec808d4d62067b0aa13fe178641f7affdd73ebf95025c4d2863fc91ad6e35779c41ef497c1be5c8bfc63e1134b5a6f939a693dbd6b58eb8bc15edcbabf6597d8427ff906b12db5be8725b123f57cf530de2eebd0fcc77c94dd7e47fb9b02f34fd6f65f3c100bd87f55d48cf37b81f196568bf6174362e532747a97b80fff975fd6cca1bfa061d8d706f180cea39cd8c67eb0a4f6d5fa295e1ad6e5a5b07f75be62b0f71362aa2fb088693d71a10f59db93dc236e83a38786757ab35d33f677e580d886fec31d6226f578f9549f2d303fc3476217d75dd28fd36aebf92f491f8e6ce9fa3cac17528d97eecf10f3dfabc72b873ebcbe43f6b8d5b02e3f1b132b8fa9d3bf12738c5f5e350cfbdd6b18fbed36b1a0ebcf0d63bc4b6217eb5d85f5cbb3ba741e1811f719d6d7ed86e11fe29a31fe45446ce17a79404cfbfbf28898cee739f5cfa2fd458af9e2a9f38a6e6f74484ce33d96c412eb5380fdaba7864f97ef7788a5843d0d1b467aea8fed613c5dcc474f8d9faecfdd25ee623c05ecc7635dccb752e7efb7faea84a1f5774fac76cc9a236207e393250debf1ae0431c3f56ad430ec61a3619cef7d620ece9e1ac6785e34acebcf376bc6fe393f26a6f1aeb29ae9ba0356fe4c979fee81073d9a7ff70d637f5c10d378e41658f977dd7efe42dc21ff7eddb04e1f8f89bbb0ffb2cedfc37856bbc40ef617d55ec3f0ff1d62064e0d62297579e204ec386dec270330b3307eb9b6df7ebbdf1de0fec40d710f5c5c120f68bf74d230c6f31b318d6796358cfd43de30d6df8898c6b71a368cf18c1bc678ee378cf9f644cc91bf081a46feb461dc6f1bd50c7f5d95c434dec535b1cb600f75fb3c3a3f1e368cfb3b2158a90fe71dd247b39f3f00abf30ff6fb547e33fe5ec3e8cf39710ffe7e1c37ace7637a5a33fc736510f7e9fe5c7dddc27ed984fdb61dda4f66fafcd8efd4e39b0f88ebf1fd46dcc77ebf08892dda2fd5d72d9cd7aa57e2818dfb7da735e33c5a780debf128c60d43bf37c436fc6b56e76774fedf6d18f67849cc717faf7824f670ff25a5f6a8f319e6db11d8eed2f9f5a061ad6fbf023b1da9e7b35b73bfadd9c37cee3007eb53784ccc305f2495c73838837d75957e616fdd86a1df4ec338cfc70d63fc6e1bc6fa715833f6e3e590b887f4d94dcd580f8b8cb80f4e319fbb03067d2403623a6fe492d8a3f5276b18e77f6a5f7dbe4a7789fbb03ff3a6619c3fa8ff6a7dd0f66308e2bec479e185d86a633fd2062bfd82af1bc6fe85f4c524f41f603c7b75fb05ecbf67f7d13e13fe501d48319ec129f140eaf1081e8855813a3fa5e72d943fd2fb11b57a39b027c322a6faa40baeeb1ba2fd7dd641ff0dd88755a74fb05e59931b12dade19f100fa7331bf2ca7dfc1f321cc0f8b75519e80bf1ca8fc38cf6c358cf2ce885df8970aeb9d6df7b07f08f689293db7880794bfbe4ef7a33cac8f6a7b87f3920b7f6a73b2ff0cfd55eac4fdcfc422f6e09f62e847797bb477ec11d3fa34447f1c47623c462d30eb48ad6fff8ad843fd12fa7078b78dfd0fec970d38f65f25d67fb55aa0bf495c33ea4f618fac2e3ff9d630cec7d03fe39ce637e617affb93da6035de582f06c474fe7533621bfa8c7d6286e71102fe813b3d3ceff0b11e71d695da3e8692b887f5396cd7ece1fee90bb185f4b2472cb11ff3eafc5e1bf9f5fde4c96906ed37a04f759aa1f31323a6fb7d21ec5f30cbc37aa2f7f7fdc9794bfb6fde2376e8bc700766034fdb8bd125b691df83bdb8bcddd6fa3131ff64a34fac47d2ee607daafac41cf7e304e68f74065dddfff0ae66dcffe2b01fc95ab09fa149dcc5780e5de23ef41519c4a43fbf20b6d17e714ecce83ad613c93b6d3d1f23f81fb59b867f0a90dfabcfdffc8a98419f15faabf6cbb0f700f6e1d5f5870fc436380d1ac6fd8d4d6249eb11f6271e97785eeda2bf9e68b7a04f3d5e56b31fcc4d6281f11be9f65b93fd05ece19698a37df103b140fb7d07cc1cb4c7cbc0bc8ff134f4fa6875eafe675d62aa8fef350c7fd12776d13ebfd530fccf1dd869937f3b24ee75757de29178d0d5f6ed517ad6827d44541f6f7b783ea8d73bab6bdbb8df90f588a97e7ed6b0ae8fed378cf1bd22a6f390097d751dda3f277a7cad9eda7fe9eb86496c439fd901313d3fcb3ac4547f241bc6f8e6c4929e77dd801dbabf2bfac47617f7931330ef60bef9d41ede47ff233dbfad7e7d3f287d21a6e78be28c98ea134760c7427c00bb06330feb7584f1edbb3dacc791f69796e5b6e19fe388b88feb23bdffb5063d8ef1e2bbe0dafe78464ceb8170893db4277905abfdaace1fa17d03de26ff7d4fdc877f4cf47cb16c35df74fec827eef7f4fc0debeb02fb5ff9046682ec07edb1dd0ee6571c13dbe88fd0eb9be5a8f2b19f2ec1aa3db87f3626f63cdc8f0733bb4dfe6e93b887f33e877d3365efba3c91340c7f8cf9c7943d637f02fd31e1225e64a8d7778bf75b981f2ee607afcb6366c3f0475d621bcf13240733bb8bf498ff5cb4d07e43af776a71eba0bc11ec5f3017f69feafd87e5aaf985fd09ea73ebf4ee43c3b02f8c972b24f68315e68354edc1fdf407628ee715690156fe0fe76dbd7fb23cdbc1fd328ef49ed3457d9e4fdc0307985f9e101ecec7bafd839643f7ebab4762067df0a461eccff7885d6adf3db1c4fdeaaa47ecc19e4a03cc5ab057b74bcc7b7afc22ddfe813a9f91bd5760a78ff6566d626a4f84f2dbae83f5dcd7f638e8d4f9ab1658e94ba767c4dc85bfe67a3e0e26010bf0bfaf0d63ffaed7d741cfa1e733954d4cf1237145dceb43bf5bc4f47c9a3f130fc0c625b180fedc43b05047105d1ef4d37319f62b0cfaedd7ed0b8f88655fa7f7915f9d66d19fb15e1f079643f12c639fb8aeff8298c6c7d7fe7730a8fddfd8052b7dc37e6e896db29727b0f03cddbe31f4a7fc07dd3f83fe6cb7ddc17ee484d86ac31fa2ff4eedff13f4c7711cb24f07ccb9c4fe5bfb8f017318ae4bf48771af87fb997a3d579b5909ff2150bf1aedae6ebfa9fdc140a8f318ea3b27b6c011ec4138ae85f2f66bc67924db26a6f22be84bedffc89e9f8807d0a7d901abed82d687d0fbdf81eb50fc46780d56131efb29bd7e0da4da2eeaeba9d5b02e3f89885d8af7d823a6fda19f83dd81a7fb9b60fcbd26fd0631b53fdb24a6fc19ecd563b4fff28660b785f82743e7b75b0e3d2fe317c4148f93ed8219ddfff6eec12edd8f33f479c66ee633db06abf6401f070debf646fb60e55f757dfe2e711bf61d6d11dbb81eec81d5f069ff150c886d0fe50b6207ed31b57ddb9d49c092d6f73e3187bd273eb187f6b13198f5e06fa333b0e848d853464ce78190581d0731fff5794a6d46c8dec40bd8edc17e19ab19f389a3fd3d46eb67482c3ad87f8fb4bfb1fb1daf8d78ae6fe0ba3f86036614df644a6207f7a759d830e25512b0ea0fae3f815d0bfa33315e9643e32bd03f8bb569fc50bf3afdc0fecc47709d5f687bb30775fab2472cd11e03ed1bb81ef435d4f3d1b6ebfe8902cc3ad88f49d9b02ecfb3c12ec5779a7abdb3d57918cfb70cd8a35a0db13f8d39d875d03e1ff6c91cba7f106e10f728dee415ccba149f70d830f4631133e8338cc1ae447ba2082cdb880f8cfac45dc44fc6681fafcb8f72e21eca1f0b62e1e27926ec571dbff13c4fa23d5c1d58b1df37c06a39467ff57ec31692ced35caf67b6cbeaf80d87989e47f997c472a0fb6fc2fe5cde813e25e6bfda8d537d5db06b211ed1f08905c633d1fedb56e7493affdf8139b730de68af745da48f52b0d20fe617dae7d9143f9560bcbcbabca04f4ccfaf992016180f13e3e10986f9e3df80557b757fc67a3e382d46fb21298807d0cf988395be91de246e839316b8b6df50db83d36ed6b72db02a4fb75776c1dc817ebd6f60b7dfc3f9619398f431d4f3c5e97405ce93910bae9f5778b7c4a41f1181994df11361c3d83f3f83dd96a5edddb3887bd8ff075bc47d9c9f7caa5f6d47b1bf45fe6e57627f1df7c113d1e96beed1fdcd63309703cc2f94d795ccc3fd24706f227afc76c1cc21fd3330a7fb3d63a3613c4f6b110f069abd73b06ce33c6542df7d5b403ff109586d38b09ed1f5babe90117bb87fecc21efa6abc74f96c44ec91bfc478a9dd12fc9f87fef65da7a7d3873760d981fe62e8db9a886e3fcab71843fd2eea57070edcff363d70edff8d90b887fa42baaec60bf7dfc7c4ac07fda27f03879e27b0336201ff966c8319c5abf26f0da33d2931c567b100acec1ff12e0fc416fc9341e9ebf6c990b80f7b67c735437fb224b6601f1eb5c7e5389f7b11b140fcbdb489dd3ef4a1f7538e72f08897891fc1757b3309e62decffd3db86f17cfd8a58e0f9829180d57a8ef56787d8b370bf83d81d60be1843b0ecc39e8d98d8024716b143fe58ef0f1dfd4f8f1fec596d6fe97e03e683c329de82bd82ebf68c0ae201ad370131efe37c00fb77d4fe17f783ef883d9c17c27b70dd3eef807880f91e39c40ee64facfdbfc326a2ed03fe509907c56bc15e19a7f8b9cc22a6fd31877ed4690debadc4f8abf5b08ffd6e4e3ca0f68c884557979f40df9cd1fd980cfae29ce2f7328fb88bfa13e457c73bcc37f90296ddbe6e8ff74cccc9bf3d110b0ff7a3f5f9d21113d17c4aec229e343e6e18fb73e84f9df769feb48825585e368cf33ae68ba8db2ba06f2138fccbf0a166ba7f86f92ba40dfdf8989fae5ae1e1cf301fdc89687d607d726bfdf8e8bfeb7670be970fc42efcbf09fdba75f9434eec8005faafdc35e9df0773da0f9bd0b7dabdd3fdb53b62cfc27e0df349ca3ead378c58f4b43da668afa77600e80ffc933711cd182fb59e637d884b6217cf4bc59898dac7aa9a313f24d6334f762df893176289fb39b13e7fb216a37867b32076707f82ef83790be3e9e5c4f43cdedd018b1e9ee7b22eb1c0f9c41d80e500f547350bf2d7970dc3def4fcd51f77c2fae480ebfa5d1f2c6c3caf8c6cb07429bfde0fb2ce44747a09e66de4374ec092ce47b1decfb1ee44b47f79207631be469b58c2bff3537053de16580c705e777bc40cfa08ebebb4ff928c58e0ba7f0f9636eeffc4e86f6f227a7cd1df1eef50ffd19e9ed237ee078f892dc42f84d067cf953dac5fe85f4fdaf0dfde2bb107fbf3d19ebecaa1db131f10f711af968e8925f4c1517fbf6e4fb24f4cf1ac3c6818f69f82659fd637b4a7efb5e09f63b4d79a88660fccbbf037495833f57f0856fdc5fdd91bb06ca37fe18898e673a0e7b3da4c58d88fc568ef60225abfe8ff4095afeb971d628ac70dd1de416d6fee2d3183febd33b0dbc77e2580fd0feafda2a4eb4aff78dea8e73bb327a2db83faedba3e89f6d9a285f9ee46c436e22bdc136246fda7f2a43dc07eed9c9861bf11ebf55d2f5f382f62fe395e0beb77a4f79b8c35fe670f3cf9a7e7f315b1a4fb952d30b7a8bdc4cabfe9f53ad1eb13e313d1f55d83557af893838611df8bf9ca957fc67ee91b58b611ff254f893b885ff0303fb9d7e961bf0c7b106a3f8cf3d12e317d1e863f368cf1be030b06fdfa284fa8f2709e7b6c18fb2994e74e44f71ff6e936e5a1bdae2a0ffad92676517e148395bfc7f3574e2c2dec974b620ffb010ff6e7aafa612f180fc96df23768af9cdc90d3f53d11537d09ec55ba743f2288895df83b1611d3794dc27f4b49f121c99898e68f87f92ebd6e0ffa6f358c7805d8af3711dd1e8c97e7da88b7f230ff3daf65e1f3690e711bfb0da1e73f6f39140f115f8327a2c7cf2676309e9ed730f60b21d8a5fda17b43ec50fd1b60afddc7f3d3a466d4ef1d1277a07f9feaf77a18af913ecff136ebc03f06f7c402f321de014f448ff72d31ed3f444a4c9f1fe43e31c779d878050b3adfb905b185f55f6660b59dc27ca7f6a8e988fbb79cd8437f52a4efd4ed15684fa7aedf843ed5f917fb15f71b31c55f7926b187f8461981e500fe4f3e12d3fd9144db1fefd6f51925b187e79d31c6a3cbe9f3b49cd273fa7c5f7a0e56e721dc0f6e130b7cfe8e49b04be729778bd8467b5de8a32bbb88d70b610f5de5dff0fcfc9498ecd747f9930f70603fb50d9e886edf0d31b5cf8dc1c2437b5cd88f3add83a5019616ea970531c51b7b2eb107ffec09b0d702cb41c3783e89f47d4e9f67163631b5476c100b7052358ce75fe85f5fe913cfdbbac42ef67712fd55a74fc4afcb73628ffcad05aedb236f1b867d84c4b4de7a54bfd7c17e37a0f67916f907f4d79a88d66f454ced1721b14bf6d0038b3ef6afa2432c693fc789299e3282bda9f33e9e37c82370d39fe786115f017f63791df26f94deeb5a787eb34b4ced0f368907e018fa1870fa7cb92889ebf6b7c0c2823d8757608f3e3f6fe2bacde8f9570c7bb6397d3e5370628ac7663b0dc3ffed81451b9f17491f8907186f1ffab6ebfb072efa6fcb36d6a7d151cd142fb249dca1eb0d637d9139b187787919378ccf17a33e47ed1f511fdae7d4ede51eb1070e607fea7481f3a37b06960c9f1f731d62171c8dc09ed5c7fe44afdf7a7b81fb8d87c4547e0a7fc0844d9f27803f570b28ca4bd39ae12fdd4b6289f854d722f610ff1d623e32d55d9c1731dfb9ddc3fdde10e571d685ff8b4c62f22f498fd8227f03fdea7f5a7f0131c51b8821b147f131970debfe0da12f2efbf0df232abfee4fc0c06a7d83ff8b886ddc2f0a319ea27e7e9d623d1275fb0283d881ff4ee07f05a7ef33705fc092e26ddd2b620ff713434aef39a82f807e5cb54346f9f09f2ea7fbd5092776113f2a612fae68a1ff72b7613cdf863f9475fb38d64fa9f487fb4da7c42ef4196f10d3f72b70f81329da28dfa5fc52a23f01caf7588bce43f0e7de44f4f860bc3cd1a1cf2372628af709609fdee401a52e7f83d8c3e7530dacb75e3d3e86b65731890fc07efd053c11ddde13628a47089e89bbe88fac887b181f53db8bf20e1eceabe61558b4c0714e4cdf0f91dcd54ce75b49dc457d629bd8a2efcbd0fe4a749c16d6d338030b7ade9e3ed78cf2228fb88bfab86818fb03d9309e97ee81bd1ed9ef1931ef637cb4bd8a6e7dff366e81057d7f841811d3e71fc413711fed8bd0beaea4fb41510256f303fe18ed9bec0f703fc3012bfde0fb4f32e22ed6a7e891b887fae3b461ec27dc86616f07c4f47d1415c677f201393c2fc278f554fb703e0f88bb68ef48afd7a26f7bb89fc2c76041f1078caeabfd3ee6cf265872dc4ff0a19f016fd3fc4e89297e6c1883550938cf1b0de3f9f51db185f5c6807d0c5c879e473f127ba83f82fe6dc1a13f0ff66ecb16d6af680856db45f803d8af53d76f607c1daf0f7b60c8af0e7014ffaad763c1ebfb710cf6c1dd16f469421f5c9d67a05fb44ff03ef517f6a0ffe9f98cf1122ec57f1b2f0d233eeb88d8a178518c9750e383f54710d3fd25362076a87e1bec59e8cf50fb6ba1ce77889f3076c0aec0fda2e4062ce9796dfaad61c4a3803d75a2c37ad306ab1516f12daf606501f87e1f8cbf2719f27b28dfabdbc3ee890734ffb4bed5698178a8fda7abce437ddc8f7f6a58f79f697fe7aaf98ce7b3ec85b807364fc06e07fae53bc43d8c97a1d733b72b5ad8bfb06fc4549e8ffc5db78dfec97bb0a4efd719eafeb83dc7c67ece1881ebfa8d80b80ff6507f4f65d79c1e12bbd8ffa4549e3ab0e3fc6082d578e379c22bd8b33d7c9e11fae8d7f32bf0c04aa3b007b0daffc2fed203b06c61bc230156fac6fd14bdfeb86a3e51bcfb16b8aedf1f12f788f71a867f3b27ee93ffb82376c06949ccc0de1331a7fb0d8f60b55fc67a85eb6ab74aedbf00cb16e6c748fb47353b24fac3f47aec32e50f607f3e58d2f3c2ea90b847fd3f6918f1c82eb147f733501f9b7ce050d7affd851abd3abed525b6301f03d89350fe15cf0fb6c1eaf883fdc471c3b89f790656fa87ff80fdb9b20dff165d1353f9e28298ca0b7d628a571c8e6b46f9f1b061f817e8cbf51cb21f7d5e53c6d785ff1b56e0bafc684c4ce3e725c41eee9f24da1f2a6ba1fb21c3b461f8e317622a2f6811dba48fb0618cbfd6a76c091bfb45739fd8a1fde33558527c7f3620b6e9795d02f65a141f53358ccfcfe8f55fb6b98bf3875f8205a3f8ce183c119d5fd44cfbdf7b6207f5a51531a3f8e61b628aef1c31b047f1df2c2366d03fd3f62e3bcac363fc517e47ad27b0f7103c115dfe6bc388278a88bb6073ab66b24f49ecd0fdce11d8b3602fbef6472a377dde60e881d5fc83ff3869189fcfef1053fb5394df9b88ce9f105bf0b7a15eefa45afdd09fd12bb10dff128f883dcc9714e3df9f88ee6f45ecc05e467a3d53a55379c32762b2876144cc909e6f82ebf37788fc03553fca83fd0c26a2ed3927a6fa42d43ff0c85fb01be27a3d4579b6dbc1f3a3709f989ec7b2e786114f7740cc50dfd022e658df8d53b0acdbf7d8309e9f1e114bd8976f8055fff03cf998b88bf10b1ce27afdc6fc993cbe847f427b1d49f17da31b6207f1e3660a6ef6432531c7f81bd037531e0de7e70bb04a81f8b96b6246fba3bc669a2fdbc4753cf43131c5ab57e8efe4e35638ffd80d431fb7c4142f65be127731de2c21a6f67afa7c3739ae617e8fd07f2ee9fb2d463bc41cf66862fc26e75beca7b43f95427940f81bb45f4c4433f4e34e44ebfb105ccfa7e4847800ffc8dac4b4be983d6241f30bfad5ff3463fec97abc33a761ccd70be27aff04fbf624c5aff18298e6ebe898d841fced2822f6e04f8231d823ff2c4f881dd82febd54cf670444ced67fabceaa9dae9f36447c43dba9fb24d5c7ffe3227b6d0bec0241e80d92531d9c788ae7b747fd9dc20a6f890202026fb378f1a467b1931b5d7d7fed96bab1986f3df2d317d9fc4c8027bb43ea757c4146fc1b7882df8cb508f9737f94242c44b3c13dbe8eff011ec51bc916b1373da9fee12ab0d9dae5fdb8bd795b5bf3824a6ef4f180dc14a43888f2d1ac6e7d10e88693f14a2fc9eb2575c3f27a6e773238c5fcfa3f8a3e121718fe2854e891de83ff5885db47788fafb1e9d8f52464c9f9789ee1bc6789d350c7bd923ee63be047a7d50daa5cf471abc617cde759f98f64b45cd747f247921a6f6997affa4664b97f6db8386311ffb0dc39e3bc43d6adf0e31ede732414cf11cf963c3b87fdd23a6fbc7e5b78671fd8498e3ba9910537b13fd3c4ecd46ba9fe39f13f7305fc316b1057b329f8829de67b8454cfb417393b8ae3f26a6fae52b31c5d7cb21319df77dbd7f54bda3fa86dbc4747e2cfbc474bf503ac482d667a49fecafe16f8f89497fc30d623a3fa65d624efe529f2f14d1fecfc88969fd36f689e9bc615e348cf25f8839ad1776c358bf519e98b450f32d31a53779c3b0874d628a6f62d0a73ba951b7e79998e275834ec368cf2bb14bfdcb1a86bf1a378ce7291bc492d28f1b86ff863e655d3e37895ddacf150d237f442c519f79dd30e60be6affe37e18b6a2d6b598daced692dab94b53dad6595b20a7b328ddffb7f2d7f8eacca9e7e9fac2dea4f92f57ab79655ca3fd33f994c0b3785e9aea40eb6acd4097d6fded9b6ada2459f97f2fd35fd58691fa5fe67fa273deed2f4d44f7feadde0e7cb5b56eadfdf9e6a8dfc59f6f467fa27f53354bfa39acdd84cf4eba1393253333373b3d05c9a9539369fcc6f8bd494f7fc5ea9faf78bf96a6e989be696b9ad68c78ccc5df57b4f5ddfaff34eb70ca2e9c03c348fcc63f3c43c9d4975669e9b17e665936ebecd33a534b9667b325bd34c1be734329b72be2eb4e56aca9eaecdebf746e31fec9f6ecc5bf5f3aee17bf341bf7e54af5b66dbeca871ef2aee997dd33207a6adafced0e7a5eadf8e615e5486613083abdfc264865a0f0d695e1bde421992bc9c9c90e1abb481a12cd488a65319b17e3f696a986ff34c294dd9b33d994933dbc6398dcca69cabcb18aab68c8cf4cd9e8cccc8dfd3fc3fd73f4dc4288cb266e34deb4ccdbecc18abf79e9476be19cfc68bf16a6c685dcdd0e7a5ea3c9bc696b16dec18bbf05bc69eb16f1ca8913b5cdade29af621ca9d28ecdc988cd78b1b7f7c99ee6dabc7ccd996ffb4c4d736d9cd6c86cca05fdccb545bd73629cced75dcbeff04fc6d94416de3d37ceeb9fbf2a5a5b17c6a571b55c5fc6b571a3e556d57867dc1b0fc623e6dc2c7d5fa9464bbddf56573ac45dc5935afaefb56da62defd993356b4fd36d7ec79ee6da3e634f736d9ccdffa17ee6daf2b1fcf5fec91818b6e14c8666d1a65655fbc2ce628a997acd3813cc9d042029f659c04216b1585f9da1ef2b95a975890dd948ed2bc029cbd43b392b96b59795ea5ac5c6faf5937afd6db2deb1597b52a3c75ed86b53c35c9b674b694a9e6bfb4c4d736d9cedcb4ccab9ba745b36d8e6947fda3176de1b8dbfde3fb12db6cd7694ecb23db6cf0ed8213b5a751d1fda53ca8ed9c964dfca4e99b26876ce2ecc885d32ed7566e9fb4a65d7ec86ddb23b765f5f670f6a0c1edfe97f8bb5d5d58e2e61c8baac671eb3be713c93c662036633c764dc5cd6e6d9529a5c736d9f4e33dfc6397b9a4e39af1fdd166efca9e73be38cb3c967e3b83bf9801bf779c0431ef1f867bdd59f777f9c277c68467cf40b25a43c533f73654f4b7ddc9f2bbf65ff34e025aff8b811973ff16ffc99bffc6e6dac46d4fcbde0afbf5202dfe09b7c8b6ff31dbefbbb7bf363f23bce77ca43edf17d6545e3199b3ae0873fe3a3fe3cfff46f96df73ff891ff1637e32674fa77c25fbf3b5fc4ef93df79ff839bfe09773f6b4cf97ec81bfa2f6b57c9dfc26ff74bde09fc6fc86dff2bbdfad8fb5fc9afc0effc4eff9037f9cdb3f8dd589afc5af7e7c07b5f64f7f92fcf5fe69723f93b795f58c17a4c3bbbcc797de555ecbdf43fe5affc48eb8c507dc5ef04db59c7047fce09df3b57ffa93e4aff34fc699307829d8c2be69565cc18510ae90bf5ee3f7ca3f2dfaeed7e2e8dea2577ea6eebfc63f295bf2f8b3f045f0a12dbdd95428227e660c5653fbf768f59f147df76b717493b895e5f130cbcb9895aff74fca966291702e86efae724b448c442a326eade699f127dafdbb47dfad248e6e994ee8f55cbdd365cccb57fb27654db92844f923b6f4b69b521ead629ff89f15f9a7bf71f4dd6ae2e8165bdf8ce15cbdd365cccbd7fa277ea77642e3e5ab9c7812dfc4b37811af4a5ed4ab6fe269c9cab72136c5d6d77aa9bf7df4dd4ae2e8bebfded93266e52bfd9388f9333f58e699c4b6d811bb624fec8b0371288ec4b13851b4abdedd5ee2a54ec5d9fb312d3fee9fc4b9b8507239adbbbf75f4dd4ae2e8bebfdee96be24acc3cd5f82affa4d6b96b71236e975ad39db8170fe251b4441bdf8aabbfdb76f27daf0feacadd420ea1d63d6bf55152ef69f5ef167db79a38baf75b3f5fef8cadcdf5f2abfc13db1203612f5de71cd77427df9ec99788705dd714cea245b952b8cbef74ae66fff4ae2eff0ed1772b89a37bbff5f3f57eb53d2d8ada3755aeb7cc37b9be1bb8a11bb971238992371aba2395c25fc829ddd4cd56dfd2df2fbf1e7df727c957f827e3cccdb923464baca9704bb772c7ee93926feeb3fbe2beba1b4a5ed5ab4d77cbdd56b2e3eeaa54c542de3db6edee7f5efbdf4d7e3dfaee4f92aff04f93e8a665673af7c03d748fdc63f7c43d75cfdc73f7c2bd74af66e4dabd716fdd3bf75ea53c983febf103f761fd74efcf96aff04feea3db5ab67372db6ec7edba3db7ef5a4a06aeed3ad2d4afa7444ebed996ab94edc5939e1472e189c8dfdd3ffdb3e42bfc9394d25b664fd297810c6524632d895427503992a9cc14e55352c852a55cdc43b9ca4e7f2a26782d7f957c857f5a880d873555722c9fe437f94cf222f5e7cbe486dc945b72bb797f223b2aa5cab150c6aed8947b1fd7be96df295fe19fc4ed52efb42f0fe4a13c6ae418f6a46dea449eca33793e25172af5fea28792977c05df4eb296af92aff04f7277a93d5dc96b79236f1bb97bb3276d53f7f2413e36575bb22daf96d85347b81fd7be96df295f72be934beda92b7bb28fbf1232f9db20d29eb52773f2f7294c0fdf232e26df962dbb8ba5789ee7ff7a0bd7f255f225fba7a5f6245a5ee085531279f1ac3d4dc44bbca137f252753d134b4e896c87df7e5cfb5a7ea7fc75fec9cbbdc22bbdaa91f1a23d794fde37efd97bf15ebd0d6fd3cb9758a5ed6dadb6b5def6e4e9b0c9263fbd9dc588b64599a498cff5717a6ff72de7b2d27e44669fe77e56cea791752bde8dfe75fec9dbf3f6bd03efd03b2239f64e666ce9d43bf3cebd0b924befcadb5b52ca353ffcb8f69fec035b7cf5ab69eb27d8aa6f37deed7be97f6c44d9d13fdf9ee6e5bd0871efcebbf71ebc47afe5b5bd8ed7f57a53d6d4f7267f2ff2a111db5b8c3398c8233357ddde59bdaab638bee91bbe7ec7e7bef05d5ffa53b16e6f31946fb97cdf0ffcd08ffc18effb893ff447752a3ff5b3b7f4d365fa397c9c5ff8a5a2cabcf6c7eaf793ffedbd322765f8cffe8bffea6fbcb5a42e47bddaf4b7fc6d7f072d56b976fd3d7fdf3f786bbf7fe81ff9c7fec992de4ed5b8b445533975fa53439f8efc33ffdcbf98e4fe92fbe34bfcca44fc4bffca1bf8d72437b53df9b7fe9d7fdfbc3f9107ffd1bf5c5286eb4abff571edbf6e4f7e5b69a8e377b5a67a7e5ffdb4fca5b1ec537146b16fab744e60e2fdc0984e6506010b78634f3365e2bd40046a64021978816f86411084ef95a97e47411c2c44dbd66d0986fae7a88e5a0f5245593015a165ec06857aaf5ceced748d4b5b349553d75205e3499c4df0147c43ee2ff14ff34fde4882e7e025780d36824d2d5b137b921bc176b013ecd27bb5eca994cf4bca1042044b9e09afd69e269a0b0e287af248c7de5d04ef444f3663c482a349644740111dc1c96caae034380bce29826ea6ccc60e2e8222b80cae82ebe026b87dbf4cf5fb2eb87fbf2dc143f018b4d4de8ee231276504ed602a2625e806bda01f584b7a3b53e3628ba673525983c056e99dd044eeaff04fa1f15eb478c8421e8ad00da512cfeb857e1884a1a63789c258a5624bcf88433e08938f6bff5ce6e333e7ed69fab7b11b0e3fe8f99b3ded4e8fdb7ce493d6ca284c979559a70db3300f8bb00cab701c3ebd5fa6c9c26fe173b8f0dd464d39afe1c624571defb4684f66106e865be1f6b2de4ea75e6cd1744eaa6d27dc0df7c2fd3af757f8a7f0203c5c6e4fcaa28ec2e3f0243c0dcfc2f3f022bc54bf67e52abc56298e96e6d67733bfe6f9dd7bf614de847a66864bbf59e12d57783f5957c207ac2b4bede9316c2d2bd36088520bdb612754ab4ed80bfba1f57e9993dfe120b4a7bdc47439ac9cec7e42a7b6a748798ec8089a5da71944137f59d5b1bb336d9ca971be45b3396b89782422b7cefd15fe2992c27fcf43455ee44741144651144749349c9151944699baea474b9f278b20caf9f567b5ff641fdeb1a7a888caa88ac6d1d3c7b9a26fd173f412bd461bb3ef4f53b4b9accc682bda9eeca3a31d35f6bbeaf71ecb83f3f7cba432f6a38368660d6eca398a8ea393e8b4b1a7b3e83cba88dea2e5c3e82aba8e6ea2db25a5ced438dfa2d99c4dbd77d1fd9b0ebec23f450f6cfbbd3db9b2a8c7a815b5a34ed48d7a513fb2a24164474e6cc6867aa7a3aeb4a2c7e5de2966cc5cc73ffd6912f358bcd1d7c48fc7ae10f1d2bb5090d88bfd3888c3388aeb7f91a240bdbbd4336979e2e5b24fa1afef8fff3e899378188fa6f7725f133fce8e84bb6ccd8b532599923c2ee232aee271fc147f53f2a45e55f1b37af7455dcb26e9e677e2f12b5ff22992b5fc59f2559f6fe177c27265eda3b4156dc49bf156bc1defc4bbf15ebc1f1fc487f1517c1c9f28398dcfe2f3f822be8cafd4d5ebf826be8def548e1c76a5ace95ebcf3ad2b6bfff427c9d77d3e981dc50ff123e2c8e396f23b6fd674a5ece65059503beec4ddb817f7634bfd1ec4b6b22f2731132361daa23695bfca26dffe6b38f28bce756b59ad7ce5e7838db3605f4a7e83758fd6ba3cde48b8b6addb4424aeb2b01b25dbf1b67a7dabdebd4ba4f24b2f2a654bfba6137eca1f3efaf69eb57ffa93e4abbf5f4548719678225dfc3ebaf91dd2925dbb74bdc4ff6bbe63652dab91affffe27e3cc18b8591224a19cf984a7f657efd994cb2ff9691225f1e79f32ff55ff942409ddad4e4649ba4addfe942ed9ecef8f537e5fd44c92257952bcfd7eff3b0b7eac8dcbf2fc55df4f679cf123fe9094c24f2ab5a7721b9b6a69491b3b3a111bfc5414c275f7ff1abf6406c9387952dafe963c072bf8db56bfd89a1fb2a7e569e7e760f2823b9fcdef773e3dfaa7d8d3f77b08e34cc86423d91437c956b29decf076b29beca9fffbc901ff961c264722e196907fedf76726c7c949729a9c25da9ae6a34416f51654c94554898be472313a643afa633627c5164c457c2cc6c2bc459dfc5cd44c1dd332ddaae46a52667259ff6e221aa67ab1d8c7592d24d7c94d729bdcd13df70fa264fe997f9ff34725b94f1e12fa468af92811bc3badeba495b4f5efce6274c874f4c76ccee6896b13f1b12c16e62df5cf44cdd4312df3ad5ad692e95e2cf671560b4937e94da25e163dd87c94cc3ff3ef73fe701981c9127a92331f254229a675cd92e659ec4274c854f4c76c4ef20a53111fcb6261de52ff4cd44c1dd332dfaa652d99eec5b23e4e6b41a51dbcc52c2ccb53d7f86ff44f1fc7abcc45898c7de5cdc37246d7476f23311f1d325fda7c09d3111fcb6261de19fbef8c9a792f66656999471fdad38c163eb7a7bac6b57f9ad5cb7ccc466227ce453534a73539348658313a8bd121f3a5cd96301bf1b12c16a68e3af9b9a899fad5c7adc2efe95e2cb67a560b433e14eaa7bb684ff35132ff46ffb44cde8b3c19caa137f487c1ec7e7c180e237f7b182f4687cc97365bc26cc4c7b258983aeae4e7a2669ac8980f5b55efc7df7a51bf6f3e4f64982c6861381c0dd361662c7c87de7c94ccda3fade57361e964cd1ee6c34fff5ae8da3fade5731996c36a381e3e0dbf7d967255fee977fe5fcb9f236bffb49655cada9ed6b24a59dbd35a56296b7b5acb2a656d4ffffc7895ef2d7131ddf23ccbdeaddf5bdbd33f2f5e6556debee5e5c75af07e9eafb627930d9fe3a3df23c3e7efd5d3fbf2cf8957f9f85b5edef2fe6c34ca7bdfd9f2967215f634b1a6c56f9a5b957c5cf6c4a27eb5fdff9c78958fbfe5e5edf5cf46a3bcff9d2dabf44f7ac4a3af91e1cbc7a50f5fe315fcdda97f4abcca67dff2b23cddf747a3bcff9d2dabb6a7e1eb17c9c627a5bffcb83dfd73e3553eff969765e9be3f1aa5eee55f604f9b5f245b9f94bebd0aff34adedbf73bccae7dff2b22cddf747a3d4bd9cffce96b7942bb3a7972f929d4f4adf59b53dfd9de3553efe96975f8f4669ec69ee3b5bde52aecc9e3648769b57df2f1fe5d99b297d51f657634fff66f9fe6894cf6565f6b44db2dbbcfa7ef928cfc14ce98b72b8b6a75f95ef8f46f95c56664f5b24bbcdabade1d1f07878323c1d9e693a1f5e0c2f8757c36bf5fa66783bbc1bde0f1f16f2cccbe354e9bb33d25cffdde3b1963759993ded90ec36af7686ad615bfdec0cbb9a7ac3befe6da9ff03fdca1e3a0b79e66464ce955ecbd4f5dfadc3b5bcc9caec699f64b779b53f3246eafd111f0922b7b92247dec81f05a3703ecfbc8ca299d2f7c99a66aeff6e1daee54d56664f7b24bbcdabbd513c4ad4cfe168a4291d65cd957c544cae50eaa93cf3322a674a5f483db9febb75b8963759993d1d92ec36af0e47d568ac7e3e8dbe697a1ebde8dfafeaffc66853fddca2d45379e665b43d53fae2f515dd2f58cb6a6465f67440b23b82ec0d0f46fba383e1c9e8707434b9323a1e9d8c4e8757a333f5fa7c7431ba1c5d294bd2799adc0b32ba9e297df1facd2aec69743bba1317a3fbd1c38fe7fd8a98919f935f2b7d356d5b993d3d7e8d8c1e3f2e7db482f3dda8356a8f3aea7777d41bfde4f7077f5fccc87bdf6cb21a596cc3e7df76f426ab69dbaaec69647d910c3e29dd5e813d39293d39488d94ee004f478bccc4a72c891c418efad5e73123f37f5567fe6ef8d2bfe1f3415c4cca5391dc9a57b3914b6f7f3d68bae4e97cf3b4f8de6c248b6ec7c25f009a8ded59993d995f23a9fb71e9a9fc757b4abdfa9be1cd9053a4c774b4c8747cca7b91233f123332ff577516ed69311ee4a3b818234ed5bb69306b4ff55f0f9ab3d4a97cf3b4a4e70b912c8b7f016836b66765f6147d8d4cece5a3d2d3f06bec69f6afe4bcc513bc1739f22331238b7f5567c19e16ff86cf07713106a59fb3a793a5254fe59ba7a53d5f883c98ff0b40b3b13dabb2a734fa22093f293dfef578953469d6bb613ae5fb1b7f32159ff25ee4c88fc48c2cfe559db9989625f6f4515ccc727b5a5ef2ac752dd27cc98bf634ff178066637b56159f99c65f251f97bd8af8cc7454efc7d3349dfabb87f5efe9f894f72247be3f6664d95fd5998d8a59160ff2515c4c9a23fd327b9a2ff9c7ec697924cbec5f009a8ded59c78feb1129d2525ca4553a9e1d0d5a9fa6e353de891cf9de9891f99815c86c54ccd278900fe262d2a7f45b729b3e2fb3a7f9927fd09e9646b2ccfe05a0d9d89ef5e75bfe3cf9dabb543f22cb235966ff02d0acacede9cf933fc79e16235916ff02d0acaced692dab94b53dad6595b2b6a7b5ac52d6f6b49655cada9ed6b24a59db53fa92bea61be9a692ad743bfd24e2642d1fcbbfdb9ed2dd742fdd4f0fd24392a3f4383df9f572ffbdf26fb6a7f4343d4bcfd30b654797e9557aad7edf28ba4d977e0a772ddf23ff6a7bba4f1fd2c7b495b6d38ec9d26eda53af5b693fb5d2a5df63b296cfe5df6b4fa99d3a9999194a58c63391b999cc3ccd7e16c8bd8ff2666116657196643ad6201bbdfd9c49f5c13b8bd73e966c94a54ab22c5f7ab55057ca1f2aafcac6d953f62d7bfebc35f5d5ef69f3bfd79eb297ec35dbc836b3ad6c3bdbc976b33df57f37dbcf0eb2c3ec283bfe20e749769a9da9dfe7d98566d8d3e542ba9fb2a7ec6ae9bba8e33abb597af5367b778d7ea7bcfbec41fd7ccc5a1fb76692bfb1a7851e2ecabfd89eda5927eb66bdac9f59d920b333273773236739cf45eee61ffc05ecdccbfd9992a6fc531ee4a17222511ee39d3cc987f9122ba2d4699e654f799e17782f2ff32a1fcfbe3b93fe29a72769d369f2e789f79ad498bfe4aff946be996f7d565ebe9d357fb332df81f753af76f33d957f3f3f98ca7f585fadfb991fe5c7f9497eaaf39ee5e7f9457e59f7ecdf6b4ff9557e9ddfe4b7f95d7e9f3f982c7fcc5b793befe4ddbc97f773eb839c83596f30634f76ee4c7e17e6e49dc22858c1a753ea556b223a75210a57fd948587ab85bff8ee5bce2228c22242ddf33991aa888b44fd1c16a3cfca2bd2222bf2a240694d7ebd661655319ece3fbbdea97727753c15dab28be7e245fd7c5ddb53b1516c165bc576b153ec167b262bf68b83e2b0382a8ef37671529cbe9ff3237bca6e8bb3b7f78bf3e26231e5db2b5592b6aee292d29f2dbe3b9dde382fae8aeb653929955ef78a9be2f6b3f254aabbe2be78281ea7f317ada29d6fa8949de9fcf3f6649ceb9674a76aecadeda9e817563128ecc229cdd298f8a79295bc14a55bcad22bfdf7737eb8de0da6eda90cca70daf6e6ed29bb2da3c5abb3efce5ecb9332fe282746b7b6a7f7cb839449399c4e598ecaf4cd3ae6f7e1cbde5ddb532d6556e665519665558ecb279395dfcae7f2a57c2d37cacd72abdcfe20e74eb95bee4df6e3a58ea29e5def4abdf7c07aa7d206e5e19b45cddb53214a1dfd5e1e4f5f9d7d77366779529ebe9fb33c2b95ef282fcacbcfca2bf52ebdbcc6aa956f63169437939d57793b6b39f5d565f6543c97aa77e5fdda9eca87f2b16c95edb25376cb9eb2a77e699583d22e9dcaac8ceac398b68a57228bb3acd251d4d37aae64e5e551e55741f34e5845b545cddb5315574935ac46553a7d75f6dd3afd64c552ef6555fe7ecefca52a54ed65557d565e3556ad7fcaf72b6d4fd573964d76dcd54bf5aa8adf98b59cfaea327baa36ab2d9563bba0cf4efc7bed49e962a7daadf6aafdeaa03aac8eaae3eaa43aadceaa7375e93b4ec66b9948a5fd5c755dd17d8c7fb33d293ddc5677d57df5503d56adaa5d75aa6ed5abfad507673bed29d6f2aefcbbed4959d4a0b22b676c8e8d311bf3b118bbe30fee3cade533f9b7dbd34535f6c6fe3818874a226f6b1cff7a89ff6659dbd35a56296b7b5acb2a656d4f6b59a5aced692dab94b53dad6595f2dffffffffeafff03226cdd73</data>
+ </image>
+</images>
+<connections>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">introwizard.ui.h</include>
+</includes>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/introwizard.ui.h b/src/introwizard.ui.h
new file mode 100644
index 0000000..069eb67
--- /dev/null
+++ b/src/introwizard.ui.h
@@ -0,0 +1,25 @@
+/***************************************************************************
+** $Id: introwizard.ui.h,v 1.4 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+void IntroWizard::init()
+{
+ setFinishEnabled ( Final,true );
+}
diff --git a/src/kerrylabel.cpp b/src/kerrylabel.cpp
new file mode 100644
index 0000000..4169138
--- /dev/null
+++ b/src/kerrylabel.cpp
@@ -0,0 +1,109 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1998 Kurt Granroth <granroth@kde.org>
+ Copyright (C) 2000 Peter Putzer <putzer@kde.org>
+ Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "kerrylabel.h"
+#include "hitwidget.h"
+
+#include <qdragobject.h>
+#include <kglobalsettings.h>
+#include <kurl.h>
+#include <krun.h>
+/*
+#include <konq_popupmenu.h>
+#include <konqbookmarkmanager.h>
+#include <knewmenu.h>
+*/
+
+KerryLabel::KerryLabel (QWidget* parent, const char* name)
+ : KURLLabel (parent, name)
+{
+ dragInfo.state = diNone;
+}
+
+void KerryLabel::mousePressEvent(QMouseEvent* ev)
+{
+ if (!url().isEmpty())
+ {
+ if ( ev->button() == LeftButton)
+ {
+ dragInfo.state = diPending;
+ dragInfo.start = ev->pos();
+ }
+ else if (ev->button() == RightButton)
+ {
+ ev->accept();
+ //popupMenu( mapToGlobal(ev->pos()) );
+ return;
+ }
+ }
+ KURLLabel::mousePressEvent(ev);
+}
+
+void KerryLabel::mouseMoveEvent(QMouseEvent* ev)
+{
+ if (dragInfo.state == diPending) {
+ int distance = KGlobalSettings::dndEventDelay();
+ if ( ev->x() > dragInfo.start.x() + distance || ev->x() < dragInfo.start.x() - distance ||
+ ev->y() > dragInfo.start.y() + distance || ev->y() < dragInfo.start.y() - distance) {
+ doDrag();
+ }
+ return;
+ }
+ KURLLabel::mouseMoveEvent(ev);
+}
+
+void KerryLabel::mouseReleaseEvent(QMouseEvent* ev)
+{
+ if ( ev->button() == LeftButton)
+ {
+ dragInfo.state = diNone;
+ }
+ KURLLabel::mouseReleaseEvent(ev);
+}
+
+void KerryLabel::doDrag()
+{
+ dragInfo.state = diDragging;
+ const KURL kuri = KURL(url());
+ dragInfo.dragObject = new QTextDrag("'"+kuri.url().replace("file://",QString::null)+"'", this);
+ dragInfo.dragObject->dragCopy();
+ // Don't delete the QTextDrag object. Qt will delete it when it's done with it.
+}
+
+// void KerryLabel::popupMenu( const QPoint &_global )
+// {
+// KFileItem item( ((HitWidget*)parent())->uri(),((HitWidget*)parent())->mimetype(),KFileItem::Unknown);
+// KFileItemList _items;
+// _items.append( &item );
+//
+// const KURL kurl(url());
+// KActionCollection act(this);
+//
+// KonqPopupMenu * popupMenu = new KonqPopupMenu( KonqBookmarkManager::self(), _items,
+// kurl, act, (KNewMenu*)NULL, this,
+// item.isLocalFile() ? KonqPopupMenu::ShowProperties : KonqPopupMenu::NoFlags,
+// KParts::BrowserExtension::DefaultPopupItems );
+//
+// if (popupMenu->count())
+// popupMenu->exec( _global );
+// delete popupMenu;
+// }
+
+#include "kerrylabel.moc"
diff --git a/src/kerrylabel.h b/src/kerrylabel.h
new file mode 100644
index 0000000..f6782be
--- /dev/null
+++ b/src/kerrylabel.h
@@ -0,0 +1,57 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 1998 Kurt Granroth <granroth@kde.org>
+ Copyright (C) 2000 Peter Putzer <putzer@kde.org>
+ Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KERRYLABEL_H
+#define KERRYLABEL_H
+
+#include <kurl.h>
+#include <kurllabel.h>
+
+class QTextDrag;
+
+class KerryLabel : public KURLLabel
+{
+ Q_OBJECT
+
+ public:
+ KerryLabel (QWidget* parent = 0L, const char* name = 0L);
+
+ protected:
+ void mousePressEvent( QMouseEvent* );
+ void mouseReleaseEvent( QMouseEvent* );
+ void mouseMoveEvent( QMouseEvent* );
+ void doDrag();
+
+// protected slots:
+// void popupMenu( const QPoint &_global );
+
+ private:
+ KURL::List kurllist;
+
+ enum DragState { diNone, diPending, diDragging };
+
+ struct _dragInfo {
+ DragState state;
+ QPoint start;
+ QTextDrag *dragObject;
+ } dragInfo;
+};
+
+#endif // KERRYLABEL_H
diff --git a/src/konqplugin/Makefile.am b/src/konqplugin/Makefile.am
new file mode 100644
index 0000000..a00dedd
--- /dev/null
+++ b/src/konqplugin/Makefile.am
@@ -0,0 +1,14 @@
+INCLUDES = $(all_includes)
+
+kde_module_LTLIBRARIES = khtml_tork.la
+
+khtml_tork_la_METASOURCES = AUTO
+khtml_tork_la_SOURCES = tork_plug_in.cpp
+khtml_tork_la_LIBADD = $(LIB_KHTML)
+khtml_tork_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module
+
+KDE_ICON = AUTO
+
+part_DATA = tork_plug_in.rc tork_plug_in.desktop
+partdir = $(kde_datadir)/khtml/kpartplugins
+
diff --git a/src/konqplugin/hi22-app-tork_konqueroroff.png b/src/konqplugin/hi22-app-tork_konqueroroff.png
new file mode 100644
index 0000000..f0181c7
--- /dev/null
+++ b/src/konqplugin/hi22-app-tork_konqueroroff.png
Binary files differ
diff --git a/src/konqplugin/hi22-app-tork_konqueroron.png b/src/konqplugin/hi22-app-tork_konqueroron.png
new file mode 100644
index 0000000..fbb4411
--- /dev/null
+++ b/src/konqplugin/hi22-app-tork_konqueroron.png
Binary files differ
diff --git a/src/konqplugin/hi48-app-tork_firefox.png b/src/konqplugin/hi48-app-tork_firefox.png
new file mode 100644
index 0000000..e48d705
--- /dev/null
+++ b/src/konqplugin/hi48-app-tork_firefox.png
Binary files differ
diff --git a/src/konqplugin/hi48-app-tork_opera.png b/src/konqplugin/hi48-app-tork_opera.png
new file mode 100644
index 0000000..b5e97a5
--- /dev/null
+++ b/src/konqplugin/hi48-app-tork_opera.png
Binary files differ
diff --git a/src/konqplugin/tork_plug_in.cpp b/src/konqplugin/tork_plug_in.cpp
new file mode 100644
index 0000000..cee0681
--- /dev/null
+++ b/src/konqplugin/tork_plug_in.cpp
@@ -0,0 +1,197 @@
+/***************************************************************************
+** $Id: tork_plug_in.cpp,v 1.4 2008/07/31 19:56:28 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+/***************************************************************************
+ kget_plug_in.cpp - description
+ -------------------
+ begin : Wed Jul 3 22:09:28 CEST 2002
+ copyright : (C) 2002 by Patrick
+ email : pch@valleeurpe.net
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "tork_plug_in.h"
+
+#include <dcopref.h>
+#include <kdatastream.h>
+#include <kdebug.h>
+#include <khtml_part.h>
+#include <kiconloader.h>
+#include <kglobal.h>
+#include <kaction.h>
+#include <kinstance.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+#include <krun.h>
+
+#include <dom/html_document.h>
+#include <dom/html_misc.h>
+#include <dom/dom_element.h>
+
+#include <kparts/partmanager.h>
+
+#include <set>
+
+
+Tork_plug_in::Tork_plug_in( QObject* parent, const char* name )
+ : Plugin( parent, name )
+{
+ QPixmap pix = KGlobal::iconLoader()->loadIcon("tork",
+ KIcon::MainToolbar);
+ KActionMenu *menu = new KActionMenu( i18n("Anonymity Manager"), pix,
+ actionCollection(), "tork_menu" );
+ menu->setDelayed( false );
+ connect( menu->popupMenu(), SIGNAL( aboutToShow() ), SLOT( showPopup() ));
+
+ m_paToggleKDE=new KAction(i18n("Anonymize KDE"),
+ KGlobal::iconLoader()->loadIconSet("tork_konqueroroff", KIcon::Small),
+ KShortcut(),
+ this, SLOT(toggleKDE()),
+ actionCollection(), "tork_konqueroron" );
+
+ menu->insert( m_paToggleKDE );
+
+
+ KAction *m_firefox=new KAction(i18n("Re-Open Anonymously with Firefox"),
+ KGlobal::iconLoader()->loadIconSet("tork_firefox", KIcon::Small),
+ KShortcut(),
+ this, SLOT(openWithFirefox()),
+ actionCollection(), "tork_firefox" );
+ menu->insert( m_firefox );
+
+ KAction *m_opera=new KAction(i18n("Re-Open Anonymously with Opera"),
+ KGlobal::iconLoader()->loadIconSet("tork_opera", KIcon::Small),
+ KShortcut(),
+ this, SLOT(openWithOpera()),
+ actionCollection(), "tork_opera" );
+ menu->insert( m_opera );
+
+ p_dcopServer= new DCOPClient();
+ p_dcopServer->attach ();
+}
+
+
+Tork_plug_in::~Tork_plug_in()
+{
+ p_dcopServer->detach();
+ delete p_dcopServer;
+}
+
+
+void Tork_plug_in::showPopup()
+{
+ bool anonymized = false;
+
+ if (p_dcopServer->isApplicationRegistered ("tork"))
+ {
+ DCOPRef tork( "tork", "DCOPTork" );
+ anonymized = tork.call( "getKDESetting" );
+ }
+
+ if (anonymized){
+ m_paToggleKDE->setIconSet( KGlobal::iconLoader()->loadIconSet("tork_konqueroroff",
+ KIcon::Small) );
+ m_paToggleKDE->setText( "De-Anonymize KDE" );
+ }else{
+ m_paToggleKDE->setIconSet( KGlobal::iconLoader()->loadIconSet("tork_konqueroron",
+ KIcon::Small) );
+ m_paToggleKDE->setText( "Anonymize KDE" );
+ }
+}
+
+void Tork_plug_in::openWithFirefox()
+{
+
+ openWithBrowser("Firefox");
+
+}
+
+void Tork_plug_in::openWithOpera()
+{
+
+ openWithBrowser("Opera");
+
+}
+
+void Tork_plug_in::openWithBrowser(const QString &browser)
+{
+ KHTMLPart *htmlPart = static_cast<KHTMLPart*>( parent() );
+ QString url = htmlPart->toplevelURL().url();
+
+ if (p_dcopServer->isApplicationRegistered ("tork")){
+ QString function = QString("anonymized%1").arg(browser);
+ DCOPRef("tork", "DCOPTork").send("startEverything");
+ DCOPRef("tork", "DCOPTork").send(QCString(function),url);
+ }else
+ KRun::runCommand( QString("tork --anonymous%1 %2").arg(browser).arg(url), "tork", "tork" );
+
+}
+
+void Tork_plug_in::toggleKDE()
+{
+ if (!p_dcopServer->isApplicationRegistered ("tork"))
+ KRun::runCommand("tork --toggleKDE");
+ else
+ {
+ DCOPRef tork( "tork", "DCOPTork" );
+ tork.send( "toggleKDESetting");
+ }
+}
+
+
+KPluginFactory::KPluginFactory( QObject* parent, const char* name )
+ : KLibFactory( parent, name )
+{
+ s_instance = new KInstance("KPluginFactory");
+}
+
+QObject* KPluginFactory::createObject( QObject* parent, const char* name, const char*, const QStringList & )
+{
+ QObject *obj = new Tork_plug_in( parent, name );
+ return obj;
+}
+
+KPluginFactory::~KPluginFactory()
+{
+ delete s_instance;
+}
+
+extern "C"
+{
+ KDE_EXPORT void* init_khtml_tork()
+ {
+ KGlobal::locale()->insertCatalogue("tork");
+ return new KPluginFactory;
+ }
+
+}
+
+KInstance* KPluginFactory::s_instance = 0L;
+
+#include "tork_plug_in.moc"
diff --git a/src/konqplugin/tork_plug_in.desktop b/src/konqplugin/tork_plug_in.desktop
new file mode 100644
index 0000000..4b2c518
--- /dev/null
+++ b/src/konqplugin/tork_plug_in.desktop
@@ -0,0 +1,15 @@
+[Desktop Entry]
+X-KDE-Library=khtml_tork
+X-KDE-PluginInfo-Author=Robert Hogan
+X-KDE-PluginInfo-Email=robert@roberthogan.net
+X-KDE-PluginInfo-Name=tork
+X-KDE-PluginInfo-Version=3.4
+X-KDE-PluginInfo-Website=http://tork.sourceforge.net
+X-KDE-PluginInfo-Category=Tools
+X-KDE-PluginInfo-Depends=
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=true
+Name=TorK
+Type=Application
+Comment=Anonymity Manager
+Icon=khtml_tork
diff --git a/src/konqplugin/tork_plug_in.h b/src/konqplugin/tork_plug_in.h
new file mode 100644
index 0000000..4df506c
--- /dev/null
+++ b/src/konqplugin/tork_plug_in.h
@@ -0,0 +1,81 @@
+/***************************************************************************
+ ** $Id: tork_plug_in.h,v 1.4 2008/07/31 19:56:28 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+/***************************************************************************
+ kget_plug_in.h - description
+ -------------------
+ begin : Wed Jul 3 22:09:28 CEST 2002
+ copyright : (C) 2002 by Patrick
+ email : pch@valleeurpe.net
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+#ifndef __plugin_tork_plug_in_h
+#define __plugin_tork_plug_in_h
+
+#include <kparts/plugin.h>
+#include <klibloader.h>
+#include <dcopclient.h>
+#include <kurl.h>
+
+class KInstance;
+
+class Tork_plug_in : public KParts::Plugin
+{
+ Q_OBJECT
+public:
+ Tork_plug_in( QObject* parent = 0, const char* name = 0 );
+ KAction *m_paToggleKDE ;
+ DCOPClient* p_dcopServer;
+ virtual ~Tork_plug_in();
+
+private slots:
+ void toggleKDE();
+ void openWithBrowser(const QString&);
+ void openWithFirefox();
+ void openWithOpera();
+ void showPopup();
+};
+
+
+class KPluginFactory : public KLibFactory
+{
+ Q_OBJECT
+public:
+ KPluginFactory( QObject *parent = 0, const char *name = 0 );
+ ~KPluginFactory() ;
+
+ virtual QObject* createObject( QObject* parent = 0, const char* pname = 0,
+ const char* name = "QObject",
+ const QStringList &args = QStringList() );
+
+private:
+ static KInstance* s_instance;
+};
+
+#endif
diff --git a/src/konqplugin/tork_plug_in.rc b/src/konqplugin/tork_plug_in.rc
new file mode 100644
index 0000000..8b803b5
--- /dev/null
+++ b/src/konqplugin/tork_plug_in.rc
@@ -0,0 +1,11 @@
+<!DOCTYPE kpartgui>
+<kpartgui library="khtml_tork" name="khtml_tork" version="3" >
+<MenuBar>
+ <Menu name="tools"><Text>&amp;Tools</Text>
+ <Action name="tork_menu"/>
+ </Menu>
+</MenuBar>
+<ToolBar name="mainToolBar">
+ <Action name="tork_menu"/>
+</ToolBar>
+</kpartgui>
diff --git a/src/konqueror.ui b/src/konqueror.ui
new file mode 100644
index 0000000..0495b85
--- /dev/null
+++ b/src/konqueror.ui
@@ -0,0 +1,440 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Konq</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Konq</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>474</width>
+ <height>498</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Konqueror</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Privacy Proxy</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QButtonGroup" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Manage Proxy as follows</string>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>kcfg_SystemProxy</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>6</x>
+ <y>19</y>
+ <width>390</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Let my Privacy Proxy start and look after itself.</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>kcfg_TorkProxy</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>6</x>
+ <y>49</y>
+ <width>390</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Let TorK start and manage Privoxy as my privacy proxy.</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ <widget class="KURLComboRequester" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_PrivoxyLocation</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Location of Privoxy TorK will manage:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Konqueror Settings</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Anonymity Safeguards</string>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_DisableJava</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>20</y>
+ <width>200</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Disable Java/Javascript</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_DisableCookies</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>50</y>
+ <width>190</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Disable Cookies</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_DisableBrowserIdentification</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>80</y>
+ <width>370</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Disable Browser Identification</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_DisablePlugins</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>220</x>
+ <y>20</y>
+ <width>190</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Disable Plugins</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_DisableCaching</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>220</x>
+ <y>47</y>
+ <width>190</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Disable Caching</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Connect to Privacy Proxy as Follows</string>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>61</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>HTTP:</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>60</y>
+ <width>61</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>HTTPS:</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>10</x>
+ <y>90</y>
+ <width>61</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>FTP:</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>71</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>339</x>
+ <y>31</y>
+ <width>71</width>
+ <height>20</height>
+ </rect>
+ </property>
+ </spacer>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>71</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>339</x>
+ <y>61</y>
+ <width>71</width>
+ <height>20</height>
+ </rect>
+ </property>
+ </spacer>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>71</width>
+ <height>20</height>
+ </size>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>339</x>
+ <y>91</y>
+ <width>71</width>
+ <height>20</height>
+ </rect>
+ </property>
+ </spacer>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_KonqHttpsProxy</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>60</y>
+ <width>161</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_KonqFtpProxy</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>90</y>
+ <width>161</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>kcfg_KonqHttpProxyPort</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>260</x>
+ <y>30</y>
+ <width>71</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>kcfg_KonqHttpsProxyPort</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>260</x>
+ <y>60</y>
+ <width>71</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>kcfg_KonqFtpProxyPort</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>260</x>
+ <y>90</y>
+ <width>71</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_KonqHttpProxy</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>90</x>
+ <y>30</y>
+ <width>161</width>
+ <height>21</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>kcfg_TorkProxy</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>Konq</receiver>
+ <slot>kcfg_TorkProxy_toggled(bool)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">konqueror.ui.h</include>
+</includes>
+<slots>
+ <slot>kcfg_TorkProxy_toggled( bool state )</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/src/konqueror.ui.h b/src/konqueror.ui.h
new file mode 100644
index 0000000..778b32a
--- /dev/null
+++ b/src/konqueror.ui.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ ** $Id: konqueror.ui.h,v 1.4 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+void Konq::init()
+{
+ kcfg_PrivoxyLocation->setEnabled(kcfg_TorkProxy->isEnabled());
+
+ kcfg_KonqHttpProxy->setEnabled(!kcfg_TorkProxy->isEnabled());
+ kcfg_KonqHttpsProxy->setEnabled(!kcfg_TorkProxy->isEnabled());
+ kcfg_KonqHttpProxyPort->setEnabled(!kcfg_TorkProxy->isEnabled());
+ kcfg_KonqHttpsProxyPort->setEnabled(!kcfg_TorkProxy->isEnabled());
+
+}
+
+void Konq::kcfg_TorkProxy_toggled( bool state)
+{
+
+ if (state){
+ kcfg_KonqHttpProxy->setText("http://localhost");
+ kcfg_KonqHttpsProxy->setText("http://localhost");
+ kcfg_KonqHttpProxyPort->setValue(8118);
+ kcfg_KonqHttpsProxyPort->setValue(8118);
+ }
+
+ kcfg_PrivoxyLocation->setEnabled(state);
+
+ kcfg_KonqHttpProxy->setEnabled(!state);
+ kcfg_KonqHttpsProxy->setEnabled(!state);
+ kcfg_KonqHttpProxyPort->setEnabled(!state);
+ kcfg_KonqHttpsProxyPort->setEnabled(!state);
+
+}
diff --git a/src/kwidgetlistbox.cpp b/src/kwidgetlistbox.cpp
new file mode 100644
index 0000000..1c32868
--- /dev/null
+++ b/src/kwidgetlistbox.cpp
@@ -0,0 +1,223 @@
+/***************************************************************************
+ * Copyright (C) 2005 Petri Damst� <petri.damsten@iki.fi> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
+ ***************************************************************************/
+
+#include "kwidgetlistbox.h"
+#include <kdebug.h>
+#include <kglobalsettings.h>
+#include <hitwidget.h>
+
+KWidgetListbox::KWidgetListbox(QWidget *parent, const char *name)
+ : QTable(parent, name)
+{
+ setNumRows(0);
+ setNumCols(1);
+ setColumnStretchable(0, true);
+ setLeftMargin(0);
+ setTopMargin(0);
+ horizontalHeader()->hide();
+ verticalHeader()->hide();
+ setSelectionMode(QTable::NoSelection);
+ setFocusStyle(QTable::FollowStyle);
+ connect(this, SIGNAL(currentChanged(int, int)),
+ this, SLOT(selectionChanged(int, int)));
+ setHScrollBarMode(QScrollView::AlwaysOff);
+ setVScrollBarMode(QScrollView::Auto);
+}
+
+KWidgetListbox::~KWidgetListbox()
+{
+ clear();
+}
+
+void KWidgetListbox::clear()
+{
+ for(int i = 0; i < numRows(); ++i)
+ clearCellWidget(i, 0);
+ setNumRows(0);
+}
+
+int KWidgetListbox::insertItem(QWidget* item, int index)
+{
+ int row;
+
+ if(index == -1 || numRows()==0)
+ {
+ row = numRows();
+ setNumRows(row + 1);
+ }
+ else {
+ row = index;
+ insertRows(row);
+ }
+
+ item->setMinimumWidth( width() );
+ item->adjustSize();
+
+ HitWidget* hit = dynamic_cast<HitWidget*>(item);
+ if (hit && hit->isCollapsed())
+//#warning fixme
+ setRowHeight(row, 30);
+ else
+ setRowHeight(row, item->sizeHint().height());
+ setCellWidget(row, 0, item);
+ setItemColors(row, even(row));
+ return row;
+}
+
+void KWidgetListbox::adjustSize(QWidget* item)
+{
+ item->setMinimumWidth( columnWidth(0) );
+ item->adjustSize();
+ HitWidget* hit = (HitWidget*)item;
+ if (hit->isCollapsed())
+ setRowHeight(index(item), 28);
+ else
+ setRowHeight(index(item), item->height());
+}
+
+void KWidgetListbox::setSelected(QWidget* item)
+{
+ setSelected(index(item));
+}
+
+void KWidgetListbox::selectionChanged(int row, int col)
+{
+ ensureCellVisible(row, col);
+ updateColors();
+ emit selected(row);
+}
+
+void KWidgetListbox::removeItem(QWidget* item)
+{
+ removeItem(index(item));
+}
+
+void KWidgetListbox::removeItem(int index)
+{
+ removeRow(index);
+ updateColors();
+}
+
+void KWidgetListbox::setSelected(int index)
+{
+ setCurrentCell(index, 0);
+}
+
+int KWidgetListbox::selected() const
+{
+ return currentRow();
+}
+
+QWidget* KWidgetListbox::selectedItem() const
+{
+ return item(selected());
+}
+
+QWidget* KWidgetListbox::item(int index) const
+{
+ return cellWidget(index, 0);
+}
+
+int KWidgetListbox::index(QWidget* itm) const
+{
+ for(int i = 0; i < numRows(); ++i)
+ if(item(i) == itm)
+ return i;
+ return -1;
+}
+
+bool KWidgetListbox::even(int index)
+{
+ int v = 0;
+ for(int i = 0; i < numRows(); ++i)
+ {
+ if(index == i)
+ break;
+ if(!isRowHidden(i))
+ ++v;
+ }
+ return (v%2 == 0);
+}
+
+void KWidgetListbox::updateColors()
+{
+ int v = 0;
+ for(int i = 0; i < numRows(); ++i)
+ {
+ if(!isRowHidden(i))
+ {
+ setItemColors(i, (v%2 == 0));
+ ++v;
+ }
+ }
+}
+
+void KWidgetListbox::setItemColors(int index, bool even)
+{
+ QWidget* itm = item(index);
+
+ if (!itm)
+ return;
+
+ if(index == selected())
+ {
+ itm->setPaletteBackgroundColor(KGlobalSettings::highlightColor());
+ itm->setPaletteForegroundColor(KGlobalSettings::highlightedTextColor());
+ }
+ else if(even)
+ {
+ itm->setPaletteBackgroundColor(KGlobalSettings::baseColor());
+ itm->setPaletteForegroundColor(KGlobalSettings::textColor());
+ }
+ else
+ {
+ itm->setPaletteBackgroundColor(
+ KGlobalSettings::alternateBackgroundColor());
+ itm->setPaletteForegroundColor(KGlobalSettings::textColor());
+ }
+}
+
+void KWidgetListbox::showItems(show_callback func, void* data)
+{
+ for(int i = 0; i < numRows(); ++i)
+ {
+ if(func == 0)
+ showRow(i);
+ else
+ {
+ if(func(i, item(i), data))
+ showRow(i);
+ else
+ hideRow(i);
+ }
+ }
+ updateColors();
+}
+
+void KWidgetListbox::showEvent(QShowEvent*)
+{
+ repaintContents(false);
+}
+
+void KWidgetListbox::paintCell(QPainter*, int, int, const QRect&,
+ bool, const QColorGroup&)
+{
+}
+
+#include "kwidgetlistbox.moc"
diff --git a/src/kwidgetlistbox.h b/src/kwidgetlistbox.h
new file mode 100644
index 0000000..eae1fb7
--- /dev/null
+++ b/src/kwidgetlistbox.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ * Copyright (C) 2005 Petri Damst�n <petri.damsten@iki.fi> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
+ ***************************************************************************/
+
+#ifndef KWIDGETLISTBOX_H
+#define KWIDGETLISTBOX_H
+
+#include <qtable.h>
+
+typedef bool (*show_callback) (int index, QWidget* widget, void* data);
+
+class KWidgetListbox : public QTable
+{
+ Q_OBJECT
+
+ public:
+ KWidgetListbox(QWidget *parent = 0, const char *name = 0);
+ ~KWidgetListbox();
+
+ int insertItem(QWidget* item, int index = -1);
+ void setSelected(QWidget* item);
+ void setSelected(int index);
+ void removeItem(QWidget* item);
+ void removeItem(int index);
+ void clear();
+ int selected() const;
+ QWidget* selectedItem() const;
+ QWidget* item(int index) const;
+ int index(QWidget* itm) const;
+ uint count() const { return numRows(); };
+
+ void showItems(show_callback func = 0, void* data = 0);
+
+ void paintCell(QPainter* p, int row, int col, const QRect& cr,
+ bool selected, const QColorGroup& cg);
+ void adjustSize(QWidget* item);
+ protected:
+ void setItemColors(int index, bool even);
+ void updateColors();
+ bool even(int index);
+ virtual void showEvent(QShowEvent* e);
+
+ protected slots:
+ void selectionChanged(int row, int col);
+
+ signals:
+ void selected(int index);
+};
+
+#endif
diff --git a/src/likeback.cpp b/src/likeback.cpp
new file mode 100644
index 0000000..d38f6b5
--- /dev/null
+++ b/src/likeback.cpp
@@ -0,0 +1,854 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Sebastien Laout *
+ * slaout@linux62.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library General Public License as *
+ * published by the Free Software Foundation; either version 2 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <kconfig.h>
+#include <kaction.h>
+#include <kiconloader.h>
+#include <kaboutdata.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <qlayout.h>
+#include <qtoolbutton.h>
+#include <kpushbutton.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qvgroupbox.h>
+#include <kguiitem.h>
+#include <qpopupmenu.h>
+#include <qtextedit.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <kdialogbase.h>
+#include <qhttp.h>
+#include <kurl.h>
+#include <kinputdialog.h>
+#include <qvalidator.h>
+#include <qaction.h>
+#include <kdebug.h>
+
+#include <pwd.h>
+
+#include <iostream>
+
+#include "likeback.h"
+#include "likeback_private.h"
+
+/****************************************/
+/********** class LikeBackBar: **********/
+/****************************************/
+
+LikeBackBar::LikeBackBar(LikeBack *likeBack)
+ : QWidget(0, "LikeBackBar", Qt::WX11BypassWM | Qt::WStyle_NoBorder | Qt::WNoAutoErase | Qt::WStyle_StaysOnTop | Qt::WStyle_NoBorder | Qt::Qt::WGroupLeader)
+ , m_likeBack(likeBack)
+{
+ QHBoxLayout *layout = new QHBoxLayout(this);
+
+ QIconSet likeIconSet = kapp->iconLoader()->loadIconSet("likeback_like_tork", KIcon::Small);
+ QIconSet dislikeIconSet = kapp->iconLoader()->loadIconSet("likeback_dislike_tork", KIcon::Small);
+ QIconSet bugIconSet = kapp->iconLoader()->loadIconSet("likeback_bug_tork", KIcon::Small);
+ QIconSet featureIconSet = kapp->iconLoader()->loadIconSet("likeback_feature_tork", KIcon::Small);
+
+ m_likeButton = new QToolButton(this, "likeback_like_tork");
+ m_likeButton->setIconSet(likeIconSet);
+ m_likeButton->setTextLabel("<p>" + i18n("Send application developers a comment about something you like"));
+ m_likeButton->setAutoRaise(true);
+ connect( m_likeButton, SIGNAL(clicked()), this, SLOT(clickedLike()) );
+ layout->add(m_likeButton);
+
+ m_dislikeButton = new QToolButton(this, "likeback_dislike_tork");
+ m_dislikeButton->setIconSet(dislikeIconSet);
+ m_dislikeButton->setTextLabel("<p>" + i18n("Send application developers a comment about something you dislike"));
+ m_dislikeButton->setAutoRaise(true);
+ connect( m_dislikeButton, SIGNAL(clicked()), this, SLOT(clickedDislike()) );
+ layout->add(m_dislikeButton);
+
+ m_bugButton = new QToolButton(this, "likeback_bug_tork");
+ m_bugButton->setIconSet(bugIconSet);
+ m_bugButton->setTextLabel("<p>" + i18n("Send application developers a comment about an improper behavior of the application"));
+ m_bugButton->setAutoRaise(true);
+ connect( m_bugButton, SIGNAL(clicked()), this, SLOT(clickedBug()) );
+ layout->add(m_bugButton);
+
+ m_featureButton = new QToolButton(this, "likeback_feature_tork");
+ m_featureButton->setIconSet(featureIconSet);
+ m_featureButton->setTextLabel("<p>" + i18n("Send application developers a comment about a new feature you desire"));
+ m_featureButton->setAutoRaise(true);
+ connect( m_featureButton, SIGNAL(clicked()), this, SLOT(clickedFeature()) );
+ layout->add(m_featureButton);
+
+ connect( &m_timer, SIGNAL(timeout()), this, SLOT(autoMove()) );
+
+ LikeBack::Button buttons = likeBack->buttons();
+ m_likeButton->setShown( buttons & LikeBack::Like );
+ m_dislikeButton->setShown( buttons & LikeBack::Dislike );
+ m_bugButton->setShown( buttons & LikeBack::Bug );
+ m_featureButton->setShown( buttons & LikeBack::Feature );
+}
+
+LikeBackBar::~LikeBackBar()
+{
+}
+
+void LikeBackBar::startTimer()
+{
+ m_timer.start(10);
+}
+
+void LikeBackBar::stopTimer()
+{
+ m_timer.stop();
+}
+
+void LikeBackBar::autoMove()
+{
+ static QWidget *lastWindow = 0;
+
+ QWidget *window = kapp->activeWindow();
+ // When a Kicker applet has the focus, like the Commandline QLineEdit,
+ // the systemtray icon indicates to be the current window and the LikeBack is shown next to the system tray icon.
+ // It's obviously bad ;-) :
+ bool shouldShow = (m_likeBack->userWantsToShowBar() && m_likeBack->enabledBar() && window && !window->inherits("KSystemTray"));
+ if (shouldShow) {
+ //move(window->x() + window->width() - 100 - width(), window->y());
+ //move(window->x() + window->width() - 100 - width(), window->mapToGlobal(QPoint(0, 0)).y() - height());
+ move(window->mapToGlobal(QPoint(0, 0)).x() + window->width() - width(), window->mapToGlobal(QPoint(0, 0)).y() + 1);
+
+ if (window != lastWindow && m_likeBack->windowNamesListing() != LikeBack::NoListing) {
+ if (qstricmp(window->name(), "") == 0 || qstricmp(window->name(), "unnamed") == 0) {
+ std::cout << "===== LikeBack ===== UNNAMED ACTIVE WINDOW OF TYPE " << window->className() << " ======" << LikeBack::activeWindowPath() << std::endl;
+ } else if (m_likeBack->windowNamesListing() == LikeBack::AllWindows) {
+ std::cout << "LikeBack: Active Window: " << LikeBack::activeWindowPath() << std::endl;
+ }
+ }
+ lastWindow = window;
+ }
+
+ // Show or hide the bar accordingly:
+ if (shouldShow && !isShown()) {
+ show();
+ } else if (!shouldShow && isShown()) {
+ hide();
+ }
+}
+
+void LikeBackBar::clickedLike()
+{
+ m_likeBack->execCommentDialog(LikeBack::Like);
+}
+
+void LikeBackBar::clickedDislike()
+{
+ m_likeBack->execCommentDialog(LikeBack::Dislike);
+}
+
+void LikeBackBar::clickedBug()
+{
+ m_likeBack->execCommentDialog(LikeBack::Bug);
+}
+
+void LikeBackBar::clickedFeature()
+{
+ m_likeBack->execCommentDialog(LikeBack::Feature);
+}
+
+/********************************************/
+/********** class LikeBackPrivate: **********/
+/********************************************/
+
+LikeBackPrivate::LikeBackPrivate()
+ : bar(0)
+ , config(0)
+ , aboutData(0)
+ , buttons(LikeBack::DefaultButtons)
+ , hostName()
+ , remotePath()
+ , hostPort(80)
+ , acceptedLocales()
+ , acceptedLanguagesMessage()
+ , windowListing(LikeBack::NoListing)
+ , showBar(false)
+ , disabledCount(0)
+ , fetchedEmail()
+ , action(0)
+{
+}
+
+LikeBackPrivate::~LikeBackPrivate()
+{
+ delete bar;
+ delete action;
+
+ config = 0;
+ aboutData = 0;
+}
+
+/*************************************/
+/********** class LikeBack: **********/
+/*************************************/
+
+LikeBack::LikeBack(Button buttons, bool showBarByDefault, KConfig *config, const KAboutData *aboutData)
+ : QObject()
+{
+ // Initialize properties (1/2):
+ d = new LikeBackPrivate();
+ d->buttons = buttons;
+ d->config = config;
+ d->aboutData = aboutData;
+ d->showBarByDefault = showBarByDefault;
+
+ // Use default KApplication config and aboutData if not provided:
+ if (d->config == 0)
+ d->config = kapp->config();
+ if (d->aboutData == 0)
+ d->aboutData = kapp->aboutData();
+
+ // Initialize properties (2/2) [Needs aboutData to be set]:
+ d->showBar = userWantsToShowBar();
+
+ // Fetch the KControl user email address as a default one:
+ if (!emailAddressAlreadyProvided())
+ fetchUserEmail();
+
+ // Initialize the button-bar:
+ d->bar = new LikeBackBar(this);
+ d->bar->resize(d->bar->sizeHint());
+
+ // Show the information message if it is the first time, and if the button-bar is shown:
+ static const char *messageShown = "LikeBack_starting_information";
+ if (d->showBar && KMessageBox::shouldBeShownContinue(messageShown)) {
+ showInformationMessage();
+ KMessageBox::saveDontShowAgainContinue(messageShown);
+ }
+
+ // Show the bar if that's wanted by the developer or the user:
+ if (d->showBar)
+ QTimer::singleShot( 0, d->bar, SLOT(startTimer()) );
+
+#if 0
+ disableBar();
+ // Alex: Oh, it drove me nuts
+ d->buttons = (Button) ( 0); showInformationMessage();
+ d->buttons = (Button) ( Feature); showInformationMessage();
+ d->buttons = (Button) ( Bug ); showInformationMessage();
+ d->buttons = (Button) ( Bug | Feature); showInformationMessage();
+ d->buttons = (Button) ( Dislike ); showInformationMessage();
+ d->buttons = (Button) ( Dislike | Feature); showInformationMessage();
+ d->buttons = (Button) ( Dislike | Bug ); showInformationMessage();
+ d->buttons = (Button) ( Dislike | Bug | Feature); showInformationMessage();
+ d->buttons = (Button) (Like ); showInformationMessage();
+ d->buttons = (Button) (Like | Feature); showInformationMessage();
+ d->buttons = (Button) (Like | Bug ); showInformationMessage();
+ d->buttons = (Button) (Like | Bug | Feature); showInformationMessage();
+ d->buttons = (Button) (Like | Dislike ); showInformationMessage();
+ d->buttons = (Button) (Like | Dislike | Feature); showInformationMessage();
+ d->buttons = (Button) (Like | Dislike | Bug ); showInformationMessage();
+ d->buttons = (Button) (Like | Dislike | Bug | Feature); showInformationMessage();
+ enableBar();
+#endif
+}
+
+LikeBack::~LikeBack()
+{
+ delete d;
+}
+
+void LikeBack::setWindowNamesListing(WindowListing windowListing)
+{
+ d->windowListing = windowListing;
+}
+
+LikeBack::WindowListing LikeBack::windowNamesListing()
+{
+ return d->windowListing;
+}
+
+void LikeBack::setAcceptedLanguages(const QStringList &locales, const QString &message)
+{
+ d->acceptedLocales = locales;
+ d->acceptedLanguagesMessage = message;
+}
+
+QStringList LikeBack::acceptedLocales()
+{
+ return d->acceptedLocales;
+}
+
+QString LikeBack::acceptedLanguagesMessage()
+{
+ return d->acceptedLanguagesMessage;
+}
+
+void LikeBack::setServer(const QString &hostName, const QString &remotePath, Q_UINT16 hostPort)
+{
+ d->hostName = hostName;
+ d->remotePath = remotePath;
+ d->hostPort = hostPort;
+}
+
+QString LikeBack::hostName()
+{
+ return d->hostName;
+}
+
+QString LikeBack::remotePath()
+{
+ return d->remotePath;
+}
+
+Q_UINT16 LikeBack::hostPort()
+{
+ return d->hostPort;
+}
+
+void LikeBack::disableBar()
+{
+ d->disabledCount++;
+ if (d->bar && d->disabledCount > 0) {
+ d->bar->hide();
+ d->bar->stopTimer();
+ }
+}
+
+void LikeBack::enableBar()
+{
+ d->disabledCount--;
+ if (d->disabledCount < 0)
+ std::cerr << "===== LikeBack ===== Enabled more times than it was disabled. Please refer to the disableBar() documentation for more information and hints." << std::endl;
+ if (d->bar && d->disabledCount <= 0) {
+ d->bar->startTimer();
+ }
+}
+
+bool LikeBack::enabledBar()
+{
+ return d->disabledCount <= 0;
+}
+
+void LikeBack::execCommentDialog(Button type, const QString &initialComment, const QString &windowPath, const QString &context)
+{
+ disableBar();
+ LikeBackDialog dialog(type, initialComment, windowPath, context, this);
+ dialog.exec();
+ enableBar();
+}
+
+void LikeBack::execCommentDialogFromHelp()
+{
+ execCommentDialog(AllButtons, /*initialComment=*/"", /*windowPath=*/"HelpMenuAction");
+}
+
+LikeBack::Button LikeBack::buttons()
+{
+ return d->buttons;
+}
+
+const KAboutData* LikeBack::aboutData()
+{
+ return d->aboutData;
+}
+
+KConfig* LikeBack::config()
+{
+ return d->config;
+}
+
+KAction* LikeBack::sendACommentAction(KActionCollection *parent)
+{
+ if (d->action == 0)
+ d->action = new KAction(
+ i18n("&Send a Comment to Developers"), /*icon=*/"mail_new", /*shortcut=*/"",
+ this, SLOT(execCommentDialog()),
+ parent, "likeback_send_a_comment"
+ );
+
+ return d->action;
+}
+
+bool LikeBack::userWantsToShowBar()
+{
+ // Store the button-bar per version, so it can be disabled by the developer for the final version:
+ d->config->setGroup("LikeBack");
+ return d->config->readBoolEntry("userWantToShowBarForVersion_" + d->aboutData->version(), d->showBarByDefault);
+}
+
+void LikeBack::setUserWantsToShowBar(bool showBar)
+{
+ if (showBar == d->showBar)
+ return;
+
+ d->showBar = showBar;
+
+ // Store the button-bar per version, so it can be disabled by the developer for the final version:
+ d->config->setGroup("LikeBack");
+ d->config->writeEntry("userWantToShowBarForVersion_" + d->aboutData->version(), showBar);
+ d->config->sync(); // Make sure the option is saved, even if the application crashes after that.
+
+ if (showBar)
+ d->bar->startTimer();
+}
+
+void LikeBack::showInformationMessage()
+{
+ // Load and register the images needed by the message:
+ QPixmap likeIcon = kapp->iconLoader()->loadIcon("likeback_like_tork", KIcon::Small);
+ QPixmap dislikeIcon = kapp->iconLoader()->loadIcon("likeback_dislike_tork", KIcon::Small);
+ QPixmap bugIcon = kapp->iconLoader()->loadIcon("likeback_bug_tork", KIcon::Small);
+ QPixmap featureIcon = kapp->iconLoader()->loadIcon("likeback_feature_tork", KIcon::Small);
+ QMimeSourceFactory::defaultFactory()->setPixmap("likeback_icon_like", likeIcon);
+ QMimeSourceFactory::defaultFactory()->setPixmap("likeback_icon_dislike", dislikeIcon);
+ QMimeSourceFactory::defaultFactory()->setPixmap("likeback_icon_bug", bugIcon);
+ QMimeSourceFactory::defaultFactory()->setPixmap("likeback_icon_feature", featureIcon);
+
+ // Show a message reflecting the allowed types of comment:
+ Button buttons = d->buttons;
+ int nbButtons = (buttons & Like ? 1 : 0) +
+ (buttons & Dislike ? 1 : 0) +
+ (buttons & Bug ? 1 : 0) +
+ (buttons & Feature ? 1 : 0);
+ KMessageBox::information(0,
+ "<p><b>" + (isDevelopmentVersion(d->aboutData->version()) ?
+ i18n("Welcome to this testing version of %1.") :
+ i18n("Welcome to %1.")
+ ).arg(d->aboutData->programName()) + "</b></p>"
+ "<p>" + i18n("To help us improve it, your comments are important.") + "</p>"
+ "<p>" +
+ ((buttons & LikeBack::Like) && (buttons & LikeBack::Dislike) ?
+ i18n("Each time you have a great or frustrating experience, "
+ "please click the appropriate face below the window title-bar, "
+ "briefly describe what you like or dislike and click Send.")
+ : (buttons & LikeBack::Like ?
+ i18n("Each time you have a great experience, "
+ "please click the smiling face below the window title-bar, "
+ "briefly describe what you like and click Send.")
+ : (buttons & LikeBack::Dislike ?
+ i18n("Each time you have a frustrating experience, "
+ "please click the frowning face below the window title-bar, "
+ "briefly describe what you dislike and click Send.")
+ :
+ QString()
+ ))) + "</p>" +
+ (buttons & LikeBack::Bug ?
+ "<p>" +
+ (buttons & (LikeBack::Like | LikeBack::Dislike) ?
+ i18n("Follow the same principle to quickly report a bug: "
+ "just click the broken-object icon in the top-right corner of the window, describe it and click Send.")
+ :
+ i18n("Each time you discover a bug in the application, "
+ "please click the broken-object icon below the window title-bar, "
+ "briefly describe what is the mis-behaviour and click Send.")
+ ) + "</p>"
+ : "") +
+ "<p>" + i18n("Example:", "Examples:", nbButtons) + "</p>" +
+ (buttons & LikeBack::Like ?
+ "<p><img source=\"likeback_icon_like\"> &nbsp;" +
+ i18n("<b>I like</b> the new artwork. Very refreshing.") + "</p>"
+ : "") +
+ (buttons & LikeBack::Dislike ?
+ "<p><img source=\"likeback_icon_dislike\"> &nbsp;" +
+ i18n("<b>I dislike</b> the welcome page of that assistant. Too time consuming.") + "</p>"
+ : "") +
+ (buttons & LikeBack::Bug ?
+ "<p><img source=\"likeback_icon_bug\"> &nbsp;" +
+ i18n("<b>The application has an improper behaviour</b> when clicking the Add button. Nothing happens.") + "</p>"
+ : "") +
+ (buttons & LikeBack::Feature ?
+ "<p><img source=\"likeback_icon_feature\"> &nbsp;" +
+ i18n("<b>I desire a new feature</b> allowing me to send my work by email.") + "</p>"
+ : "") +
+ "</tr></table>",
+ i18n("Help Improve the Application"));
+
+ // Reset the images from the factory:
+ QMimeSourceFactory::defaultFactory()->setData("likeback_icon_like", 0L);
+ QMimeSourceFactory::defaultFactory()->setData("likeback_icon_dislike", 0L);
+ QMimeSourceFactory::defaultFactory()->setData("likeback_icon_bug", 0L);
+ QMimeSourceFactory::defaultFactory()->setData("likeback_icon_feature", 0L);
+}
+
+QString LikeBack::activeWindowPath()
+{
+ // Compute the window hierarchy (from the latest to the oldest):
+ QStringList windowNames;
+ QWidget *window = kapp->activeWindow();
+ while (window) {
+ QString name = window->name();
+ // Append the class name to the window name if it is unnamed:
+ if (name == "unnamed")
+ name += QString(":") + window->className();
+ windowNames.append(name);
+ window = dynamic_cast<QWidget*>(window->parent());
+ }
+
+ // Create the string of windows starting by the end (from the oldest to the latest):
+ QString windowPath;
+ for (int i = ((int)windowNames.count()) - 1; i >= 0; i--) {
+ if (windowPath.isEmpty())
+ windowPath = windowNames[i];
+ else
+ windowPath += QString("~~") + windowNames[i];
+ }
+
+ // Finally return the computed path:
+ return windowPath;
+}
+
+bool LikeBack::emailAddressAlreadyProvided()
+{
+ d->config->setGroup("LikeBack");
+ return d->config->readBoolEntry("emailAlreadyAsked", false);
+}
+
+QString LikeBack::emailAddress()
+{
+ if (!emailAddressAlreadyProvided())
+ askEmailAddress();
+
+ d->config->setGroup("LikeBack");
+ return d->config->readEntry("emailAddress", "");
+}
+
+void LikeBack::setEmailAddress(const QString &address, bool userProvided)
+{
+ d->config->setGroup("LikeBack");
+ d->config->writeEntry("emailAddress", address);
+ d->config->writeEntry("emailAlreadyAsked", userProvided || emailAddressAlreadyProvided());
+ d->config->sync(); // Make sure the option is saved, even if the application crashes after that.
+}
+
+void LikeBack::askEmailAddress()
+{
+ d->config->setGroup("LikeBack");
+
+ QString currentEmailAddress = d->config->readEntry("emailAddress", "");
+ if (!emailAddressAlreadyProvided() && !d->fetchedEmail.isEmpty())
+ currentEmailAddress = d->fetchedEmail;
+
+ bool ok;
+
+ QString emailExpString = "[\\w-\\.]+@[\\w-\\.]+\\.[\\w]+";
+ //QString namedEmailExpString = "[.]*[ \\t]+<" + emailExpString + '>';
+ //QRegExp emailExp("^(|" + emailExpString + '|' + namedEmailExpString + ")$");
+ QRegExp emailExp("^(|" + emailExpString + ")$");
+ QRegExpValidator emailValidator(emailExp, this);
+
+ disableBar();
+ QString email = KInputDialog::getText(
+ i18n("Email Address"),
+ "<p><b>" + i18n("Please provide your email address.") + "</b></p>" +
+ "<p>" + i18n("It will only be used to contact you back if more information is needed about your comments, ask you how to reproduce the bugs you report, send bug corrections for you to test, etc.") + "</p>" +
+ "<p>" + i18n("The email address is optional. If you do not provide any, your comments will be sent anonymously.") + "</p>",
+ currentEmailAddress, &ok, kapp->activeWindow(), /*name=*/(const char*)0, &emailValidator);
+ enableBar();
+
+ if (ok)
+ setEmailAddress(email);
+}
+
+// FIXME: Should be moved to KAboutData? Cigogne will also need it.
+bool LikeBack::isDevelopmentVersion(const QString &version)
+{
+ return version.find("alpha", /*index=*/0, /*caseSensitive=*/false) != -1 ||
+ version.find("beta", /*index=*/0, /*caseSensitive=*/false) != -1 ||
+ version.find("rc", /*index=*/0, /*caseSensitive=*/false) != -1 ||
+ version.find("svn", /*index=*/0, /*caseSensitive=*/false) != -1 ||
+ version.find("cvs", /*index=*/0, /*caseSensitive=*/false) != -1;
+}
+
+/**
+ * Code from KBugReport::slotConfigureEmail() in kdeui/kbugreport.cpp:
+ */
+/*void LikeBack::beginFetchingEmail()
+{
+ if (m_process)
+ return;
+ m_process = new KProcess();
+ *m_process << QString::fromLatin1("kcmshell") << QString::fromLatin1("kcm_useraccount");
+ connect( m_process, SIGNAL(processExited(KProcess*)), SLOT(fetchUserEmail()) );
+ if (!m_process->start()) {
+ kdDebug() << "Couldn't start kcmshell.." << endl;
+ delete m_process;
+ m_process = 0;
+ return;
+ }
+// m_configureEmail->setEnabled(false);
+}*/
+
+/**
+ * Code from KBugReport::slotSetFrom() in kdeui/kbugreport.cpp:
+ */
+void LikeBack::fetchUserEmail()
+{
+// delete m_process;
+// m_process = 0;
+// m_configureEmail->setEnabled(true);
+
+ // ### KDE4: why oh why is KEmailSettings in kio?
+ KConfig emailConf( QString::fromLatin1("emaildefaults") );
+
+ // find out the default profile
+ emailConf.setGroup(QString::fromLatin1("Defaults"));
+ QString profile = QString::fromLatin1("PROFILE_");
+ profile += emailConf.readEntry(QString::fromLatin1("Profile"), QString::fromLatin1("Default"));
+
+ emailConf.setGroup(profile);
+ QString fromaddr = emailConf.readEntry(QString::fromLatin1("EmailAddress"));
+ if (fromaddr.isEmpty()) {
+ struct passwd *p;
+ p = getpwuid(getuid());
+ d->fetchedEmail = QString::fromLatin1(p->pw_name);
+ } else {
+ QString name = emailConf.readEntry(QString::fromLatin1("FullName"));
+ if (!name.isEmpty())
+ d->fetchedEmail = /*name + QString::fromLatin1(" <") +*/ fromaddr /*+ QString::fromLatin1(">")*/;
+ }
+// m_from->setText( fromaddr );
+}
+
+/*******************************************/
+/********** class LikeBackDialog: **********/
+/*******************************************/
+
+LikeBackDialog::LikeBackDialog(LikeBack::Button reason, const QString &initialComment, const QString &windowPath, const QString &context, LikeBack *likeBack)
+ : KDialogBase(KDialogBase::Swallow, i18n("Send a Comment to Developers"), KDialogBase::Ok | KDialogBase::Cancel | KDialogBase::Default,
+ KDialogBase::Ok, kapp->activeWindow(), /*name=*/"_likeback_feedback_window_", /*modal=*/true, /*separator=*/true)
+ , m_likeBack(likeBack)
+ , m_windowPath(windowPath)
+ , m_context(context)
+{
+ // If no specific "reason" is provided, choose the first one:
+ if (reason == LikeBack::AllButtons) {
+ LikeBack::Button buttons = m_likeBack->buttons();
+ int firstButton = 0;
+ if (firstButton == 0 && (buttons & LikeBack::Like)) firstButton = LikeBack::Like;
+ if (firstButton == 0 && (buttons & LikeBack::Dislike)) firstButton = LikeBack::Dislike;
+ if (firstButton == 0 && (buttons & LikeBack::Bug)) firstButton = LikeBack::Bug;
+ if (firstButton == 0 && (buttons & LikeBack::Feature)) firstButton = LikeBack::Feature;
+ reason = (LikeBack::Button) firstButton;
+ }
+
+ // If no window path is provided, get the current active window path:
+ if (m_windowPath.isEmpty())
+ m_windowPath = LikeBack::activeWindowPath();
+
+ QWidget *page = new QWidget(this);
+ QVBoxLayout *pageLayout = new QVBoxLayout(page, /*margin=*/0, spacingHint());
+
+ // The introduction message:
+ QLabel *introduction = new QLabel(introductionText(), page);
+ pageLayout->addWidget(introduction);
+
+ // The comment group:
+ m_group = new QButtonGroup(0);//i18n("Send Application Developers a Comment About:"), page);
+ QVGroupBox *box = new QVGroupBox(i18n("Send Application Developers a Comment About:"), page);
+ pageLayout->addWidget(box);
+
+ // The radio buttons:
+ QWidget *buttons = new QWidget(box);
+ QGridLayout *buttonsGrid = new QGridLayout(buttons, /*nbRows=*/4, /*nbColumns=*/2, /*margin=*/0, spacingHint());
+ if (m_likeBack->buttons() & LikeBack::Like) {
+ QPixmap likePixmap = kapp->iconLoader()->loadIcon("likeback_like_tork", KIcon::NoGroup, 16, KIcon::DefaultState, 0L, true);
+ QLabel *likeIcon = new QLabel(buttons);
+ likeIcon->setPixmap(likePixmap);
+ likeIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ QRadioButton *likeButton = new QRadioButton(i18n("Something you &like"), buttons);
+ buttonsGrid->addWidget(likeIcon, /*row=*/0, /*column=*/0);
+ buttonsGrid->addWidget(likeButton, /*row=*/0, /*column=*/1);
+ m_group->insert(likeButton, LikeBack::Like);
+ }
+ if (m_likeBack->buttons() & LikeBack::Dislike) {
+ QPixmap dislikePixmap = kapp->iconLoader()->loadIcon("likeback_dislike_tork", KIcon::NoGroup, 16, KIcon::DefaultState, 0L, true);
+ QLabel *dislikeIcon = new QLabel(buttons);
+ dislikeIcon->setPixmap(dislikePixmap);
+ dislikeIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ QRadioButton *dislikeButton = new QRadioButton(i18n("Something you &dislike"), buttons);
+ buttonsGrid->addWidget(dislikeIcon, /*row=*/1, /*column=*/0);
+ buttonsGrid->addWidget(dislikeButton, /*row=*/1, /*column=*/1);
+ m_group->insert(dislikeButton, LikeBack::Dislike);
+ }
+ if (m_likeBack->buttons() & LikeBack::Bug) {
+ QPixmap bugPixmap = kapp->iconLoader()->loadIcon("likeback_bug_tork", KIcon::NoGroup, 16, KIcon::DefaultState, 0L, true);
+ QLabel *bugIcon = new QLabel(buttons);
+ bugIcon->setPixmap(bugPixmap);
+ bugIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ QRadioButton *bugButton = new QRadioButton(i18n("An improper &behavior of this application"), buttons);
+ buttonsGrid->addWidget(bugIcon, /*row=*/2, /*column=*/0);
+ buttonsGrid->addWidget(bugButton, /*row=*/2, /*column=*/1);
+ m_group->insert(bugButton, LikeBack::Bug);
+ }
+ if (m_likeBack->buttons() & LikeBack::Feature) {
+ QPixmap featurePixmap = kapp->iconLoader()->loadIcon("likeback_feature_tork", KIcon::NoGroup, 16, KIcon::DefaultState, 0L, true);
+ QLabel *featureIcon = new QLabel(buttons);
+ featureIcon->setPixmap(featurePixmap);
+ featureIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ QRadioButton *featureButton = new QRadioButton(i18n("A new &feature you desire"), buttons);
+ buttonsGrid->addWidget(featureIcon, /*row=*/3, /*column=*/0);
+ buttonsGrid->addWidget(featureButton, /*row=*/3, /*column=*/1);
+ m_group->insert(featureButton, LikeBack::Feature);
+ }
+ m_group->setButton(reason);
+
+ // The comment text box:
+ m_comment = new QTextEdit(box);
+ m_comment->setTabChangesFocus(true);
+ m_comment->setTextFormat(QTextEdit::PlainText);
+ m_comment->setText(initialComment);
+
+ m_showButtons = new QCheckBox(i18n("Show comment buttons below &window titlebars"), page);
+ m_showButtons->setChecked(m_likeBack->userWantsToShowBar());
+ pageLayout->addWidget(m_showButtons);
+ connect( m_showButtons, SIGNAL(stateChanged(int)), this, SLOT(changeButtonBarVisible()) );
+
+ setButtonOK(KGuiItem(i18n("&Send Comment"), "mail_send"));
+ enableButtonOK(false);
+ connect( m_comment, SIGNAL(textChanged()), this, SLOT(commentChanged()) );
+
+ setButtonGuiItem(Default, KGuiItem(i18n("&Email Address..."), "mail_generic"));
+
+ resize(QSize(kapp->desktop()->width() * 1 / 2, kapp->desktop()->height() * 3 / 5).expandedTo(sizeHint()));
+
+ QAction *sendShortcut = new QAction(this);
+ sendShortcut->setAccel(QString("Ctrl+Return"));
+ connect( sendShortcut, SIGNAL(activated()), actionButton(Ok), SLOT(animateClick()) );
+
+ setMainWidget(page);
+}
+
+LikeBackDialog::~LikeBackDialog()
+{
+}
+
+QString LikeBackDialog::introductionText()
+{
+ QString text = "<p>" + i18n("Please provide a brief description of your opinion of %1.").arg(m_likeBack->aboutData()->programName()) + " ";
+
+ QString languagesMessage = "";
+ if (!m_likeBack->acceptedLocales().isEmpty() && !m_likeBack->acceptedLanguagesMessage().isEmpty()) {
+ languagesMessage = m_likeBack->acceptedLanguagesMessage();
+ QStringList locales = m_likeBack->acceptedLocales();
+ for (QStringList::Iterator it = locales.begin(); it != locales.end(); ++it) {
+ QString locale = *it;
+ if (KGlobal::locale()->language().startsWith(locale))
+ languagesMessage = "";
+ }
+ } else {
+ if (!KGlobal::locale()->language().startsWith("en"))
+ languagesMessage = i18n("Please write in English.");
+ }
+
+ if (!languagesMessage.isEmpty())
+ // TODO: Replace the URL with a localized one:
+ text += languagesMessage + " " +
+ i18n("You may be able to use an <a href=\"%1\">online translation tool</a>.")
+ .arg("http://www.google.com/language_tools?hl=" + KGlobal::locale()->language())
+ + " ";
+
+ // If both "I Like" and "I Dislike" buttons are shown and one is clicked:
+ if ((m_likeBack->buttons() & LikeBack::Like) && (m_likeBack->buttons() & LikeBack::Dislike))
+ text += i18n("To make the comments you send more useful in improving this application, try to send the same amount of positive and negative comments.") + " ";
+
+ if (!(m_likeBack->buttons() & LikeBack::Feature))
+ text += i18n("Do <b>not</b> ask for new features: your requests will be ignored.");
+
+ return text;
+}
+
+void LikeBackDialog::polish()
+{
+ KDialogBase::polish();
+ m_comment->setFocus();
+}
+
+void LikeBackDialog::slotDefault()
+{
+ m_likeBack->askEmailAddress();
+}
+
+void LikeBackDialog::slotOk()
+{
+ send();
+}
+
+void LikeBackDialog::changeButtonBarVisible()
+{
+ m_likeBack->setUserWantsToShowBar(m_showButtons->isChecked());
+}
+
+void LikeBackDialog::commentChanged()
+{
+ QPushButton *sendButton = actionButton(Ok);
+ sendButton->setEnabled(!m_comment->text().isEmpty());
+}
+
+void LikeBackDialog::send()
+{
+ QString emailAddress = m_likeBack->emailAddress();
+
+ int reason = m_group->selectedId();
+ QString type = (reason == LikeBack::Like ? "Like" : (reason == LikeBack::Dislike ? "Dislike" : (reason == LikeBack::Bug ? "Bug" : "Feature")));
+ QString data =
+ "protocol=" + KURL::encode_string("1.0") + '&' +
+ "type=" + KURL::encode_string(type) + '&' +
+ "version=" + KURL::encode_string(m_likeBack->aboutData()->version()) + '&' +
+ "locale=" + KURL::encode_string(KGlobal::locale()->language()) + '&' +
+ "window=" + KURL::encode_string(m_windowPath) + '&' +
+ "context=" + KURL::encode_string(m_context) + '&' +
+ "comment=" + KURL::encode_string(m_comment->text()) + '&' +
+ "email=" + KURL::encode_string(emailAddress);
+ QHttp *http = new QHttp(m_likeBack->hostName(), m_likeBack->hostPort());
+
+ std::cout << "http://" << m_likeBack->hostName() << ":" << m_likeBack->hostPort() << m_likeBack->remotePath() << std::endl;
+ std::cout << data << std::endl;
+ connect( http, SIGNAL(requestFinished(int, bool)), this, SLOT(requestFinished(int, bool)) );
+
+ QHttpRequestHeader header("POST", m_likeBack->remotePath());
+ header.setValue("Host", m_likeBack->hostName());
+ header.setValue("Content-Type", "application/x-www-form-urlencoded");
+ http->setHost(m_likeBack->hostName());
+ http->request(header, data.utf8());
+
+ m_comment->setEnabled(false);
+}
+
+void LikeBackDialog::requestFinished(int /*id*/, bool error)
+{
+ // TODO: Save to file if error (connection not present at the moment)
+ m_comment->setEnabled(true);
+ m_likeBack->disableBar();
+ if (error) {
+ KMessageBox::error(this, i18n("<p>Error while trying to send the report.</p><p>Please retry later.</p>"), i18n("Transfer Error"));
+ } else {
+ KMessageBox::information(
+ this,
+ i18n("<p>Your comment has been sent successfully. It will help improve the application.</p><p>Thanks for your time.</p>"),
+ i18n("Comment Sent")
+ );
+ close();
+ }
+ m_likeBack->enableBar();
+
+ KDialogBase::slotOk();
+}
+
+#include "likeback_private.moc"
+#include "likeback.moc"
diff --git a/src/likeback.h b/src/likeback.h
new file mode 100644
index 0000000..4b825a5
--- /dev/null
+++ b/src/likeback.h
@@ -0,0 +1,364 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Sebastien Laout *
+ * slaout@linux62.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library General Public License as *
+ * published by the Free Software Foundation; either version 2 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef LIKEBACK_H
+#define LIKEBACK_H
+
+#include <qobject.h>
+
+class KConfig;
+class KAboutData;
+class KAction;
+class KActionCollection;
+
+class LikeBackPrivate;
+class LikeBackBar;
+class LikeBackDialog;
+
+/**
+ * @short System to Get Quick Feedback from Beta-Testers
+ *
+ * This system allows users to communicate theire liking of the application to its developers.
+ * Thus, developers know what theire users prefer of theire applications, what should be enhanced, etc.
+ *
+ * Basically, how does it work?
+ * Whenever the user notice something good he appreciate or something he do not like, do not understand, do not find polished...
+ * he can send a few short words to the developers to tell them what he like or do not like. It is only two or three clicks away.
+ * It is fast and efficient.
+ *
+ * This greatly lowers the communication barrier between the application developers and the application users.
+ * It makes the developers understand and satisfy better the needs of the users.
+ *
+ * The LikeBack system has 5 components:
+ * @li In the application: The comment dialog, where the user write a comment, select a type of comment, etc.
+ * @li In the application: The KAction to plug in the Help menu. This action displays the comment dialog.
+ * @li In the application: The button-bar, that floats bellow titlebar of every windows of the application, and let the user to quickly show the comment dialog.
+ * The button-bar can be hidden.
+ * @li On the server: A PHP script that collects every comments that users send. The LikeBack object should be configured to contact that server.
+ * @li On the server: The developer interface. It lists every comments that were sent, let you sort them, add remarks to them, and mark them as fixed or another status.
+ *
+ * Here is an example of code to call to quickly setup LikeBack on the client:
+ * @code
+ * // Instanciate the LikeBack system, and show the first-use information dialog if the button-bar is shown:
+ * LikeBack *likeBack = new LikeBack(LikeBack::AllButtons, LikeBack::isDevelopmentVersion(kapp->aboutData->version())); // Show button-bar only in beta-versions
+ * likeBack->setServer("myapp.kde.org", "/likeback/send.php");
+ * likeBack->setAcceptedLanguages(QStringList::split(";", "en;fr"), i18n("Please write in English or French."));
+ *
+ * // Comment the following line once you are sure all your windows have a name:
+ * likeBack->setWindowNamesListing(LikeBack::WarnUnnamedWindows);
+ *
+ * // This line should be called early in your KMainWindow constructor because it references actionCollection().
+ * // It should be called before createGUI() for the action to be plugged in the Help menu:
+ * likeBack->sendACommentAction(actionCollection());
+ * @endcode
+ *
+ * @see Visit http://basket.kde.org/likeback.php for more information, screenshots, a tutorial, hints, return of experiences, and to download the server-side developer interface...
+ * @author Sebastien Laout <slaout@linux62.org>
+ */
+class LikeBack : public QObject
+{
+ Q_OBJECT
+ public:
+ /**
+ * Ids of every LikeBack buttons the button-bar can have.
+ * The four first values are each individual buttons you can enable or not.
+ * The next ones are combinations: all buttons at once, and the default set of buttons (Like, Dislike).
+ * Those values are used in the constructor, to set the allowed type of comments, and when triggering the comment dialog, to set the default checked type.
+ * @See The LikeBack constructor and execCommentDialog().
+ */
+ enum Button {
+ Like = 0x01, /// The user select that option to report a positive experience he got with the application.
+ Dislike = 0x02, /// The user select that option to report a frustrating experience he got with the application.
+ Bug = 0x04, /// The user select that option to report a bug in the application.
+ Feature = 0x10, /// The user select that option to ask for a new feature he desire.
+ /// If not enabled, the user is explicitely informed she cannot ask for new features.
+ AllButtons = Like | Dislike | Bug | Feature, /// Usable in the constructor to enable every posible buttons.
+ DefaultButtons = Like | Dislike /// Usable in the constructor to enable only the recommended default set of buttons.
+ };
+
+ /**
+ * Flags letting LikeBack print out name and path of each window you show during execution, for debugging purpose.
+ * @See The method setWindowNamesListing() explains how to use those values.
+ */
+ enum WindowListing {
+ NoListing = 0, /// Do not print out any window name. For release time.
+ WarnUnnamedWindows = 1, /// Each time the user option a window, print out a message if the window is unnamed. For development needs, to check windows.
+ AllWindows = 2 /// Print out the window hierarchy of each opened windows during execution. For development needs, to check every windows have an understandable name.
+ };
+
+ /**
+ * You only need to call the constructor once, typically in main.cpp.
+ * Even if you do not show the button-bar by default, you should instanciate LikeBack,
+ * to include its action in the Help menu of your application, to let the users send comments or activate the bar.
+ * @param buttons The types of comments you want to get. Determine which radio-buttons are shown in the comment dialog,
+ * and which ones are displayed in the button-bar. Default buttons do not show the Bug and Feature buttons because you are
+ * likely to already have a way to get bug and feature reports (most of the time, it is a bugs.kde.org account).
+ * If you do not have that, then use the value LikeBack::AllButtons to show every possible buttons.
+ * @param showBarByDefault Determines if the floating button-bar should also be shown, in addition to the action in the Help menu.
+ * Advise: to avoid getting too much noise, enable it only if it is a small application or a development release.
+ * Notes: This is only a default value, the user will be able to enable or disabled the bar afterward.
+ * The button-bar display is stored by version. On a new version, your default value will take effect again.
+ * This allow you to disable the button-bar once the version is stable enought to be released as final.
+ * @param config Set the configuration file where to store the user email address and if the button-bar should be shown.
+ * By default (null), the KApplication configuration object is used.
+ * @param aboutData Set the KAboutData instance used to get the application name and version. By default (null), the KApplication about data object is used.
+ * The application name is only used in the first-use information message.
+ * The version is used to store the button-bar visibility per version (can be shown in a development version but not in a final one...)
+ * and to send with the comment, so you can filter per version and know if a comment refers the latest version of the application or not.
+ */
+ LikeBack(Button buttons = DefaultButtons, bool showBarByDefault = false, KConfig *config = 0, const KAboutData *aboutData = 0);
+
+ /**
+ * Destructor.
+ * Also hide the button-bar, if it was shown.
+ * Be careful, the KAction is deleted. Do not use it afterward, and take care to unplug it before destroying this LikeBack instance.
+ */
+ ~LikeBack();
+
+ /**
+ * This method is interesting while setting up the system for the first time.
+ * LikeBack send the current window name (and hierarchy) with the comment. This allows you to put the comments in theire context.
+ * So, of course, you are encouraged to give a name to your windows. It is done in the constructor of the widgets.
+ * This method allows to output the name of the current window to the standard output.
+ * So you can use the application, open all the windows, and when you see a warning, you know which window you should assign a name.
+ * @see The WindowListing flags for an enumeration and explaining of every possibilities.
+ * @Note If you do not name your windows, the name of the classes will be sent. So it is not that grave.
+ */
+ void setWindowNamesListing(WindowListing windowListing);
+
+ /**
+ * @Returns The window listing flag.
+ * @see setWindowNamesListing()
+ */
+ WindowListing windowNamesListing();
+
+ /**
+ * By default, only English comments are accepted. The user is informed she must write in this language by a sentence placed in the comment dialog.
+ * If you have people talking other languages in your development team, it can be interesting to call this method to define the accepted locales (languages),
+ * and provide a message to inform users. The developer interface on the server let developers view comments in theire locale.
+ * Note that no verification is done to check if the user used the right language, it would be impossible.
+ * The list of locales is there to make it possible to NOT show the message for users of the accepted languages.
+ * For instance, if you accept only English and French, and that the application run in a French environment,
+ * it is likely the user is French and will write comments using French. Telling him he should write in French is unnecessary and redundant.
+ * Passing an empty list and an empty string to the method will make LikeBack display the default message telling the user only English is accepted.
+ * Example of call you can quickly copy, paste and adapt:
+ * @code
+ * likeBack->setAcceptedLanguages(QStringList::split(";", "en;fr"), i18n("Please write in English or French."));
+ * @endcode
+ * @Note During tests, if you do not see the sentence, it is because you are running the application with an "accepted language": do not be surprised ;-)
+ * @param locales The list of locales where the message does not need to be shown. See TODO TODO for a list of available locales for you to choose.
+ * @param message The message to displays to the user to tell him what languages are accepted to write his comments.
+ */
+ void setAcceptedLanguages(const QStringList &locales, const QString &message);
+
+ /**
+ * @Returns The list of accepted locales for the user to write comments.
+ * @see setAcceptedLanguages()
+ */
+ QStringList acceptedLocales();
+
+ /**
+ * @Returns The message displayed to users who are not running the application in an accepted locale.
+ * @see setAcceptedLanguages()
+ */
+ QString acceptedLanguagesMessage();
+
+ /**
+ * Set the path where LikeBack should send every comments.
+ * It is composed of the server host name, the path to the PHP script used to send comments, and optionnaly a port number if it is not 80.
+ * This call is mandatory for LikeBack to work.
+ * @param hostName The server host name to contact when sending comments. For instance "myapp.kde.org".
+ * @param remotePath The path to the send script on the server. For instance, "/likeback/send.php".
+ * @param hostPort Optionnal port used to contact the server using the HTTP protocol. By default, it is port 80.
+ */
+ void setServer(const QString &hostName, const QString &remotePath, Q_UINT16 hostPort = 80);
+
+ /**
+ * @Returns The server host name to contact when sending comments.
+ * @see setServer()
+ */
+ QString hostName();
+
+ /**
+ * @Returns The path to the send script on the server.
+ * @see setServer()
+ */
+ QString remotePath();
+
+ /**
+ * @Returns The port used to contact the server using the HTTP protocol.
+ * @see setServer()
+ */
+ Q_UINT16 hostPort();
+
+ /**
+ * Get the KAction letting user to show the comment dialog.
+ * You should plug it in your Help menu, just bellow the "Report a Bug" action, or replace it.
+ * Adding the action below "Report a Bug" or replacing "Report a Bug" depends on your application and if you have a Bugzilla account.
+ * If you do not have a Bugzilla account, LikeBack is a good way for your small application to get bug reports: remove "Report a Bug".
+ * For more information about how to configure LikeBack depending on your application size and settings, see the constructor documentation.
+ * @Note The action is named "likeback_send_a_comment". So you should add the following XML in the *ui.rc file of your application:
+ * @code
+ * <Action name="likeback_send_a_comment" />
+ * @endcode
+ */
+ KAction* sendACommentAction(KActionCollection *parent = 0);
+
+ /**
+ * @Returns The path of the currently active window. Each windows are separated with "~~".
+ * Normally, you should not need to call this method since it is used to send the window path.
+ * But if you call execCommentDialog(), you could need to use it.
+ */
+ static QString activeWindowPath();
+
+ /**
+ * @Returns The combination of buttons that are shown in the comment dialog and the button-bar.
+ */
+ Button buttons();
+
+ /**
+ * @Returns true if the button-bar is currently enabled. Ie, if it has been re-enabled as many times as it has been disabled.
+ * @see The method disableBar() for more information on how enabling/disabling works.
+ */
+ bool enabledBar();
+
+ public slots:
+
+ /**
+ * Temporarily disable the button-bar: it is hiden from the screen if it was shown.
+ * Does not affect anything if the user has not choosen to show the button-bar.
+ * @Note Calls to enableBar() and disableBar() are ref-counted.
+ * This means that the number of times disableBar() is called is memorized,
+ * and enableBar() will only have effect after it has been called as many times as disableBar() was called before.
+ * So, make sure to always call enableBar() the same number of times ou called disableBar().
+ * And please make sure to ALWAYS call disableBar() BEFORE enableBar().
+ * In the counter-case, another code could call disableBar() and EXCPECT the bar to be disabled. But it will not, because its call only canceled yours.
+ * @Note Sometimes, you will absolutely need to call enableBar() before disableBar().
+ * For instance, MyWindow::show() calls enableBar() and MyWindow::hide() calls disableBar().
+ * This is the trick used to show the LikeBack button-bar of a Kontact plugin only when the main widget of that plugin is active.
+ * In this case, call disableBar() at the begin of your program, so the disable count will never be negative.
+ * @Note If the bar is enabled, it does not mean the bar is shown. For that, the developer (using showBarByDefault in the construcor)
+ * or the user (by checking the checkbox in the comment dialog) have to explicitely show the bar.
+ */
+ void disableBar();
+
+ /**
+ * Re-enable the button-bar one time.
+ * @see The method disableBar() for more information on how enabling/disabling works.
+ */
+ void enableBar();
+
+ /**
+ * Show the first-use information dialog telling the user the meaning of the LikeBack system and giving examples of every comment types.
+ */
+ void showInformationMessage();
+
+ /**
+ * Popup the comment dialog.
+ * With no parameter, it popups in the default configuration: the first type is checked, empty message, current window path, and empty context.
+ * You can use the following parameters to customize how it should appears:
+ * @param type Which radiobutton should be checked when poping up. AllButton, the default value, means the first available type will be checked.
+ * @param initialComment The text to put in the comment text area. Allows you to popup the dialog in some special circumstances,
+ * like to let the user report an internal error by populating the comment area with technical details useful for you to debug.
+ * @param windowPath The window path to send with the comment. If empty (the default), the current window path is took.
+ * Separate window names with "~~". For instance "MainWindow~~NewFile~~FileOpen".
+ * If you popup the dialog after an error occurred, you can put the error name in that field (if the window path has no sense in that context).
+ * When the dialog is popuped up from the sendACommentAction() KAction, this value is "HelpMenu", because there is no way to know if the user
+ * is commenting a thing he found/thinked about in a sub-dialog.
+ * @param context Not used for the moment. Will allow more fine-grained application status report.
+ */
+ void execCommentDialog(Button type = AllButtons, const QString &initialComment = "", const QString &windowPath = "", const QString &context = "");
+
+ /**
+ * Popups the dialog for the user to set his email address.
+ * The popup will always be shown, even if the user already provided an email address.
+ */
+ void askEmailAddress();
+
+ private:
+ LikeBackPrivate *d;
+
+ /**
+ * Get the user email address from KControl.
+ */
+ void fetchUserEmail();
+
+ private slots:
+ /**
+ * Slot triggered by the "Help -> Send a Comment to Developers" KAction.
+ * It popups the comment dialog, and set the window path to "HelpMenuAction",
+ * because current window path has no meaning in that case.
+ */
+ void execCommentDialogFromHelp();
+
+ public:
+
+ /**
+ * @Returns true if the user has enabled the LikeBack bar for this version.
+ */
+ bool userWantsToShowBar();
+
+ /**
+ * Explicitely set if the floating button-bar should be shown or not.
+ * Tehorically, this choice should only be left to the user,
+ * and to the developers for the default value, already provided in the constructor.
+ */
+ void setUserWantsToShowBar(bool showBar);
+
+ /**
+ * @Returns A pointer to the KAboutData used to determin the application name and version.
+ * @See The LikeBack constructor for more information.
+ */
+ const KAboutData *aboutData();
+
+ /**
+ * @Returns A pointer to the KConfig used to store user configuration (email address, if the button-bar should be shown).
+ * @See The LikeBack constructor for more information.
+ */
+ KConfig *config();
+
+ /**
+ * During the first comment sending, the user is invited to enter his email address for the developers to be able to contact him back.
+ * He is only asked once, or he can set or change it by using the bottom-left button in the comment dialog.
+ * @Returns true if the user has already configured his email address.
+ */
+ bool emailAddressAlreadyProvided();
+
+ /**
+ * @Returns The email user address, or ask it to the user if he have not provided or ignored it.
+ * @Returns An empty string if the user cancelled the request dialog.
+ */
+ QString emailAddress();
+
+ /**
+ * Define or re-define the user email address.
+ * LikeBack will not ask it again to the user, unless you set @p userProvided to false.
+ * Then, this call can be considered as setting the default email address, that the user should confirm later.
+ */
+ void setEmailAddress(const QString &address, bool userProvided = true);
+
+ /**
+ * @Returns true if @p version is an Alpha, Beta, RC, SVN or CVS version.
+ * You can use this static method in the constructor to enable the button-bar by default only during beta-releases.
+ */
+ static bool isDevelopmentVersion(const QString &version);
+};
+
+#endif // LIKEBACK_H
diff --git a/src/likeback_private.h b/src/likeback_private.h
new file mode 100644
index 0000000..37ed60f
--- /dev/null
+++ b/src/likeback_private.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Sebastien Laout *
+ * slaout@linux62.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU Library General Public License as *
+ * published by the Free Software Foundation; either version 2 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Library General Public *
+ * License along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ ***************************************************************************/
+
+#ifndef LIKEBACK_PRIVATE_H
+#define LIKEBACK_PRIVATE_H
+
+#include <kdialogbase.h>
+#include <qtimer.h>
+
+#include "likeback.h"
+
+class QToolButton;
+class QTextEdit;
+class QCheckBox;
+class QButtonGroup;
+class Kaction;
+
+class LikeBackPrivate
+{
+ public:
+ LikeBackPrivate();
+ ~LikeBackPrivate();
+ LikeBackBar *bar;
+ KConfig *config;
+ const KAboutData *aboutData;
+ LikeBack::Button buttons;
+ QString hostName;
+ QString remotePath;
+ Q_UINT16 hostPort;
+ QStringList acceptedLocales;
+ QString acceptedLanguagesMessage;
+ LikeBack::WindowListing windowListing;
+ bool showBarByDefault;
+ bool showBar;
+ int disabledCount;
+ QString fetchedEmail;
+ KAction *action;
+};
+
+class LikeBackBar : public QWidget
+{
+ Q_OBJECT
+ public:
+ LikeBackBar(LikeBack *likeBack);
+ ~LikeBackBar();
+ public slots:
+ void startTimer();
+ void stopTimer();
+ private slots:
+ void autoMove();
+ void clickedLike();
+ void clickedDislike();
+ void clickedBug();
+ void clickedFeature();
+ private:
+ LikeBack *m_likeBack;
+ QTimer m_timer;
+ QToolButton *m_likeButton;
+ QToolButton *m_dislikeButton;
+ QToolButton *m_bugButton;
+ QToolButton *m_featureButton;
+};
+
+class LikeBackDialog : public KDialogBase
+{
+ Q_OBJECT
+ public:
+ LikeBackDialog(LikeBack::Button reason, const QString &initialComment, const QString &windowPath, const QString &context, LikeBack *likeBack);
+ ~LikeBackDialog();
+ private:
+ LikeBack *m_likeBack;
+ QString m_windowPath;
+ QString m_context;
+ QButtonGroup *m_group;
+ QTextEdit *m_comment;
+ QCheckBox *m_showButtons;
+ QString introductionText();
+ private slots:
+ void polish();
+ void slotDefault();
+ void slotOk();
+ void changeButtonBarVisible();
+ void commentChanged();
+ void send();
+ void requestFinished(int id, bool error);
+};
+
+#endif // LIKEBACK_PRIVATE_H
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..8418c61
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,120 @@
+/***************************************************************************
+ ** $Id: main.cpp,v 1.61 2010/07/24 12:24:04 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#include "tork.h"
+#include "crashhandler.h"
+#include "torkconfig.h"
+#include "functions.h"
+#include "newfirstrunwizard.h"
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <kconfigdialogmanager.h>
+
+static const char description[] =
+ I18N_NOOP("<b>TorK - An Anonymity Manager for the KDE Desktop.</b>\n"
+ "This product is produced independently from the Tor anonymity\n"
+ "software and carries no guarantee from The Tor Project about\n"
+ "quality, suitability or anything else.");
+
+static const char version[] = "";
+static const char title[] = "TorK 0.33";
+
+static KCmdLineOptions options[] =
+{
+ { "+[URL]", I18N_NOOP( "Document to open." ), 0 },
+ { "toggleKDE", I18N_NOOP("Toggle Anonymous KDE"), 0 },
+ { "anonymousFirefox", I18N_NOOP("Launch Anonymous Firefox"), 0 },
+ { "anonymousOpera", I18N_NOOP("Launch Anonymous Opera"), 0 },
+ { "anonymousKonsole", I18N_NOOP("Launch Anonymous Konsole"), 0 },
+ { "anonymousKopete", I18N_NOOP("Launch Anonymous Kopete"), 0 },
+ { "anonymousPidgin", I18N_NOOP("Launch Anonymous Pidgin"), 0 },
+ { "anonymousGaim", I18N_NOOP("Launch Anonymous Gaim"), 0 },
+ { "anonymousKonversation", I18N_NOOP("Launch Anonymous Konversation"), 0 },
+ { "anonymousEmail", I18N_NOOP("Launch Mixminion Interface"), 0 },
+
+ { 0, 0, 0 }
+};
+
+int main(int argc, char **argv)
+{
+ KAboutData about("tork", I18N_NOOP(title), version, description,
+ KAboutData::License_GPL, "(C) 2006 - 2008 Robert Hogan", 0, 0, "tork-users@lists.sf.net");
+ about.addAuthor( "Robert Hogan", I18N_NOOP("Author and Maintainer"), "robert@roberthogan.net", "http://tork.anonymityanywhere.com" );
+ about.addAuthor( "Corinna Habets", I18N_NOOP("Icons"), 0);
+ about.addAuthor( "Contains code by: Matt Edman, Justin Hipple, Max Howell,", 0, "" );
+ about.addAuthor( " Trolltech AS, Roger Dingledine, Nick Mathewson, ", 0, "" );
+ about.addAuthor( " Sebastien Trueg, Joris Guisson, Markus Gustavsson, ", 0, "" );
+ about.addAuthor( " Diego Petena, Ben Burton, David Sansome ", 0, "" );
+ about.addAuthor( " Stephan Binner, Hugo Parente Lima ", 0, "" );
+ about.addAuthor( I18N_NOOP("This product includes GeoIP data created by MaxMind"),
+ 0, 0, "http://maxmind.com/" );
+ about.addAuthor( I18N_NOOP("The Tor(TM) trademark and Tor Onion Logo are trademarks of The Tor Project."),
+ 0, 0, "http://www.torproject.org/" );
+
+
+ about.addCredit( "Matthias Slovig", I18N_NOOP("Flag images by which can be used under this Creative Commons License: "
+ "http://creativecommons.org/licenses/by/2.0/de/"), "matthias.slovig@baseball-in-bayern.de", "http://flags.blogpotato.de/");
+ about.addCredit( "Emre Aladag, Inanc Yildirgan, Mustafa Gunay, Ertugrul Erata", I18N_NOOP("Turkish Translation"), 0);
+ about.addCredit( "Liu Songhe", I18N_NOOP("Chinese Translation"), "shuizhuyuanluo@126.com");
+ about.addCredit( "Marek Stopka", I18N_NOOP("Czech Translation"), "marekstopka@gmail.com");
+ about.addCredit( "Hans-J. Ullrich", I18N_NOOP("German Translation"), "hans.ullrich@loop.de");
+ about.addCredit( "Max Urgel", I18N_NOOP("German Translation"), "bitwisser@googlemail.com");
+ about.addCredit( "Daniel Berthereau", I18N_NOOP("French Translation"),
+ "Daniel.Berthereau@free.fr");
+ KCmdLineArgs::init(argc, argv, &about);
+ KCmdLineArgs::addCmdLineOptions(options);
+ KApplication app;
+
+
+ //Check for the existence of anonymizable/helper programs first.
+ QStringList programList;
+ programList << "firefox" << "kopete" << "gaim" <<
+ "pidgin" << "opera" << "konversation"
+ << "konsole" << "yakuake" << "xterm" << "konqueror"
+ << "rxvt" << "gnome-terminal" << "gpg";
+ TorkConfig::setAvailablePrograms(findPrograms(programList));
+
+ //Run the wizard if necessary, and exit TorK completely if the wizard is
+ //cancelled.
+ if (TorkConfig::user().isEmpty()){
+ FirstRunWizard wizard;
+ wizard.setCaption( i18n( "First-Run Wizard" ));
+ if (wizard.exec() == QDialog::Rejected) {
+ TorkConfig::setUser("");
+ return 0;
+ }
+ }
+
+ // see if we are starting with session management
+ tork *widget = new tork;
+ if (app.isRestored())
+ widget->hide();
+ else
+ widget->show();
+
+ //KCrash::setCrashHandler( torK::Crash::crashHandler );
+
+ return app.exec();
+}
+
diff --git a/src/maxmin.ui b/src/maxmin.ui
new file mode 100644
index 0000000..f925689
--- /dev/null
+++ b/src/maxmin.ui
@@ -0,0 +1,460 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>MaxMin</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>MaxMin</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>529</width>
+ <height>430</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>MaxMinOptions</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>Bandwidth Options</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="2" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>71</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="3">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Maximum Incoming Bandwidth: </string>
+ </property>
+ </widget>
+ <spacer row="0" column="1">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>101</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>Largest Chunk of Bandwidth to Allocate In One Go:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel4_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Max Bandwidth to Advertise:</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="4">
+ <property name="name">
+ <cstring>kcfg_BandwidthBurst</cstring>
+ </property>
+ <property name="suffix">
+ <string> KB per second</string>
+ </property>
+ <property name="maxValue">
+ <number>2097151</number>
+ </property>
+ <property name="minValue">
+ <number>20</number>
+ </property>
+ <property name="value">
+ <number>20</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="4">
+ <property name="name">
+ <cstring>kcfg_MaxAdvertisedBandwidth</cstring>
+ </property>
+ <property name="suffix">
+ <string> KB per second</string>
+ </property>
+ <property name="maxValue">
+ <number>999999</number>
+ </property>
+ <property name="minValue">
+ <number>10</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="4">
+ <property name="name">
+ <cstring>kcfg_BandwidthRate</cstring>
+ </property>
+ <property name="suffix">
+ <string> KB per second</string>
+ </property>
+ <property name="maxValue">
+ <number>99999999</number>
+ </property>
+ <property name="minValue">
+ <number>20</number>
+ </property>
+ <property name="value">
+ <number>20</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>kcfg_DefaultMaxMinOptions</cstring>
+ </property>
+ <property name="text">
+ <string>Let Tor &amp;figure out the best bandwidth options to use.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+F</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="3" column="0">
+ <property name="name">
+ <cstring>TimedBandwidth</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>Scheduled Bandwidth</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView" row="0" column="0" rowspan="1" colspan="7">
+ <column>
+ <property name="text">
+ <string>From</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Every</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Use Max Incoming BW</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Max Chunk</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Max Advertise</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>timedBandwidthList</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="4">
+ <property name="name">
+ <cstring>spacer7_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="1" column="3">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>every</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="5">
+ <item>
+ <property name="text">
+ <string>Day</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Monday</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Tuesday</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Wednesday</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Thursday</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Friday</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Saturday</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Sunday</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>theDay</cstring>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="6">
+ <property name="name">
+ <cstring>pushButton1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Use B/W Options Above</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>From</string>
+ </property>
+ </widget>
+ <widget class="QTimeEdit" row="1" column="1">
+ <property name="name">
+ <cstring>theTime</cstring>
+ </property>
+ <property name="maxValue">
+ <time>
+ <hour>23</hour>
+ <minute>50</minute>
+ <second>0</second>
+ </time>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0">
+ <property name="name">
+ <cstring>kcfg_UseScheduledBandwidth</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Use Scheduled Bandwidth</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>kcfg_DefaultMaxMinOptions</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>MaxMin</receiver>
+ <slot>kcfg_DefaultMaxMinOptions_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_BandwidthBurst</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>MaxMin</receiver>
+ <slot>kcfg_BandwidthBurst_valueChanged(int)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_BandwidthRate</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>MaxMin</receiver>
+ <slot>kcfg_BandwidthRate_valueChanged(int)</slot>
+ </connection>
+ <connection>
+ <sender>pushButton1</sender>
+ <signal>clicked()</signal>
+ <receiver>MaxMin</receiver>
+ <slot>pushButton1_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>timedBandwidthList</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>MaxMin</receiver>
+ <slot>timedBandwidthList_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_UseScheduledBandwidth</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>MaxMin</receiver>
+ <slot>kcfg_UseScheduledBandwidth_toggled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>kcfg_DefaultMaxMinOptions</tabstop>
+ <tabstop>kcfg_BandwidthRate</tabstop>
+ <tabstop>kcfg_BandwidthBurst</tabstop>
+ <tabstop>kcfg_MaxAdvertisedBandwidth</tabstop>
+ <tabstop>timedBandwidthList</tabstop>
+ <tabstop>theTime</tabstop>
+ <tabstop>theDay</tabstop>
+ <tabstop>pushButton1</tabstop>
+</tabstops>
+<includes>
+ <include location="local" impldecl="in implementation">maxmin.ui.h</include>
+</includes>
+<slots>
+ <slot>kcfg_DefaultMaxMinOptions_toggled( bool state )</slot>
+ <slot>kcfg_BandwidthRate_valueChanged( int newValue )</slot>
+ <slot>kcfg_BandwidthBurst_valueChanged( int newValue )</slot>
+ <slot>pushButton1_clicked()</slot>
+ <slot>timedBandwidthList_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotDeleteEntry()</slot>
+ <slot>kcfg_UseScheduledBandwidth_toggled( bool )</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/maxmin.ui.h b/src/maxmin.ui.h
new file mode 100644
index 0000000..05e0b15
--- /dev/null
+++ b/src/maxmin.ui.h
@@ -0,0 +1,123 @@
+/***************************************************************************
+** $Id: maxmin.ui.h,v 1.12 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "torkconfig.h"
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+
+void MaxMin::init()
+{
+
+ QStringList bandwidthSlots = TorkConfig::bandwidthSlots();
+ for ( QStringList::Iterator it = bandwidthSlots.begin(); it != bandwidthSlots.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+
+ new QListViewItem(timedBandwidthList,(*it).section("\n",-5,-5),
+ (*it).section("\n",-4,-4),(*it).section("\n",-3,-3),(*it).section("\n",-2,-2),(*it).section("\n",-1));
+ }
+
+}
+
+
+
+
+void MaxMin::kcfg_DefaultMaxMinOptions_toggled( bool state )
+{
+ MaxMinOptions->setEnabled(!state);
+ kcfg_UseScheduledBandwidth->setEnabled(!state);
+ if (kcfg_UseScheduledBandwidth->isChecked())
+ TimedBandwidth->setEnabled(!state);
+ else
+ TimedBandwidth->setEnabled(false);
+
+ if (state){
+ kcfg_BandwidthRate->setValue(TorkConfig::defaultBandwidthRate());
+ kcfg_BandwidthBurst->setValue(TorkConfig::defaultBandwidthBurst());
+ kcfg_MaxAdvertisedBandwidth->setValue(TorkConfig::defaultMaxAdvertisedBandwidth());
+ }
+
+}
+
+
+void MaxMin::kcfg_BandwidthRate_valueChanged( int newValue)
+{
+ if (newValue > kcfg_BandwidthBurst->value()){
+ KMessageBox::information(this, "Largest Chunk of Bandwidth should be at least equal to the Bandwidth Rate");
+ kcfg_BandwidthBurst->setValue(kcfg_BandwidthRate->value());
+ }
+}
+
+
+
+void MaxMin::kcfg_BandwidthBurst_valueChanged( int newValue)
+{
+ if (newValue < kcfg_BandwidthRate->value()){
+ KMessageBox::information(this, "Largest Chunk of Bandwidth should be at least equal to the Bandwidth Rate");
+ kcfg_BandwidthBurst->setValue(kcfg_BandwidthRate->value());
+ }
+}
+
+
+void MaxMin::pushButton1_clicked()
+{
+
+ QString bwtime = theTime->time().toString();
+ QString max = QString("%1").arg(kcfg_BandwidthRate->value());
+ QString burst = QString("%1").arg(kcfg_BandwidthBurst->value());
+ QString adv = QString("%1").arg(kcfg_MaxAdvertisedBandwidth->value());
+
+ new QListViewItem(timedBandwidthList,bwtime,theDay->currentText(),max,burst,adv);
+
+}
+
+void MaxMin::timedBandwidthList_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( timedBandwidthList );
+
+ menu->clear();
+ menu->insertItem( "Delete Entry", this,SLOT(slotDeleteEntry()) );
+ menu->popup( point );
+
+}
+
+
+void MaxMin::slotDeleteEntry( )
+{
+
+ QListViewItemIterator it(timedBandwidthList, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (timedBandwidthList->isSelected( it.current()))
+ delete it.current();
+ ++it;
+ }
+
+
+}
+
+
+void MaxMin::kcfg_UseScheduledBandwidth_toggled( bool state)
+{
+ TimedBandwidth->setEnabled(state);
+}
diff --git a/src/menu/Makefile.am b/src/menu/Makefile.am
new file mode 100644
index 0000000..1eb5fd1
--- /dev/null
+++ b/src/menu/Makefile.am
@@ -0,0 +1,2 @@
+menudir = $(prefix)/share/menu
+menu_DATA = tork
diff --git a/src/menu/tork.in b/src/menu/tork.in
new file mode 100644
index 0000000..a22ec7b
--- /dev/null
+++ b/src/menu/tork.in
@@ -0,0 +1,4 @@
+?package(tork):needs="X11" section="Applications/Network/Web Browsing"\
+ title="TorK"\
+ description="An anonymity manager for KDE."\
+ command="@prefix@/bin/tork" icon="@prefix@/share/pixmaps/tork.xpm"
diff --git a/src/mixminion.ui b/src/mixminion.ui
new file mode 100644
index 0000000..dd23437
--- /dev/null
+++ b/src/mixminion.ui
@@ -0,0 +1,190 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>MixMinionClient</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>MixMinionClient</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Anonymous Email Message</string>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>mailLayout</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>11</x>
+ <y>11</y>
+ <width>578</width>
+ <height>458</height>
+ </rect>
+ </property>
+ <property name="title">
+ <string>Anonymous Email Message For Delivery Through the Mixminion Network</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout2_2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Subject:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>subject</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget" row="4" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>461</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>send</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Send</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QTextEdit" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>messageBody</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>To:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>toAddress</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+ </widget>
+</widget>
+<customwidgets>
+ <widget class="KProcess">
+ <property name="name">
+ <cstring>proc</cstring>
+ </property>
+ </widget>
+ <widget class="KProcIO">
+ <property name="name">
+ <cstring>mixminionproc</cstring>
+ </property>
+ </widget>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>send</sender>
+ <signal>clicked()</signal>
+ <receiver>MixMinionClient</receiver>
+ <slot>send_clicked()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>toAddress</tabstop>
+ <tabstop>subject</tabstop>
+ <tabstop>messageBody</tabstop>
+ <tabstop>send</tabstop>
+</tabstops>
+<includes>
+ <include location="global" impldecl="in declaration">kprocio.h</include>
+ <include location="local" impldecl="in implementation">mixminion.ui.h</include>
+</includes>
+<slots>
+ <slot>send_clicked()</slot>
+ <slot>slotProg( )</slot>
+ <slot>receivedMixminionOutput( KProcIO * mixminionproc )</slot>
+ <slot>mixminionprocExited( KProcess * proc )</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/mixminion.ui.h b/src/mixminion.ui.h
new file mode 100644
index 0000000..38ba077
--- /dev/null
+++ b/src/mixminion.ui.h
@@ -0,0 +1,126 @@
+/***************************************************************************
+ ** $Id: mixminion.ui.h,v 1.9 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <kprocio.h>
+#include <kmessagebox.h>
+#include <kprogress.h>
+#include <kdebug.h>
+#include <qregexp.h>
+#include <qtimer.h>
+#include "torkconfig.h"
+#include <cstdlib>
+
+KProgressDialog* progressDialog;
+QString output;
+
+void MixMinionClient::init()
+{
+}
+
+void MixMinionClient::send_clicked()
+{
+
+ if (toAddress->text().isEmpty()){
+ KMessageBox::information (this, i18n("Emails are usually sent to someone!"), "Umm.");
+ return;
+ }
+ output = "";
+ mailLayout->setEnabled(false);
+
+ KProcIO* mixminionproc = new KProcIO();
+ mixminionproc->setUseShell(TRUE);
+
+ QString curpath = (QString) getenv("PATH");
+ mixminionproc->setEnvironment("PATH",curpath + ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin");
+
+ mixminionproc->setEnvironment("http_proxy",QString("%1:%2").arg(TorkConfig::konqHttpProxy())
+ .arg(TorkConfig::konqHttpProxyPort()));
+ mixminionproc->setEnvironment("https_proxy",QString("%1:%2").arg(TorkConfig::konqHttpsProxy())
+ .arg(TorkConfig::konqHttpsProxyPort()));
+
+ *mixminionproc << "printf '" << messageBody->text() <<"' | mixminion send -t " << toAddress->text()
+ << " --subject '" << subject->text() << "'";
+
+ connect( mixminionproc, SIGNAL(processExited(KProcess *)),
+ SLOT(mixminionprocExited(KProcess *)) );
+ connect( mixminionproc, SIGNAL(readReady(KProcIO *)),
+ SLOT(receivedMixminionOutput(KProcIO *)) );
+
+ progressDialog = new KProgressDialog( this, "progress_dialog", QString::null, "Sending Anonymous Mail Message..", false );
+
+ progressDialog->setPlainCaption( i18n( "Sending Anonymous Mail Message.." ) );
+
+ progressDialog->progressBar()->setTotalSteps( 00 );
+ progressDialog->progressBar()->setPercentageVisible( false );
+
+ progressDialog->setMinimumDuration( 500 );
+ progressDialog->show();
+ QTimer* timer = new QTimer( this );
+ connect( timer, SIGNAL( timeout() ), this, SLOT( slotProg() ) );
+
+ timer->start( 200, FALSE );
+
+ mixminionproc->start(KProcIO::NotifyOnExit,KProcIO::All);
+
+}
+
+void MixMinionClient::slotProg()
+{
+
+ if (progressDialog)
+ progressDialog->progressBar()->setProgress(progressDialog->progressBar()->progress() + 4 );
+}
+
+void MixMinionClient::receivedMixminionOutput(KProcIO *mixminionproc)
+{
+
+ int pos;
+ QString item2;
+ while ((mixminionproc) && ((pos = (mixminionproc->readln(item2,true))) != -1)) {
+ item2.replace(QRegExp("^[^#]+\\]"),"");
+ progressDialog->setLabel( item2.stripWhiteSpace());
+ progressDialog->progressBar()->setProgress(progressDialog->progressBar()->progress() + 4 );
+ output += item2;
+ output.append("<br>");
+ mixminionproc->ackRead();
+ }
+}
+
+
+void MixMinionClient::mixminionprocExited(KProcess *proc)
+{
+ QString caption;
+ QString message;
+ delete progressDialog;
+ progressDialog = 0;
+
+ if (proc->exitStatus() == 0){
+ caption = i18n("Email Successfully Dispatched!");
+ message = i18n("<p>%1<br>").arg(output);
+ }else{
+ caption = i18n("There was a problem!");
+ message = i18n("<p>%1<br>").arg(output);
+
+ }
+
+ KMessageBox::information (this, message, caption);
+
+ delete this;
+}
diff --git a/src/newfirstrunwizard.ui b/src/newfirstrunwizard.ui
new file mode 100644
index 0000000..259decf
--- /dev/null
+++ b/src/newfirstrunwizard.ui
@@ -0,0 +1,2551 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>FirstRunWizard</class>
+<widget class="QWizard">
+ <property name="name">
+ <cstring>FirstRunWizard</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>627</width>
+ <height>432</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>TorK</string>
+ </property>
+ <property name="titleFont">
+ <font>
+ <pointsize>12</pointsize>
+ <bold>1</bold>
+ </font>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>OpeningPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Welcome.</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KActiveLabel" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>text1</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;h1&gt;Welcome to TorK!&lt;/h1&gt;
+&lt;p&gt;TorK aims to be easy and intuitive to use. Before you can get started though, you need to tell it a few things.&lt;/p&gt;
+&lt;p align="right"&gt;&lt;i&gt;"TorK is beta software!"&lt;/i&gt; - The Author&lt;/p&gt;
+&lt;h2&gt;What is Tor?&lt;/h2&gt;
+&lt;p&gt;Tor is an onion-router. You use it to anonymize your internet traffic.&lt;/p&gt;
+&lt;h2&gt;What is TorK?&lt;/h2&gt;
+&lt;p&gt;TorK is a Tor controller. It allows you to manage, monitor and configure Tor.&lt;/p&gt;
+&lt;p&gt;
+&lt;p&gt;This wizard will help you setup TorK in a couple of simple steps. Click &lt;i&gt;Next&lt;/i&gt; to begin.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>260</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>LocalOrRemote</cstring>
+ </property>
+ <attribute name="title">
+ <string>Local or Remote?</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>260</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2_3_3</cstring>
+ </property>
+ <property name="title">
+ <string>Nature of Tor Installation</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KActiveLabel" row="0" column="0">
+ <property name="name">
+ <cstring>text2_2_2_3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;First things first.&lt;/p&gt;
+
+&lt;p&gt;Maybe you actually want to monitor an instance of Tor that's running on another computer?.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ <widget class="QButtonGroup" row="1" column="0">
+ <property name="name">
+ <cstring>buttonGroup1_2_2</cstring>
+ </property>
+ <property name="title">
+ <string>Local or Remote Tor?</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>monitorLocal</cstring>
+ </property>
+ <property name="text">
+ <string>No, Tor &amp;is going to run on this PC.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+I</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>monitorRemote</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Yes, I'm going to use TorK to monitor a remote Tor installation.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+Y</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Locate_Tor</cstring>
+ </property>
+ <attribute name="title">
+ <string>Locate Tor</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion</cstring>
+ </property>
+ <property name="title">
+ <string>Couldn't Find Your Tor Installation!</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>TorLocation</cstring>
+ </property>
+ <property name="mode">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>The path to my Tor client:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="KActiveLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>text2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;OK, so we need to look harder for your Tor insallation..&lt;/p&gt;
+&lt;p&gt;If you are sure you have Tor installed, locate it below.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ <widget class="QToolButton" row="1" column="1">
+ <property name="name">
+ <cstring>downloadTor</cstring>
+ </property>
+ <property name="text">
+ <string>Download Tor</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>text2_3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;If you can't find your Tor installation, or have not installed it, try downloading it. You will need the tools used to compile and install software to do this. If you don't have them installed, use your package manager to do so, or install your distribution's package of Tor.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>HowDoesTorStart</cstring>
+ </property>
+ <attribute name="title">
+ <string>How Does Tor Start?</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2</cstring>
+ </property>
+ <property name="title">
+ <string>Nature of Tor Installation</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout2_2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>TorLocation_2</cstring>
+ </property>
+ <property name="mode">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_5</cstring>
+ </property>
+ <property name="text">
+ <string>The path to my Tor client:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QButtonGroup" row="3" column="0">
+ <property name="name">
+ <cstring>How</cstring>
+ </property>
+ <property name="title">
+ <string>How does Tor start?</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>torStartsAutomatically</cstring>
+ </property>
+ <property name="text">
+ <string>Tor &amp;starts in the background when my computer boots up.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+S</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>torStartsManually</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;I have to start Tor manually.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+I</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="KActiveLabel" row="2" column="0">
+ <property name="name">
+ <cstring>torDiagnosis</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;To be honest, I'm not that bright. It looks as if Tor is configured to start up by itself when your computer boots up, but I can't be sure. So can you help me? Does Tor start by itself at boot-time?&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="0" column="0">
+ <property name="name">
+ <cstring>text2_4</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;I've found Tor on your system at the location below.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TorUsage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Tor Usage</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2_2</cstring>
+ </property>
+ <property name="title">
+ <string>Nature of Tor Installation</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel9_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;Since you usually have to start Tor manually, Tork will do that for you in future.&lt;/p&gt;
+&lt;p&gt;TorK can run Tor in a variety of different modes. Choose one from the list below.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="0">
+ <item>
+ <property name="text">
+ <string>Run a Tor Client and Server With Default Settings</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Run a Tor Client and Relay Server With Default Settings</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Run a Tor Server With Default Settings</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Run a Tor Relay Server With Default Settings</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Run a Tor Client with Default Settings</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Let me configure Tor myself.</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>WizardQuickConfigure</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>settingsDescription</cstring>
+ </property>
+ <property name="text">
+ <string>Explanation of setting.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_4</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Remote_Tor</cstring>
+ </property>
+ <attribute name="title">
+ <string>Remote Tor</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>groupBox28</cstring>
+ </property>
+ <property name="title">
+ <string>Remote Instance of Tor</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_2_2_2_4</cstring>
+ </property>
+ <property name="text">
+ <string>:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="1">
+ <property name="name">
+ <cstring>TorPassword</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1_4_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Address/ Port of Tor Instance:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>RemoteTorAddress</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>127.0.0.1</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="2">
+ <property name="name">
+ <cstring>RemoteTorPort</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>70</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="specialValueText">
+ <string>9051</string>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Tor Password (if needed):</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel9_3_2_4</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;Since you are going to use TorK to monitor a remote Tor instance, you need to tell me the address and port it listens on.&lt;/p&gt;
+&lt;p&gt;If your remote installation of Tor requires password authentication, type the password in the space provided..&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_5</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image2</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TorServer</cstring>
+ </property>
+ <attribute name="title">
+ <string>Tor Server Info</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>groupBox28_2</cstring>
+ </property>
+ <property name="title">
+ <string>Your Tor Server</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel9_2_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; The information below will be used to identify your Tor server &lt;b&gt;You can change this later.&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel9_3_2_4_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;Since you are going to run a Tor server, you need to give it a name and provide your contact info.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="0">
+ <property name="name">
+ <cstring>layout8</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_3_3</cstring>
+ </property>
+ <property name="text">
+ <string>Server Name:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>serverName</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Contact Email:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>contactMail</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_6</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image3</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TestingTor</cstring>
+ </property>
+ <attribute name="title">
+ <string>Testing Tor Connection</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Testing_Tor</cstring>
+ </property>
+ <property name="title">
+ <string>Testing Your Tor Connection</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>modifyConfigs</cstring>
+ </property>
+ <property name="title">
+ <string>Candidate Config Files</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="2" column="0">
+ <property name="name">
+ <cstring>modifyConfs</cstring>
+ </property>
+ <property name="text">
+ <string>Modify Tor's Control &amp;File</string>
+ </property>
+ <property name="accel">
+ <string>Alt+F</string>
+ </property>
+ </widget>
+ <widget class="KURLComboRequester" row="1" column="0">
+ <property name="name">
+ <cstring>addConfig</cstring>
+ </property>
+ </widget>
+ <widget class="QListBox" row="0" column="0">
+ <item>
+ <property name="text">
+ <string>~/.tor/torrc</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>/usr/local/etc/tor/torrc</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>/etc/tor/torrc</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>/usr/local/etc/torrc</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>/etc/torrc</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>~/torrc</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>configCandidates</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QPushButton" row="1" column="0">
+ <property name="name">
+ <cstring>testTorAgain</cstring>
+ </property>
+ <property name="text">
+ <string>Test Tor</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>torControlStatus</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>I'm trying to connect to Tor.</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_7</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image2</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>NowForPrivoxy</cstring>
+ </property>
+ <attribute name="title">
+ <string>Now For Privoxy..</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2_2_2</cstring>
+ </property>
+ <property name="title">
+ <string>Half Way There!</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel9_3_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;OK, that's Tor taken care of! &lt;/p&gt;
+&lt;p&gt;Now we're going to look for the Privacy Proxies you have set up on your system.&lt;/p&gt;
+
+&lt;p&gt;What's a Privacy Proxy?&lt;/p&gt;
+&lt;p&gt;A privacy proxy is an application like privoxy or polipo. It allows your internet browser
+to talk to Tor and cleans out a lot of revealing junk from your browser's requests in the process.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_8</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image4</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WhichProxy</cstring>
+ </property>
+ <attribute name="title">
+ <string>Which Privacy Proxy Do You Use?</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2_3</cstring>
+ </property>
+ <property name="title">
+ <string>Nature of Privoxy Installation</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QButtonGroup" row="2" column="0">
+ <property name="name">
+ <cstring>buttonGroup1_2</cstring>
+ </property>
+ <property name="title">
+ <string>Which Privacy Proxy?</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>usingAnotherProxy</cstring>
+ </property>
+ <property name="text">
+ <string>I &amp;have another Privacy Proxy installed, I want to use that.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+H</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>usingPrivoxy</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;I want to use Privoxy, so let's try harder to find it/install it.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+I</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="KActiveLabel" row="1" column="0">
+ <property name="name">
+ <cstring>whichProxyTextwhichProxyText__setText__I_found_an_installation_of_Privoxy_on_your_system_____2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;Do you want to use Privoxy as your privacy proxy, or have you another application installed for this purpose?&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="0" column="0">
+ <property name="name">
+ <cstring>whichProxyText</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;I couldn't find your installation of Privoxy.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_9</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image5</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Locate_Privoxy</cstring>
+ </property>
+ <attribute name="title">
+ <string>Locating your Privacy Proxy</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_3</cstring>
+ </property>
+ <property name="title">
+ <string>Couldn't Find Your Privoxy Installation!</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout2_5</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>PrivoxyLocation</cstring>
+ </property>
+ <property name="mode">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_6</cstring>
+ </property>
+ <property name="text">
+ <string>The path to Privoxy:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="KActiveLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>text2_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;If you are sure you have Privoxy installed, locate it below.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ <widget class="QToolButton" row="1" column="1">
+ <property name="name">
+ <cstring>downloadPrivoxy</cstring>
+ </property>
+ <property name="text">
+ <string>Download Privoxy</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>text2_3_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;If you can't find your Privoxy installation, or have not installed it, try downloading it below. You will need the tools used to compile and install software to do this. If you don't have them installed, use your package manager to do so, or install your distribution's package of Privoxy.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_10</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_10</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image5</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>HowDoesPrivoxyStart</cstring>
+ </property>
+ <attribute name="title">
+ <string>How Does Privoxy Start?</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_11</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_11</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image5</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2_4</cstring>
+ </property>
+ <property name="title">
+ <string>Nature of Privoxy Installation</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="1" column="0">
+ <property name="name">
+ <cstring>layout2_2_2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>PrivoxyLocation_2</cstring>
+ </property>
+ <property name="mode">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_5_2</cstring>
+ </property>
+ <property name="text">
+ <string>The path to Privoxy:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="KActiveLabel" row="0" column="0">
+ <property name="name">
+ <cstring>text2_4_4</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;OK, so we have Privoxy on your system at the location below.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ <widget class="QButtonGroup" row="3" column="0">
+ <property name="name">
+ <cstring>buttonGroup1_3</cstring>
+ </property>
+ <property name="title">
+ <string>How does Privoxy start?</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>privoxyStartsAutomatically</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Privoxy starts in the background when my computer boots up.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+P</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>privoxyStartsManually</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;I have privoxy installed but it doesn't start up by itself.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+I</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="KActiveLabel" row="2" column="0">
+ <property name="name">
+ <cstring>privoxyText</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;To be honest, I'm not that bright. It looks as if Privoxy is configured to start up by itself when your computer boots up, but I can't be sure. So can you help me? Does Privoxy start by itself at boot-time?&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>PrivoxyConfiguration</cstring>
+ </property>
+ <attribute name="title">
+ <string>Privoxy Configuration</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>Testing_Tor_2</cstring>
+ </property>
+ <property name="title">
+ <string>Verify your Privoxy Configuration</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1">
+ <property name="name">
+ <cstring>modifyConfigs_2</cstring>
+ </property>
+ <property name="title">
+ <string>Candidate Config Files</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="2" column="0">
+ <property name="name">
+ <cstring>modifyConfPrivoxy</cstring>
+ </property>
+ <property name="text">
+ <string>Update Privoxy Config</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="KURLComboRequester" row="1" column="0">
+ <property name="name">
+ <cstring>addConfig_2</cstring>
+ </property>
+ </widget>
+ <widget class="QListBox" row="0" column="0">
+ <item>
+ <property name="text">
+ <string>/etc/privoxy/config</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>~/privoxy/config</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>/usr/local/etc/privoxy/config</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>configCandidatesPrivoxy</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>privoxyStatus</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;In order to work properly with Tor, Privoxy needs a line such as the following in it's configuration file:&lt;/p&gt;
+
+&lt;b&gt;forward-socks4a / localhost:9050 .&lt;/b&gt;&lt;br&gt;
+
+&lt;p&gt;This line tells Privoxy to forward all its traffic to Tor for anonymization.&lt;/p&gt;
+&lt;p&gt;TorK can try to find your privoxy configuration file and add the appropriate line for you.&lt;/p&gt;
+&lt;p&gt;Press &lt;b&gt;'Update Privoxy Config'&lt;/b&gt; to try this.&lt;/p&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>CheckUsing</cstring>
+ </property>
+ <attribute name="title">
+ <string>Konqueror in Anonymous Mode</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2_3_2_2</cstring>
+ </property>
+ <property name="title">
+ <string>Privacy Proxy Configuration</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="1" column="0">
+ <property name="name">
+ <cstring>pushButton1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Configure Konqueror To Use &amp;Your Privacy Proxy</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="0" column="0">
+ <property name="name">
+ <cstring>text2_2_2_2_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;&lt;b&gt;Now go into Konqueror and configure it so that it &lt;i&gt;is&lt;/i&gt; using your privacy proxy. In other words, the way it is set you when you &lt;i&gt;are&lt;/i&gt; browsing anonymously.&lt;/b&gt;
+
+&lt;p&gt;When you've done this. Click Next.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_12</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_12</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image6</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>CheckNotUsing</cstring>
+ </property>
+ <attribute name="title">
+ <string>Konqueror When Not Using Tor</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2_3_2</cstring>
+ </property>
+ <property name="title">
+ <string>Privacy Proxy Configuration</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KActiveLabel" row="0" column="0">
+ <property name="name">
+ <cstring>text2_2_2_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;OK, so your going to use your own privacy proxy..&lt;/p&gt;
+
+&lt;p&gt;TorK is going to assume you have configured it to start at boot time and have already got it set up and working..&lt;/p&gt;
+&lt;p&gt;So all TorK needs to learn now is the proxy settings you configure in Konqueror when using your privacy proxy and when not using it.&lt;/p&gt;
+
+&lt;p&gt;&lt;b&gt;Go into Konqueror and configure it so that it is not using your privacy proxy. In other words, the way it is set you when you are &lt;i&gt;not&lt;/i&gt; browsing anonymously.&lt;/b&gt;
+
+&lt;p&gt;When you've done this. Click Next.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="0">
+ <property name="name">
+ <cstring>pushButton1</cstring>
+ </property>
+ <property name="text">
+ <string>Configure Konqueror &amp;For Non-Anonymous Use</string>
+ </property>
+ <property name="accel">
+ <string>Alt+F</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_13</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_13</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image6</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>NonPrivoxyConfirmation</cstring>
+ </property>
+ <attribute name="title">
+ <string>Privoxy Confirmation</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2_3_2_2_2_2_2</cstring>
+ </property>
+ <property name="title">
+ <string>Privacy Proxy Configuration</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_2_2_2_2_2_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>:</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="0" column="0">
+ <property name="name">
+ <cstring>text2_2_2_2_2_2_2_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;OK, that's everything.&lt;/p&gt;
+
+I've configured your Privacy Proxy. Click next to continue.</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_14</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_14</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image5</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>FinalPrivoxy</cstring>
+ </property>
+ <attribute name="title">
+ <string>Configure Konqueror For Normal Use</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2_3_2_2_2</cstring>
+ </property>
+ <property name="title">
+ <string>Configure Konqueror for Normal Use</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_2_2_2_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>:</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="0">
+ <property name="name">
+ <cstring>pushButton1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Configure Konqueror &amp;For Normal Use</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="0" column="0">
+ <property name="name">
+ <cstring>text2_2_2_2_2_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;OK, that makes things quite simple for you and for TorK.&lt;/p&gt;
+
+&lt;p&gt;TorK will start and manage Privoxy for you. It will also configure privoxy for you.&lt;/p&gt;
+
+&lt;p&gt;To be sure things work right, make sure that you do not have Konqueror configured to use Privoxy at the moment. &lt;b&gt;When you are sure that Konqueror is currently configured to browse the internet using your normal, non-anonymous settings, click next&lt;/b&gt;.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_15</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_15</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image7</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>PrivoxyConfirmation</cstring>
+ </property>
+ <attribute name="title">
+ <string>Privacy Proxy Configuration Complete</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>Tor_Installtion_2_3_2_2_2_2_3</cstring>
+ </property>
+ <property name="title">
+ <string>Privacy Proxy Configuration</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KActiveLabel" row="0" column="0">
+ <property name="name">
+ <cstring>text2_2_2_2_2_2_2_3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;OK, that's your privoxy configuration done.&lt;/p&gt;
+
+&lt;p&gt;Click next.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer6_16</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>283</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pixmapLabel1_2_16</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image4</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Netstat</cstring>
+ </property>
+ <attribute name="title">
+ <string>Network Monitoring.</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>Tor_Installtion_2_3_2_2_2_2_3_2</cstring>
+ </property>
+ <property name="title">
+ <string>Network Monitoring Configuration</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="0" column="1">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>pushButton6</cstring>
+ </property>
+ <property name="text">
+ <string>Let TorK run 'netstat' as the root user.</string>
+ </property>
+ </widget>
+ <spacer row="3" column="2">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>151</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="3" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>121</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KActiveLabel" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>text2_2_2_2_2_2_2_3_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;TorK uses a program called 'netstat' to monitor your computer for network activity that might breach your anonymity.&lt;/p&gt;
+&lt;p&gt;This approach is most effective if 'netstat' runs as the root user.&lt;/p&gt;
+&lt;p&gt;If you would like to use the root-user approach, TorK can make a copy of 'netstat' which will run as root whenever it is executed. &lt;b&gt;This is not a good idea if you share this computer with other users, since it might enable them to monitor all network activity too!&lt;/b&gt;.&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ <spacer row="2" column="1">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>30</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Final</cstring>
+ </property>
+ <attribute name="title">
+ <string>Wizard Complete</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>Tor_Installtion_2_3_2_2_2_2</cstring>
+ </property>
+ <property name="title">
+ <string>All Done</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_2_2_2_2_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>:</string>
+ </property>
+ </widget>
+ <widget class="KActiveLabel" row="0" column="0">
+ <property name="name">
+ <cstring>text2_2_2_2_2_2_2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;OK, that's everything.&lt;/p&gt;
+
+&lt;p&gt;Thanks for your patience. Enjoy using TorK!&lt;/p&gt;</string>
+ </property>
+ <property name="wrapPolicy">
+ <enum>AtWordBoundary</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+</widget>
+<images>
+ <image name="image0">
+ <data format="PNG" length="2605">89504e470d0a1a0a0000000d49484452000000300000003008060000005702f987000009f4494441546881ad9a696c5cd515c77fefce7b33e319efbb9d380b71121c5bd98046e4d146a1a2d092500805814050d45405296dd50f05d40f55253e21da2204a51b15b45445950ab44528ec25842140421282972c268e933876e27d9de52db71fee1b676c8f3dcfd8473a9a3733f7befbffbf7bb67b66341628b1584c7897d2344d39d7d86ddbb669e9b1fbf6ed9bbc5ec8fa5aee21b34b2c168b0037009b8043c047c0602e228b29fa02e7878075c00f3d7d5308b1efd0a143a782c1e01929e5e8e8e868a2a4a4c46a6c6c5c30d86cb2d01dd0800dc02f805b0101589aa60d09217aa594bdc0494dd362aeeb7eb072e5ca733535358bba3b0b22009366f400f030b02ccb10099c060e006f036f9ba6d9bdd075d322720fc92971e008d04a7687d48055c03dc08f81abbd9d5b14593001cf613b81934022c7f0614f17cd8c1663074081ea02c6728c4b0249d3341769d9c5235008d402d139c668c095c0fa582c165ea475174e20168b8580adc075405e8ee175c077800d19097041b2a09b7811e826600fb09edc51cd00ae071e449158681efa6a6134168b19a8c872077037b00608cce31671e003e04fc0fb2c207bcf8b402c160ba0cce06614f0cde4369bd9c4052ea172c38bc027c0c87c1ddc1701cf5e2b51e6721f700d903faf95661707e806f6a2887c669ae684dfc97312f0124e21ca41ef47d96f69ae795f516ce04be09fc04bc029d3349d5c936605e299cb2a5499700fb084c50bbb73491c5576fc19780b1898cbacb212f0e2f43750d1653b3ecdc5c5e192d14c57f020c37a2709860108534491bd9c25a96ba8b49a10b9fddd05ce017f07fe0a9c9e6d37661088c56245c0775175cb267c44175b4bd096f72ac7dc57b8746e98f8059d62b78e1005048441521b65449c47af9aa0b2ae88f562170df1dbd065ce7c3601bc033c057c689a666a56029ebd57a2cce541a03e1bc1e9d26d1c619ffe04675b7a291b6b62f38aed2caf584b404c0df152ba9cef3fcdc1d36fd11b3dc6b2c60ab6d93fa7c6da946b090bf810780278c7344d6b360225c0f7819f002b72dd15a02df85ff64ffc9ea123116e5cf7002b2a1afc4ca3e3520b6fb6bd40c9a6385f8f3c4443ea965c5352a87cf104f0be699af614029ecddf0a3c823aa0e47cf2ed8177d93bfc386e7b35bbaeda437ea868e6a0b4cbbb33bf1a890ff0f2674f63ace9e3db458f50ef7c33d79209e065e071e08bb463eb5eb4d9827afa4d7ec0f76927796fe24952edc5ecdab49ba061907227d0231ac188869ea72174d034752b2925ae0d7642624d4852e3925028ccce4dbb79f5c833bcd7f824c5e13acae59ab9960da3c2782b2a6ff4a59f512d701b60e2e38c2c91ec97cfd27b22c5f6863bd175032d9a245a673351f6257da1565c3d8eaba57048e290c4d55260a4d00b2cf2aa6c0a96d904f293848261b65d793b974e24d92f9f45e63e26547b58af4bd751021569b6e233549e9107e8b8d8ca9af26b28ce2f255a6313ad72d08c140967845bca7e899482be64072ec9ac8a9e2252e950b0d4a1a2a4862b4a36d271b19533f240aee535a01155112c4b13d8822ac67c49abb5176b48b0b6763345751223dfc1c552ea3a0445946f95fe94ad853fa077a29bb833e27d9f9aa17a9e4d499da469d916ac2141abb5d70f8430aa066b8cc56242786f0afcccb4649c8eb1c3d416d653be348c1e76a600725c6bf2b05897d7c45d35bfa65c5e49f758078eb42e13cd501174a85a16a5b6b09e8eb1c358329e0b86860af15b8032812a177c95083df671928914ab96ae265a082a445f56e94e4d9642136c2dbf875b2b1f6362cc61387909893543435197d5cb57934ca4e8b18ffb81520434004b0450ee6706c090dd8de60658525389d4ac99eada59e71507abf95edd63341977d033d08d2313a05953b4aeb61acd150cd9be3a2e1acaa12b05f3a8e7934e9cb011259a1f40158f975562e3ba73178f4da5dbb977f9ef60b88ad6fef7b9681f25e10e20b1884404e16084a493d384d2048a81e279559701d740043474dd99f10435cd0269e76c98040379ec5cf130b7973e47e7f91efadd662c86d0844d301820e01a7ee1140345f322902f2a184f8c9070fb41b367e8741f984d8ef77dcc6b171e65e992288608302ebbb018269e9c205f54f885930252f33a545787d76025257d890eaaa22b096a53538794f69c1b309e1ae6b5f6c7e9cf7f97f22579a8deb0c2326475303166535de63ba20f00033a592b95ec52a09751e1aea5bb6f80d2683eb61c4068414022a543c2e99dd5843ee97c8d4fc79ea26a295489c219df9febefa7dc5d43815ee6178e04a400efd4e1531a0bb773a2fd22ae2bd18586d02c846613101291251af78e76f1fcd1873815fe2dcb561884740343e8535443d07aa29bc6c2edf3013f000c0a544bd0b75c55b183547701473a4f63088360e0b206e4658b74a5cb5b6d7fe195aefba95edb455951c194b199da72be93f1f3795c55b1c32f0c1be801fa04ea20edcffb004384b8be6637cd877b3874ee04baa61314064161a07b87b7d3179b79eeb3fb48d5fe87fa2b8a145031530dcda0b9bb83839f9ce5fa9add18229463f54919014e011775e028eadc5be977f6c6ca1b3833d8c2e79fbf4edc8963d66da0281c252075fe7df83738951fd1b0b10888cc7a8ff1549c8fce37d3f2790f0d72071b2b6ff0bbbc04daf0fa483af031d0ec91f0dd2ed9b97a0fff3836c0f1a30718b0f6535fbc9455d57554e6b76118b33be270729c96fe0e4e0e9ea5a73949f5e0b5ec5cbfc7efb200e3c0a740b3699aae0e7c813a383700357eef12103af76ef8156f9c789e4f3f7889c4e64e4e159d25dfc8a326524e61304a381044d33412768a516b829e893e8653e32487253d871dbe16b99b9b363c80a6f94e47ae87f77fa8aedee491721df02870279783b36fe91c68e5f5b63f3258dc42f14a417ead404ceb65b80e8c5d7019ea7029196ae4e6861fb1bc74dd7c97fa12781278d134cd914c0206ca841e01b691a39522a50af6aeeb4ebe775d973303adb474c7681f3cc478e8025a48c506990c104dd6525f72358dd55b5951d688a669932a84da81f4117416e9079e079e364df36cfac3ccae44d823f13354536b7227d2006ddbc6711c1cc799bccefccc75ddc957dbb149dae30084f40801a123844008412010201008a0ebfa8cebcccf3208f5032f00cf009d999dec2994bd9db81ad55ad98177cc4c03b32c6b06f86c4432c9482927c1a481a58166829eaede3817e84075e8fe06744c6fc367ebcc096035aa0b7d17aa4724d23b912624a59c04980976ba669a46da5cd2afd335d3ac505db903c01f803781d16c3dd2b99abb05de6eec42fd9d6025109c6d7c9a600e3bf62349549cff17aa0f346797da4f7b3d8c3a83de08ec4435be0ab3cd4d3f71c8e990d3c541d536c750bf13bce1019fd10b9d2ebe57f11a60d5c0b528276f44ed4a052ae54e06f34cf30132cd22137012e805da8183c0bba8aa60d0cfef02f32690854c04a84235051a517e53888a5ee5deb540259f6160109545bb518e791615d7bb8071d3347d97f599f27f14734ae37c53dea70000000049454e44ae426082</data>
+ </image>
+ <image name="image1">
+ <data format="PNG" length="2962">89504e470d0a1a0a0000000d49484452000000300000003008060000005702f98700000b59494441546881ad9ad98f1cd775c67f75bbaabb67ba675f380b67b888db686452a4245352292228409011894e6c23860c038e052889032801f2e038c81f90173d084104677bb013073102c4319cc09064499628a9c248a4c5c533430d39e22c5c66efbdbbf67bf350dd833139c3eef1cc010a5d5d756f9defeb7beeb9e77ed51adb34cbb244f55499a6a9eed7f6d4a9535aadedd9b367d7ceb7e35fabdf6473b32cab197816380e5c00fe17c8d623b293a66fb37f027810f8a3eaf19610e2ec850b17aec7e3f119a554b1582c3a1d1d1dfee8e8e8b6c16e64db1d010d3806fc35f0fb80007c4dd372428865a5d432704dd3344b4af9c1be7dfb6ef6f7f7efe8e86c8b00ac85d14bc05f02c31b3451c00de01cf036f0b6699af3dbf55b3351bf495db3818bc0041b4f480d7800f826f067c0a3d591db11db3681ea849d05ae014e9de6f9eab16361b413230011a8db40a94e3b17704dd3dc21b73b47a015180052f769a3014780a396652577c8eff609589695009e049e029aea341f027e1738b66e01dc966deb21d50cf425e015e028f5b39a013c037c8788c476d7a1df2e8d5a96651065963f00be011c02625b78840d7c00fc13f03edb58bdb744c0b2ac1851183c4f04fc04f5c3663393c012d1daf023e063a0b0d509de10816abcf61285cbb780c780f4963c6d6e21300fbc4144e457a669561aed7c5f02d505a7956882fe2151fc76d6ebf75b5a007c0efc07f063e0ba699a61bd4e9b02a986cb034465c2378141762eeddecf6ca2b2e39f815f0099fb85d58604aa79fa69a2ec729a06c34512b2648c713b7e9ebc3e8b431e80246db4057b18f41ea3d77f08517fbe4be026f06fc0bf0037361b8d7b085896d506fc1e51dd729c06b24ba0395c6dfa2957e47fb174338f7d47a75d0e91a085983070b52205710b7d5785dea1368e8aaf32627f055dd55dcf2ac03bc0df021f99a6e96d4aa01aefbd44e1f21de0c04604efb679e32267f557991b5fa6abf41027f69e664fcf6162e23753bc52925bab37387fe3172ca7ae303cdac3a9e0bbf4fbc7ebb9f0818f805781774cd3f43723d0017c1bf873606fbda7025c8dff371f56fe9edcc5669e7bf025f6f68c002003c5f24491446b8925679581c17da4d229342d7237bd34ce5b577f48c7719bdf69fe5346bc2fd773e511ad17af02ef9ba619d46e882af824f01c518adcd308f8a9d8bbbc93791d7bac87174f7e8fe19e83480224014a04a8b824e1ea94a6353ebf9cc1f5bcb5fb7b7a0ff3e217bf4be94a07ef645e672af66e3d7771a239f96d60c4b2acb51ba29a6d4e566f3e440361b3a25de39795d7f0a6daf9f2f19749c40d3c5941266df44e87f8ee222d4772286930dcb99f30f4d1bbcbe85d0eaac9c69515128924678ebf8c7d2dcd2f2bafb1a25dabe7364994c6cf00dd6b0488aac8af00260dec91158a0fd5f7599ef4383df27574dd404bb9a486022a5dd7c9a5de67c9799bb9899b74f736d19e4ee22d6adc9e9925482c93dce5d3321c104bbb24e2494e1df91a4b932e1faaefa3ea6f13faaa589faad5518228d33c4983a972469d637a718243dd8fd19eee24d51f90da15a2c50b18fa0cc53b3966de331832f6d33fd44a32e5b1b77d981bff6330f9d12299d52542e1d0dc1bd2b23ba4a7a39ffd1d0f33bd38c18c3a57cfbd068c125504c3350227898ab1866cc27f033f27383c7082b62185910e9038045c657e2c20f3f10027fa4ef1f813a3e842c7487bb4b4840c1afbb9f133c1af7e324f76a140a85cf4a6808e21c543c327f1738209ff8d462024896ab051cbb284a87e6969a4a7af6ca64b9f32d07a80eedd49f46488d48a045c62f6d74582c93d3cfd85a739fe8583c4420d29252a0c114d6584d4184c1ca2f0719a733fbdc4c2d24d243e221eb26b38c540eb01a64b9fe22bbb1e0c8d28c59f04ba0451b9d05089b0107c86eb783cb0fb20a956009f98b1487e312473b993c78f3ecaf0602f5e29402985263482409248498a7616e90a3ac530998f7a59fac4230c1d143e8994e4e09e83b88ec742f0592350da80116050b06e46d7b35c308f26630cf6f7a2341fa5f968cae0c6798fc30323f4efea24bf5a413304f1948152602462482465bf44296fe3574252ee0063ef6528e5b2a0f9a0f90c0df4a149412e684871d1882674af600bf5bc1bda248d14a9748ca8780c8869a017dbd9bf779042ce26d962906836f02a0181132243854212681556568b148b0e7e45a332d5c1cc95051cb98ac2a7b959908c37e3867543a846a01d68df527519930622a6a1ebe1da2fa709494ba21b5dd7914a92481a14b336811f622463f85e881f86842a205f28522eb9d8151f372f589975c9c8097c726822201e8f119346a370da81b62d11488b1eca4e0147ae82168016a05024f404a5a24d6b7b33c5bc4d2025c996389e1380844ac9c3757dca6517bbe2e1d81e9e2351414832665056b7f1c963bb15d2a2a751381ee06d89405ff210beab5871a6f1c9a369215242a87c023fc4b53d3c2f20dd9a200c15c59c8342a350b029971d3c37c4767c1cdbc7973e464aa16b3134cd23e74f532905f4251bcee8192023886aef86ac45efa2471e667e2583cf32153547512e53f2b3c40cc1f2628e300c892774b2d91289b441a885d8b643b1e010f812d7f1717d0f92362dbb7d74a11317060bab39bae5215af4ae46e1284009a8ee3a1ab4d1d6d34c4e2d22a542171a42f37153ab64f3399452d8b64ba5ec50cc9748a5130481c4ae38ac2c15903e785e80e7bb34ef2dd37fc4c0103a1a8289c979465b4f6f057c06c80a2249b0617ba4e705bcf9162ecedec01006f198c1d02392abf397710297cc4a817cae4c3c61502854705c8f5bb73214563d8240e2051e7ec72ac7bee6d23bd0443c66307e6b96f2ad261ee979a1511801b000ac08a28d74ddcd73cd0c91e099fe9719fb74810b3727d1359dbee124fd8fe7f964f202376f2f71f1c21495b2cbecf422b39f2f327ee5365ec120d06dc45096a75e7138f97c1b493dced8fc34e73f9ee399fe973144a2511805e03ab0a8039788f6bdbd8df67eb8f75966b2e35cbefc73ecd0c61c3a46dffe0441b8cad5f7f2e4e63caedfec45b9825f5f9ea2e016e93cd2c6e0b10227cef81c7dba1d19f7f960f612e3971718512ff070efb38dba57c055aa3a920efc1f305625d1b05c72e6e02bfcfb950c9f5d3a47c6ff9003edbbd9dfbf9b67bf9566f98e60616e99d50587e15e9b635d9decd9ab3374240ee918e3d929ae65e7581873e9cb3ec199a3af34ea16a00c7c028c99a62935cbb2ba803f26dac4f76fe5494a49de9cfc019f547e4cdf891889368db4d1447f7337adf114c9581c4dd370028fa25f61a1b242de2be3e6150b9f867cb1f91b7ce9f04b685ac3d95c12fdf27f03bc699a66a0015896f520f057c0d7895edc6dc9663313fcfcea3f926d1fa77d9f203d20107769193284d21d496e5ad2911be5f9913f614fe7835b75f539f01af023d3340b500d99aa587b1af81e708a3a528a52d1ce494ab9f65d4ac94c6682f1798ba9ec05ca893b68892837283746ca1de040c7a38cf63dc9deae51344d5b3b848846a0b6e9dfc456811f007f679ae65cede27a55225925f117441be8b591a8010c8280300c09c370ed7cfd3529e5da671006b841198084de4c4ce808211042108bc588c562e8ba7ecff9fa6beb08ad023f045e0766d72bd9bf41b93a128f12492b2f50dd66d680f9be7f0ff88d88ac27a3945a0353035603ba1ef4dd47b59d04a68914ba7f05a6ef96e13752e604709048627991482312b591a811524aad015c0ff6ee637d68d4c2a5f679f7b13eac8854b973c03f006f01c58d34d2fb89bb2dd5d1f82ad1df09f611e9339b9a52aa5e1c37622e519eff4fe027d451a91b91d793447bd0e7883499634492fb3d7d6bbf38d49d90775b4854db5c217a4ff06615f83d5ae8ddd6b097aa00d6073c4134c9478946a5076866ddbe7a7df800ebc3623d60175806a680f3c0bb445541b691f7025b26b001996660179128304a346f5a89b25777f5bc56aee7812cd12a3a4f3431e788f2fa6da06c9a66c365fd7afb7f45003c408f3206230000000049454e44ae426082</data>
+ </image>
+ <image name="image2">
+ <data format="PNG" length="2975">89504e470d0a1a0a0000000d49484452000000300000003008060000005702f98700000b66494441546881ad9a5b6c1cd779c77f73e6b2c3bd70975ade698a6275b34459b264c9b2354e55bb309c3672daa449e134451b032e9a026ed13ea429fad4d7d60f46d1a0685a14499aa0468224451f02c7b72672bc566c29924d9992ac3b295114c5cb72b997d9999d39d387b3245632c95d86fa80839ddd3d67ceff3fe7fbbef39dffaec6062d97cb89fa65e4384eb456dfa3478f6a4b7d8f1f3fbe7cbd91f9b5e65d56b75c2e17079e06f603a78077817c3322f7d38c0d8e8f01bb813fabb7d78410c74f9d3a75c9b2aceb5114158bc562b5a3a3a3363232b261b02bd946574003f6017f0ffc3e20809aa6690b428899288a66808b9aa6e5a4946f0f0f0fdfe8ebebbbafabb32102b0ec46cf037f0b6c5ea14b045c054e006f006f388e33b5d179974c34efd2d45ce00c708e95035203b6025f06fe1238585fb9fb621b26500fd871e022506dd2bd506ff7cd8deec70a80023509949af4f300cf719cfb34edfd23d00ef4038935fa68c083c0de5c2e67dfa779374e2097cbc58023c013405b93ee83c0ef02fb1a36c00dd9866e52cf409f065e04f6d23cab99c053c057512436ba0ffd7a693497cb99a8ccf245e04bc00e405fc72d5ce06de0df819fb381dd7b5d0472b99c8e7283cfa0801fa0b9dbac6612b883da1bbe0bbc072cae37c05b2250f7d76e94bbfc09700848ae6ba6d52d04a6805751447ee5384ea5d5c16b12a86f38eda800fd5394ff6e6a36eed7b400b8027c1f7805b8e4384ed86cd0aa40eaeeb21555267c1918e0fea5ddb5cc45951dff01bc0eccafe5562b12a8e7e9df4465972769d15d242177cc8f98b44e5230c6a95200c0264d3a1862c03f44776d0fa279bc4be006f03de03bc0d5d556e3130472b95c1af83d54ddb29f16b24ba05539dff63f8cca1f73e74601f79641460e1223852e4c3cadc8a2b889d153a17b30cd5ef17976b99fc3889aee6715e04de09f81771cc7f1572550f7f76e94bb7c15d8b612c17b6dca3cc371e32526c666c896f67060cb930c75ed441777a7f82892dc9cbbcac9abaf33931865f348174783afd157dbdf6c8a1af00ef012f0a6e338b5d50874005f01fe0ad8b2daddcae532f1789cb9b939a63adfe144f04d16cec47966f7f36cdeb413e909d2b11ebad27d4ccd4c920f6e104fddfda4afdd19e3b5f3dfa663bfcba7e27fc12effb3cd48f8a8fde225e0e78ee3044b5f883a781b7806952287d6ba93e77924934912ed6d7c78f634faa9031cdbfad76c320791258bfef84eba139bb1b4389b123d9417ab4882bbda50f74e9e7bf46b94463b7873fe1b5cd6df6a46c042c5e457805db95c6ef90b51cf3687eb5feea189db789ec7e8b9d3bc773ac7adb1225b6207b873a54470278e564e323b9d6762628272b94c221e47243de2431ef6808791ad12b5b978b2422c66f3ecfe17702f26f9bfcacbcc6a179b91b05169fc59a0739900aa8afc1ce0d0c219b9abbb8b93e23b9c1fff157ded5be91deae2b1c38ff1e881c7191cd8ac562791209d4e53aa2e52338b48cd07d3c748d568eb09486d0ed0931e31cbe6e8837fc09d8f3d7e11fd2b51f363426f1deb134b759440659a23b4982a6f88f799e40c999e0499782749af9fdfe8db0d9186699a64321932990c8661707df222b6ad532d78540b35aa85806a21a4569698318db6768d4e7b33db938f7375ea1cd7a313cda6d780115445b019d4133f8c2ac65ab273b557a99522b66c19664fcf13485f6376668ecece4e0cc3a05c2ed3d6d6866e983cb4f33134f3109ad0eef2cb08208ac088d052826da943bcfcee0b9ccbbecab075a419041b55838de472b9eb46fd4daa15f0b5c8e55ae934438987d93b7c88b6204db63fcbf4f434fdfdfd542a158410a4dadbf9c1cf26288b38ed291bdb36b16206bad0a87801b30b3e958a47b15865678fcd33fbb7d327f670adf40b6a1d2ea6b6667da8a152fc61e09706aa5c68a944b81d5cc02f473c39f4473cb2f328d7ae5c27994c92c96428140ab8ae4b14454829b9321bb1a93b4e5b3c811533314d1d21342a158f93376b2c2c442ce443c230e4b776fb74777473b3ea733bb8c0a0d9746f4803bb80018386886e660bc114fdd15e8eec38462ad14e4f4f0f737373846148b158c4ad56d034c1c0c00354ab35423f803044d6209421ba2110610d51f3b1a2002d0ca894ab542a924c3a8556102c0453ad10d05001dd6db08e7ade0b5d0ef61ea333dd8beffb54ab55a6a7a771dd0ab3c55bccc8b37466b3ec8946a8947de6e74a74a54d2ccbc0d035e2ed2669137a135041a3345dc55dd409039d9825b0ad385ee8b60245033240665d473a5d9ae417e6393bf601f97c81b9b919f2e5690af21afac00d867697b12a12a1471886c1f88c4b0d811533b04c9dc12e9b2090542b1e55b7860c2520906180262496a5a34bb355381920bd2e0249d1c5ffcefc133e93e0c51076487c5bc00303217647151946889b4358d938a66d71f66289eb0b1176dcc4b60ce6dc8884258884816644889885b004a10c097171bd0ac94457ab707cc05f17815e7b07815d2279f0125d6d43d87a0aa11b48aa78551d6371988cb9035de8ec184c51923689440cbbcdc4b40c4c4343862a1634017d5d71b60d984859c40d67a994027ab32d67f47960de40d5de2d59cac8d225777267214f573a854701a159048b2603ee17d8d6f11466368eaeeb3c77b49fcf7a21102165888c2461101204114120f06b825acdc220a45675c9978a74ca1da48c6cab7022203250aa5abcd55123ed4f72eaf27fb26b709098a111d47ce2f9c36cc93e8516c6f07c9f45af881002e1fb144b252ccb52448290280ca956cadc98be88cb34881057cef071fe230e753cb71ef0f340de4049827dad8e7ca4eb18ef9efd0167c6aff2a9ed7bd4ad2aedccc93c524aa2285ade0b128904d96c1629258661a0691ab55a0ddbb6c9761fe4f2fc5bcca7de60b27c09ff96c6233b8eb50a23006e03b306ea20ddd2c90bc014319eea7b81574fff236db6c9a3fdbb990dc798ba344b183416631a8f3cf8dbf424bb096a21beef53abd508c310dbb6696fef66b1fc10276fbfc2e8f84d7e67e0eb9822d62a8145e012306d001fa0cebdddad8e7eb8fb69aee7c7f8f0c39fe0862e87b63d84dd7f8392efa2e9f54d3d820f672f70e1bd87c89a3b88c7da11c240ca904a7591e9c58b8cbaaf73c51f6357748c87bb9f6e75fa08384f5d4732805f021fd549b42c973cbbfd45fe7b749e0b1f9c607e24c7b6cc036cdd3448dcb69084689a40eff591e50f70f3a3cc2f42e84345badcd46e32999960aee8325039c2b37b5f6c755a8032f03ef091e338d200cea20ecebb58472ce8c2e08ff7fd033ffdf85bbcfff62b540f8c73293d41d26ca32fde49bb95c0d62d345da39af129262adcaecc52f0cb788588dba7431e8d7f894fef7b1e4d6b59ad9175bc3f43a97aea89e772b9ddc0df017f88fae16e5d363e7f8e9f9cff26f9cc18996141b25f20ee89281942e99664e19aa4636184cfecfa738636ed5eef5457809781ef3a8eb3d848c044b9d0d781a33409e82852c12aa55c7e2fa5e4fafc39c6a6725cce9fa21cbb851653524ee4e924bc7eb6751c64a4f7085bb223689ab6dc84502ba0696b7af01cf02de05f1cc79958fab05195b0eb24fe0675805e5e89258041101086aa045eba6efc4c4ab9fc1a84015e50062066c4d185a1f60621d0751d5dd7310ce313d78d9f35109a03be0d7c03186f54b2efa25c5f89832869e518f563e612b0a534d8087e25228d64a2285a06b3046c096823e87b5bbd9f04aea114baff02aedd2bc3afa4cc09603b4a62790ea51189a59558221445d132c046b0f7b646d7587297a5d77b5ba35ba154b913c0bf01af01c59534d2b5c4dd547d353e8ffa3bc1304a9f59d5a2286ae6c7ad9887caf33f047e441395ba1579dd469d419f416932fb5092fb27c62e3d71681a90f75a88aa6d4651bf13fcb40efc135ae8bdd6f22c7501ac17781c15e423a855e9421583cbc9bcd17d8046b76804ec0133c065e024f016aa2ac8b7f2bbc0ba09ac40260ef4a044811154dcb4a3b25767fd5aa0369f029047eda253a8c09c40e5f549a0ec384ecb657da3fd3fad00dc2c128163e40000000049454e44ae426082</data>
+ </image>
+ <image name="image3">
+ <data format="PNG" length="2905">89504e470d0a1a0a0000000d49484452000000300000003008060000005702f98700000b20494441546881ad9a6d6c5cd599c77fe7dc7be7cd9ef1fb6be2248624609c4d480844e44223a81005c22e04757751f70556acb695d89576a55d56bb5f56db7e417c401594be7d28b4ab565d6db755054a29852584216d098484c48943881d3bc1268ec7af337367eebde7ec8733e30e89ed19633fd2d5dc199f73cfff3fe7799ef33cffb16095964ea765e956bbaeab971bbb6fdf3e511e7be8d0a185fbd5ac2faa0f59dad2e97402b807d8091c05de01a6aa11594bb357393f0adc04fc6de97a554a79e8e8d1a31f45229161adf5dcdcdc9cd7d4d4e4f7f7f7af1aec62b6da1d10c00ee0df80870009f842886929e584d67a02382b84482ba5deeaeded1dedeaea5ad3dd5915015870a3c7817f01362c324403e78123c06bc06baeeb8ead76ddb2c9ea43aa5a1e38060cb078400ae07ae02bc0df03bb4b3bb726b66a02a580bd009c05bc2ac3674ad79ab9d15aec0018509780f92ae30a40c175dd355a76ed08a4806ea06e993102b811d89e4ea7636bb4eeea09a4d3e928b017b803885719de03dc0feca838005765ab7a4829037d097812d84ef5ace60077035fc59058ed39f4f9d2683a9d763099e5cbc0a3c056c05ac123f2c05bc0f7803759c5e9bd2202e974dac2b8c10318e0bba8ee364b99022e63ce861f01bf0366571ae0351128f96b3bc65dfe0ab815a85fd14a4b5b088c01073144de735d3757ebe46509940e9c142640ff1ae3bfcdd5e67d4e0b808f819f023f013e725d37ac366949202577b91e53267c0558c7daa5dde52c8f293bbe0ffc1ac82ce7568b1228e5e92f60b2cb5dd4e82e8a90cbce492e45de65c6be80c70c00311a680836b2ae782bedfe3664f57857c028f05fc04bc0f9a576e31a02e974ba01f8134cddb2931ab24b203c4ec77fce09f5bf5c1e9d21ff894da3ea214a124b3a14c41cb3f22276478ef69e06b6cb03f4e51fc6d655cfb31cf01be09bc0dbaeeb16972450f2f7768cbb7c15d8bc18c1ab6dcc39c621fb19464e4dd032bf8d5d9bee6263db0d58f2b3295e6bc5c5c9f3bc7bfed74cd49d60437f1bfb827fa6cbdf596d091f781b7806f88debbafe52049a80c7807f0036557b2ac0e9c82f399cfb36d3c712dc7bd3e36c6aebab651a43974ff1eae91769da99e7cec4d7e82bfe71b52945cc79f10cf0a6ebbac16708947cfe21e0294c8352f59b3f67bdcec199a751e73a3970cb93d4471bae1d540e7975ed9f66f3197ef6de73385baf705fc3536c0ebf586d490ff819f034f06139b0ed52b6d983f9f6b7d502fe8a38cb1bb967299e6be4c0ce2788380e4595c34e40a44e216302dbb611c23c4a6b8d0a20f0347e4e53cc6aa2d1180fee7c829f1f7b9e37fa9fa531d643abdebadcb2314c1a1fc09c1b57c0f4c4ddc0c3804b0d3db2467358bfc0c46091fbfa1ec3b61d86ce5ce4d12f7e0d291461a8d0be46f8025d2afb05c2ccb4c06a9014129a1fbffe2d7afbbbd877e323bc36f82287b7bfc0433c5b1abba47596b00ea4d3e9975dd70d6c4ca6d94b8da972581f61e8f2005b5b6fa5b1be99baae8075931b992b24f9dec1f3b476b6104fd8c4635122511bad14f9bc4f3e57249b2d303f3dc7bfffe5cd34c69a49ae0f096417d735ddccd0a7c7196e3f42afd8bbdcf202e8c754042780f336c67d96ddbb4a1bf00fe24f4b6eb861170d3d1a2716625982cb198f974f78b45df6686c88539f0c8944254a29f2b990b9992293533972b31e8f5d9e270c8bd87168ead16c2bee61f4cc870c341da437b22c0130aeb40be84fa7d3c376e94db216f0bece3334ff3edda9cdb4ae8f61c7141a0b2905d29214b37902cfc3b33404456cc742298d5f0c28e67c74d127c817c865b3046180422023d0b1a18eee4f363334ff3e7e531e472c5b1f0a4c8adf03fcd6c6940b359508e3c1190a5e91eb7bb6509702538759080ba4905c1cc9e0878296967a623107cb9280c6f715b95c81f1f159bcb93c4a85980831293d5a075b366e213d3cc87870861ea7ead9d000f401eb6ca0b516f000d3c1184259aceb6a471300011a8dc4c2766ca2f108052f606e368f5f0c9096446b28167c72b9225eae88b48409742c04219a10d0f4747722ce4ba683b15a08084c40b7dbaca09e2f8479e24e3d8df56d082c8cb8a0115262db16a95482ba5482643246246a635912a534c5828f1d71d008c26280520aad145ac51142a3459e4442128b242884f95aa008a011685c514b67290761819693e80aaf93b28b8863b1be3b4932554f3215251e77b02c0ba5149ee7939d2f3015b7f03d1f21350881d416456641e4b0a52612b1b094532b9c46a0614504ea651b596f168f0962d61f4edef19951f66fa8e3d5afdf86e779785ede0469a8088280c0b708c328881842489271cd9c97212b27c87309814f3d1de40b39eaebda6a8553048a2b22d019db8a5fd05cf186e8a8eb2522ccd1a17a4ef09f2f7d19a520a57ad9d3773f9deddd0485022a5408ad1919fd8863232fe35b5378059fd69d93146462611fa7fd2172f3019d2d3567f40c90b159b45259dc92760b6dea06c6ae6468aeab27d019223246c77521cdbdf39c3d1cf0d0b66fd0946cc7f33c1a1a9b09c390e9e969f6ecbe93ad376ee617e7fe899dae8d49247fb0d1c9495ad55692764bad7034a02594ba8e1aad3f751783e73e45298d2d051109f58e832d6c8a730ec97833894482baba3a8220406b45737333a9548a864407d9b108712b8a23ed854b2019181ca33f75d74ac06780291b230976d53af396b6fdbcf3e17f73ecc279eedcb20d25146849bd1d63f77d3edf7df311f2a36da49c2e766cba9f99d90c1f4f1c61b67889d48649ee38d042d472f07461e199c747ce92bd18e7963fda5f2b8c001807ae484c235db5792e9b23a3dcddf50427df1fe7e8e820b6b051020a4180a51cf6dedbcede47439cf5e7908e626c728858ef2077ff8dc47da00b292d424222d2c1110e27c78678f77723dcddf5048e8cd60a6316f808f8d4063ec0f4bdedb5cebeb9fd1e86a74e71fcf82be4c33c6ecf0e0a9392f0833f23d5b1896c6692ddc926d6afebe0fa0d37f2de7bfd4cbce271dd759bb93472166bfb4f69582f79e7e2494e1d1fa74fefe7e6f67b6a5d5e03a729e94836f05be0648944cd72c9835b9ee4c727329cf9e00819ff30eb441799c197880ec6d1da2669adc7b26ca494ccccce50101739752946ae9825b5619889c238e3270b744eddce83db9fac7559802cf07be0a4ebbaca063ec434ce7dac20162c69f3173bfe835f0dfe80dfbff513bc5d17893e7009e9c4e94ab4928a0c13b3220821680e8accf939c67357c815b34ccd68c60f85dc9678942fed781c216a566b5409efff6154bd8596f226e05f813fc5fc70b722bb9019e095d3df65aaf1148dbd92fa6e89bc4acb5021cc7fa2981e52344df7f340dfdfb1b1f9a6952ef531f02cf023d775672b093818177a0ad8471529456bd36929a516de2ba518ce0c706a2ccdb9a9a364a39f20a22637e882455da19bcd4dbbe9efdccba6967e84100b97946607ca2de8123609fc0078ce75dd91f28795aa44ac44e21f31a2d6c24e940106414018868461b8705ff999526ae13508030a411680a89dc092261ea4945896856559d8b67dcd7de567158426811781e7810b954af6672897766237465ad94fa9cd2c03f37dff1af08b11a924a3b55e00530656065a09faeaab344e01431885ee87c0d0d532fc62ca9c04b66054e83fc76844b2bc1365425aeb05809560afbe2a5da3ec2ee5d7abaf4ab7c2a8724780ef00af02738b69a4cb89bbc9d26e1cc0fc3b412f10596a7c9960153faec50a983cff3f181d685995ba16793d86e941ef051ec4085fa9c5e696bf71a81a90575b88a96d4e607e27f85509f8355ae8d556f32a2501ac13b81d13e4fd985d69031254f4d595ee0354ba4525e00230019c03de055ec7540553b5fc2eb062028b9049001d1851a01f1337294cf66a2ddd4bcce133034c614ed1314c608e60f2fa2520ebba6ecd657da5fd3f5583a9d5198e224e0000000049454e44ae426082</data>
+ </image>
+ <image name="image4">
+ <data format="PNG" length="2801">89504e470d0a1a0a0000000d49484452000000300000003008060000005702f98700000ab8494441546881ad9a696c1dd515c77ff7cecc5bbdc64b6c274e48b3e1380d5989c8b40d81462c091452d116a1165069019156aaba04f55bbf54023e441588ae1269a98a5a354542b421842d094380840442622721d889b3d889ed673bb6df36f3e6f6c37dcfbcc4cb7bc63ed2d59bf77cefdcff7fce72cf3963c114c5711c99bd54b66dab89e6ae5fbf5ee4e6eeddbb77e47a2afb8bc253c617c77122c04660057008780fe82b44643ac59ce2fa20b004f85176ec9652ee3d74e8d0678140e08c526a70707030595959e93637374f19ec5832550d08e006e0d7c03d80045c2144bf94b25b29d50d9c124238beefef9b376fdeb9fafafa69d5ce9408c088193d0cfc0a9833c61405b40107803dc01edbb63ba7ba6f4e64e1290525011c015a18db2105301f7800f809b03aabb969912913c83aec59e014902c307d203ba6cd8ca64303a0415d00860acc4b0129dbb6a769dbe92350063400d109e608e07a6099e338a169da77ea041cc70902eb80af01e102d31b813b811bf20ec029c9946e928d40b7035b8165148e6a16700bf0189ac454cfa12f17461dc7b1d091e53ee07e6011604ce21609601ff027e01da6707a4f8a80e33806da0c36a181afa4b0d98c273e70197d36bc087c005c99ac831745206bafb56873f901b0062899d44ee34b06e80476a1897c64db76bcd8c51312c81e386568077d106dbf330aadfb92e2019f03ff045e023eb36d3b5368d1b840b2e6321f9d263c00cc62fac2ee449240a71d7f065e07621399d59804b271fa1be8e8b28122cdc527c365eb181702071930cf9264008010e5947b7399955e43adbb1459d8df7de01cf077e0af40db78da1845c0719c72e05be8bc65054544174f24690dbfcc51ff3f5c3e3740e2a24985df4890520c699112835c91e73167c6a96d2c6799dc4253e25e4c55f03c8b036f00bf03deb56d3b3d2e81acbdd7a2cde53160c15804af954eeb087bcd67e838de4dd5d052565eb781b9358b31e4d5215e299ff3bd6d1c6c7b9deee851e634d7b0defb25f5ee8a425bb8c0bbc033c01bb66dbbe311a8041e027e0a5c57e8ae00ad8157d81fff3dfd4722dcb6e461aeab692a6619ed978fb3bb7507952b127c3df2384de9bb0b2d49a3cf8b6780776cdbf6ae2290b5f97b806de802a5e0933f6dbcc9ae81a7f04fd7b165d5564a82e5a327e55cde1ffda72b89183b3f7a166b510f77946f6341e6d6425b26819dc053c0a739c736b3d1662dfae92f2d067c8f38c55bf1eda44f57b065c523042c8bb41fc78c4020ea234302d3341142df4a2985ef819754b871457a58110c86b86bc523bc7ce439de6ade4e45a8916ab568a26d43e830de823e377a40d7c40dc0bd804d1135b242b15f3d4ff7c93477343d84695a88688ac80c9f941c0611a0fbc00a062f9461054a49263d924997731d9d846b06b9f5f118414f118f65086642acbffedbec39b983fdcb9ee71eb623267e7e7559ac2d8ee3bc6adbb667a223cd3a8a0c9567d401da2fb7b0a87a0d15253388d67b044b241e71cce172baf7dad4d6cee4e67b66515b65601ae065a0f3b2cbce9d9ff297adc7b8ef37dd94d6fa98a53e9eace72b95cb69bff409676a0f304fac9b687b0134a33382a3409b449bcf84bacb971677176ebf6471c34aca1b155649069f0c82007d1fac62f69c39dcb2610e0db51a3c80694063bdc5d6c75772ebc635fc6f7b253e69ccb04765a362e99cb5b8fd92167757311042e81cacd9711c29b35f4a8b59e9aa04ed438769285b40f5ec1066c847010a9f3457c8c4cb58b264264240c61f3d84804d9b9a10e94a7c5c7c5c6420c3cc39511aca16d03e741857250ac110e810bf16a892e874a1a814a1cb3b412a9966feec8544cb40e7613e8a24262110060a4824c71f00159551143e0a17854b30eab370ee4252c9345dde8962a094034dc02c13a82e660540bfd789f00d66d5d7a2f0000f85421246007db1418686270e63f1040cf40f2309a218469101148d0d75883649bfd749a355f070136887ae3599443e9fca24085b255494d42030206b400281423198becca913e7696a9e3dee3d0e1ffa1cdfea43f90a451821144a24884424a1408454a6a009e50854001593ca2e0ddf4218a0642f3e3df8f4e21323430f1992346d6965cfae2378ae8b6980618094fad334c04da779f59583d80ff622a4442a0357c5f11846488f40c0c0f0ad62e15400e593aa494b640dc3c92b24e926647c71f27ab8a4336d1895d5888a0a9c7daddcb969d9a8f56fec3e41d9ac5eaa16b6319c062c9f041710b8943093442a4e49b4a6583869203d290dd48516e1a6143dc9765c06102283101920094682a47f861bbf7f8cb7df6a211060d478e7ed16563eb887bef4a7a482ada4e449a41c428814fd6e3bf1218fba50d1113d06c42463662a634ba959458dbf98ce9e182eddc455079eb88c1203e888e462547f8e8cc6683b7d8980c5c8683b7d0911ed255a3b44341c2620adab46576f3fd5fe224acdaa62e1284049c8561d454a73d9064e9ebe84ef2b4c29084828b12c4c61a21418840957c649a7d2571148a7d2442ae3044d8bb011c492e6c810485a4e76d25cb66132e063409f896e09d617bb7255cd66defbf45f1c39dbc6d7172ec5173e2849891922808987c7a29bdb78f1c55779fae973747474904824b0ac088f6e2fa7d488208424a95223f7fca4e314c3e7c3acfaeae66261784017d063a20be9a22a2f004b06b9a5fe11761d7e8a70c8e2a6b9cdf88097c910342d424232a7dea77c7598bbef7e92fefe412e5eece689277e48d785008be52c7c7c02c242293872f114073fe8e08efa6d5832582c812bc067c025097c0cf416bb126079ed469ad4663ef9e43c6fb51d22e5ba84cd10aeabf03c9fbebe7ece9d3b87eb7a24122962b12b249329841498d224202d5ccf63dfd98f79ff501b4d6a33cb6b3716bbbd025ac9f6914ce07de018ba782fba5d72d7c2adfce3688c131f1f20e6ee6741c56ce6471ba98a94b1702decdaf1323fff452b97baba79effd7dacf9e64c6effee720652c31cef6de7545f075dc752d4f5ddc45dcbb64ee6f90d031f02c76cdbf685e33855c08fd1457cd1be00bace7dede40b7c187f89ba9506c172418915a63e524d59204ac808208420e9a51974e374c57b18480f931a50741dce7063e47e6e5ffc3042141dcd7df493ff2df09a6ddb5eaea45c023c097c07fde26e527236d6c27f5bff485fc5712ae6494a1a24f21a8ff2333074d1a7bfdda7b2bf994d4d8f3277c692c96ef539b01d78d1b6ed2bf0454d6ca14d681bb09e020ead94eec3fabe3ff2ddf77dcec45a38dee970baef10c3c18b88a06ee5a8944134d5c082cad534d7ade3baaa66841023434aad815c093a8ef4022f00cfdab6dd91fb31bf2b11ca92f819baa935a2891c40cff3c8643264329991ebfcdf7cdf1ff9f4321e296f1880a019c19026524aa494188681611898a639ea3affb73c42bdc00ee039e06c7e27fb2aca594dac46b75636932d3373c05cd71d057e2c22f9649452236072c07240f3415f3bb2f37ca01ddda1fb1bd07e6d1b7eacce9c0416a2bbd0df43f788644e1339424aa91180f960af1df9a6913397dce7b523dfacd05db903c01f80ddc0e0583dd2899abba5596d6c41ff3bc13c2030defc1cc102765c8ca4d071fedfe83ed0845dea62daeb21740d7a1b7017baf15536d6dadc1387820e79ad64d0b9cd51f47b82d7b2c047f542af95a277c936c0ea809bd04ede8cd64a0d1021afaece371f20df2cf201a7806ee034701078139d15f415f35e60d204c620130166a29b02cd68bf294347afeaec752e5d1f00fad0a76827da313bd071fd02306cdb76d1697dbefc1ffac78389f05b587d0000000049454e44ae426082</data>
+ </image>
+ <image name="image5">
+ <data format="PNG" length="3020">89504e470d0a1a0a0000000d49484452000000300000003008060000005702f98700000b93494441546881ad9a5b6c1cd779c77f736666ef247779bf883789a2445117eb66591e27820d187563bb49dca66d90a269e016cd435aa00f698a3e358f8581064102a44d1e728f13b4ee356de2d8ae2dc16b39326999ba909248f17e2797cb5d72afb333270fb3bb5e4b247719f20306333b3867ceff3fe7fbbef39dffacc21e2d1c0e8bfca5340c43eed4f6d2a54b4aa1ede5cb978bd77b195f29df647b0b87c33ee069e0343000bc0344cb11d94fd3f6d8df0d1c03fe227fbc2a84b83c303030ea72b926a5941b1b1b1be9502864f6f7f7ef19ec56b6d719508053c0df039f0204602a8ab22e84589152ae00f7144509dbb67da5bbbb7ba6a5a5655f67674f04a0e8465f00fe16e8d8a28904c681abc06bc06b86612cec75dc8289f24dca5a0ab80e0cb375402ac021e073c05f01e7f233b72fb66702f9809d02ee01e932cd63f963dfdc683f66001c5073c066997619206318c63e0dbb7f04aa8156c0bf431b05380a9c0c87c39e7d1a77ef04c2e1b01b781c7802f09669de0e7c023855b200eec9f6f4907c067a06f8127092f2594d079e02be884362afebd06f9746c3e1b08e93593e037c16e805d45d3c22055c01be0dbcc51e56ef5d110887c32a8e1b3c8b03fc0ce5dd663bb381659cb5e187c0af81f86e03bc2202797f6dc471973f05ce03815d8db4bd59c002f00b1c22838661242bedbc2381fc82538d13a09fc7f1dfda72fd7e4bcb01f7819f012f03a3866158e53a6d0b24ef2e8770ca84cf016dec5fdaddc9523865c777805f016b3bb9d59604f279fae338d9e5492a74171b8b65fd1673aef7886953a48901e0a1869a5c276dd9f3349ac711e5e3dd0666801f01df07c6b79b8d870884c3e11ae0933875cb692ac82e3925cd88f73fb861ff3bcb333152f31a41bb1d3755a84227a36c1017b3684d491adb6b38295ea02ff5693459763d4b02af035f07de360c23bb2d81bcbf37e2b8cb17819ead083e680bfa752e6b2f317d7b85bacde39ce97a92ce8623a8e2a3295e4a9bd9c838ef8dff8a15ff0d3afa1bb894fb322de6e9724398c0dbc04bc0eb866198db1108017f06fc35d0b5ddd3ae5dfb8063c70ee376bb198ebd8da6ba585c58c0e37571e4702fba6be7b52995c83233358f8286ed4d622b691eadff24cbcb11262666b878f1cc56ddb238ebc54bc05b8661e43e4220eff39f02be82b341d9f6cd4f4dcd63db1691c04d0e864ef3e4d96730cd2cc37747189e799ffa4e0fba9ef7ba42c8dbce29b999c58a0638dbf728cd4dcd643219bef58baf12aaaba22e7686783cce891347b71b3a0dbc02fc2370b310d8229f6d2ee0bcfde33b8107686d6da2b6a19ac199d7d02d1fe9741acbb2e93dd44b4ff371621bebb85ad2f83a33f83bb2f83bb2f83a33680d49b249853347cf521baa259bcd22a5444f86189e7e9f9ec3ddb8ddee9d86f6e0a4f1e781fac24d8153457e1a30a8608fbcbcbc4a6b4b1b6d99c7585c5a249148924aa548a7d374b47540d2c3666689ac1225431c9324b692251649d2ecebc6e7f5934aa548a5522c2faf105bccf278c31f91b3326c6ec6cb0ddf9cc7fa44a18e123899e6712a4c9573e6102393433c75e6f7989a98676a7a8a64324132992467e608aaadc496b3486901596c9264ed3899b8458d3744329922994cb2b999e0fa8d218281067a3b8ef37fefbc423238596e7805e8c7a9083a0a042ee0146315d942fd15debcf753744da3a3bd8dab8361226b6bc5b76a662c32891cb9ac24b90a89a8859d9348cb2697338bed46c746b9333acc23274f303631cae0f2ff1069bc5609040f4e0dd61f0e878596ff5155494f53a698c95ec7173acce8c24dba5bfb48a5d3c4e31b98a64924bacad8ec2d6abc1ab11bb504451b9be9189bbe25d2d60677166fd254d34e4d7590f5588cde43bd486933ba3248638f9799ec07983285aeec581f2a3829fe02f0aec029172a2a11167377c8a4b3f4f675a1b4ceb09e88d0d773148fdb4d3c1e63e8ee00aaaad36c9ea6deee41c9b8a8521a68324f5295e8613936cbddc91132990ced6d6d1c683dc0bd999bd49f4871fcc41132e92c8bb93b9540a901fa80368d92882e67ebb905145ba5bdad098f9ec3bc1d45a8cd20c1ef0f70f1d425745d47da92743a4d2a9542d334bcaa87e6ea0eea036d481b8450501405336b92f3afd271c48369b5f0eea4603db740bb5e7671537002ba516317f57cc64ae1d1fdf8032ae424aa5747910a524a54a1e2717bb06d9b8c9966697d9ec5c418d5fe20cdca21825a2dbaaa217467b21545415515dc0189d06c7c6e81c7e52363a52a81a2004120b8ab2d9d6aeb08a162c575d4683bd54a3b9ad0904216412d47a7b913791dad6995cec782a84a8495e9fbacaf777330780197e6fbf0799a4aab3c467aee1eaefa04baaea2da7aa5708240cdae080444035df209eaa34f51a3b520fd1fae79524a84aa90884fd1f4d80435cd1a42383291bb41b23ebd848c1dc7ef6f2892955272d0ff0816fd4416c7f0c4af12a86ba8144e16c8ee8a40b3a797ba401badd54ed6b56c8bc8fa322892ba9a46344d2350e52755a521c487e48450f078dd04ac2a02fe00e94c92a5b5796a6b1af07bab505008691738e4be44b3a7e28cbe06ac69142b95f256a5d561ba5d783c1e669726b93df3166bda757cd550b7719ef3075fe050e3056ec707908145943c07cb54a897e739d0d0c3ccc204d726fe153b348977b59136fd123dcd67a9f2d553add553a5d5550a470252c351d57c651a176d6529cabbb7be0e7523d41f49d1dda422348554f432636b21ce75fd3eeb8b9f607ee3c7b8aa3348096abc9d1edf7398a6c9e0fc4f089dbb8f3fa421ad3956575e666ef632fecc199454c53024ce0c44058e2458b1656239de9e7f9948eb2d5a3a7df8bc6e3421f0d5daacfade60667584dec68fe18d9ec5ca829df4d1a13c4fd0dbc2afeffe1c77f70455751aaaaae0f5b868ea70b15017e695a17fa25a54ecff3960115815381be9b29be782757574f3bb7d7fcec88d250666eea2291a2ee142280a9ec618f736ff935ccee468f5f3982b4d0436ced1597d9ed1a91bac6a6f71a0d34b40f711d07db8848b5b0b130c0ecef074efe739d0da5e298c38300a2c09e0032052694f455178a4f169fae4730c0dcdf2ffe30398968557b85184c46ebcc3c8d21bd455b5d39efd0c07ddcf924ca4b9bdf0730e9e10f83d5edcaa0b3397e3cad407bc3b304e9f7c8e471a9f46512a123b2430425e47525f7cf1450d6759ee621772c9e1da738c4f8c3319bbc79c3e4bd6ce11d28204fc1aeb89397cd95e42ee2e029e208323afa2770cd2d8e62661a6195a19e39df99b8c0fc5688a5ce40f8e7d19a1542c782480ff06fecb308cb806dcc4d938f7012d953e45151a7f72ea1ff8e5ddef72edcacba4cf4c315a334d40f7d2e4aa2715f9114fd47f89fbb3130c657e8acbbdc0d5f108b16c824c4cb2f8bec5a3becff2cca92fa0540edecee37d1347d52b6e298f017f07fc21ce87bb5dd9d4da30ff3bf22f4483b709760b02ad0291f27262fd45265786891c7c132d20d99cb7599fb009adf7f36cdf5fd2597b6cb743dd07be06fcd0308c7829011d47fff90a708932528a944ee960db76f1b76ddb4cae0d737b21cc5874804dd73c981ab6b4102e9b40b68d9ed039fa9b1fa7abae1f45518a87101fd6473b5804f82ef00dc330a60b374b55094f9ec4dfe0885ac5992800cce5725896856559c5ebd27bb66d17cf392b47269700c0adf950858610022104aaaaa2aa2a9aa63d745d7aaf845004f81ef04d60aa54c9fe08e5fc4c9cc391569e23bfcd2c00334df321f05b11292523a52c8229002b002d05fde0916f670313380add0f80890765f8ad9439011cc651a1ff18273b89c24c140849298b004bc13e7894ba46c15d0ae7078f52b7c251e5ae02ff0cbc0a6c6ca591ee24ee56e567e3059cbf137403aeedda17085698cb77b20c4e9eff371c1d684795ba1279dd83b307fd1d1c4de6148ee4fe50dfc21b87b201f9a05938b5cd0d9cef04bfcc037f480b7dd02a1e252f803503177182bc1f67561a708ac162322f751fa0d42d4a01678015600c780f7803a72a8856f25d60d704b620e3039a7044817e9cb8a9c6c95ef5f96b81b3f8c48028ce2aba801398d338797d0e4818865171595f6abf0195fbdb69ad4333b80000000049454e44ae426082</data>
+ </image>
+ <image name="image6">
+ <data format="PNG" length="4642">89504e470d0a1a0a0000000d49484452000000300000003008060000005702f987000011e9494441546881c59a7b7053d79dc73ff7a1ab2b5d599225dbb2e5270f1b6303c10963f082dd249b92b4034dc2d06e37b3bb64b36c96d9b2dd364d9add3fb26da7e96bb2d3994c32dd769b6cb69b699cc78640023421601c1e31d824e6610cd8d860cb58b6902dcb92acf7bdfb8731216008a18ffdcdfc66a473757ef7f73dbfe739478261185c4d3b77eeac2f2a2afa422a95faf9f2e5cbb333e3636363984c260e1e3c88c7e3c1e7f3118d46191b1b23994c323636467b7b3b252525f87c3e62b118922461b55a0170381c442211d2e934e9741a41101045118bc582aaaaac5cb992dcdc5c0401c2e149aed6edf1c71fbf4657f9ea8196969655c01baaaa163a9dce3ce0c9eeeeee1a5555279d4ee7906118d708feff24f1ea015555bf5a545454180c064924124ff4f5f5fdd66eb7bfef72b93eb25aad7f250802aaaa92cd666793f727a76b00389dcec73399ccffe4e5e5e1f3f9846c36fb50494989d7e97416a8aafab2cd66db5257575761b7dbb9da1a8661a0ebfa9fd442d700a8a9a949a7d3e987dbdbdbb7ecdebd9bdede5e62b1d8271344f1c19c9c9c439aa6fd9dc7e341922400745d172449925d2e17b22c5f063103f24a4610fe6000ae89018083070f169c3d7bf68e0b172ea0280a168b85fafa7a6c36dbf42459f6d86cb617344dbb5f55d5c7e3f1b86e3299feb5b2b2325d5151b1e9a38f3e42d77544717a7d32998c60b7db0dabd54a3299241d8b611806822020fc9e60660560b15882555555e7ac566bf9c993271104015dd7a9afafc76eb7934824c866b3a8aaba766262a2b1a2a242acadadb50f0c0cf8fd7eff331e8fc7eaf7fb970f0d0d2d5055355fd7755992a46c555555b0b3b3b3676c6cec882449dd8661c47fdfa4302b80cd9b37679b9b9bffc5e5727d108fc7cd274f9ec46c3663b55a59ba7429822070ead4298e1f3f0ee00c87c38442213c1e4f614141c196fefefe92a2a22257454505332e356311b7db4d2412898642a14e5dd7b76a9af6bac9641a02d075fd7303106e84feb5d75e7b2e1e8f6fdeb9732773e6cc61e9d2a52c59b284c9c949b66ddb46201040922456ae5c494343037ebf9f63c78e214912252525b8dd6e5455451445745d4792245c2e17a9548ab7de7a8bd6d65646464606962c59f2efa228beb478f1e298a669489244381cbeb53a70254522911f389dce071a1a1a4afafafaa8afaf67707090e79f7f9ed1d151aaabab59b76e1df9f9f9fcee77bf2393c970db6db7e174b9181654ba2d394c48225386882808b83415afa2b2a840e11f37ff138b162d221289945f181e7ece6ab1dc9b9f9fffcfe3e3e3fd9f2793dd10c0c68d1b834f3ffdf4f71a1b1b5f1c1f1fa7afaf8f7038cce8e828369b8da6a626cacbcbf9c52f7e81dbeda6a2b28ab3ee52ba3013f08d121f2ec6a93b31039208fd024c8a09644f07de395ebe587f270fb8ac089914e17078cde0e06099a2281b42a1d05141102e07fa2d0300686b6b7b299bcd3e74f7dd77ffb9dd6e67f5ead500fcec673f63cb962d0c0c0ca0280ab69aa57c5cb9045f772feee87ddc593187f2fa69c5af24c350191a5b41471bbca0bd4b6b5d2d1b4af2f14a121e8f6789d96cfeaddbedfe0b9bcdd6353131f19900aea90357d38e1d3b8ca3478f3e95cd66f59a9a1a9e7bee393a3b3b8946a3048341fafafa90ef5849576121befd65dcebb98ff52b606e214812207c9a05114af361dd72585d701fbdbb3dfcfcf8513a5222a22862b7db6b5c2ed77f7abdde8282820244514492a4cbf5e6735b00e0a1871ef23636368a5bb76ec5e7f34d4f9465f2f3f3519736e0cb2f463fb982bf5c0136335c934b6696e9aa07e505f0f51c85373f5ac16fe28778a47a1e7333092c164b433a9d7e229bcd3e218ae20dad705300aaababbf954c26696b6b43966532990c05050598bc15c46a6b49f5d6b3ae0e1413a47490ada05841b680287f52780d03f40c6412909e82540ccc66585b076f75de4eb3d2c9a3a55e5ca93876bbfd1f52a9d49b1e8fe790dbedbeae6e9fe9424f3cf1c45d0b162c5875e4c8112a2b2b71b95cbcfffefb64b35994bbee65bc4fe6ae8522b20c82065a294cb92168065d065d802cd3ac0b8009e41cb07820a70c241b9815f842b5c2c8e910db4331b2ba4e369bcdd1346d633018143b3a3a3872e4c8e703a0aaaae272b98a9d4ee7238aa2200802ddddddbcfdf6dbc8b28cb5a69e84e4a42a6f054e1b6845a079403041220b5f714faf783039ed39b33132580b20a704f273616eee7d9cf64d70366d26994c62369bbfa4aaeafc4c26433c1e9f554f19c06eb75bcacaca8a172c5850d6d4d4f485dadada556d6d6d65b22c17abaa6a492693e8ba4e7b7b3b9148049bcd86f5b61ad213452c58008e5230a99fb8b8ae8322c26a17f8e2b03f341d1be6d9e310d902b9a5b02805bed3457446c728b34a288ae29565b949d7f59e482432fbdc1ffef087dfeeececfc7645458547922465e6412693e1fcf9f3389d4e0cc3e0ecd9b3463299144c2613b2c58654984741b69cbc1290d54fc76756072ed5a1520b7c5d854363d01385026df6665454c05306dee172ce8c9f2661f660d175144559a528ca8ba228ce5ad9c4471f7df4fe79f3e6955ea9fc95202c160b994c06bfdf7fb99fb1965691cd989857029afd5aa1c655d94614e0cff2e08102988a4238398def6a366b50590e89b8812f0ee9741a5114cb5555b55daf4f12272626f44422413a9d26954a914aa5c8643297aba0288aa4522942a1903003c094eb40d017525c0486300b5fa727732ab0be14169960641cb206d7d489522f087a29113d43269341922487aaaad6d925827ce0c0014e9c3881d96cbedc7f689a86cd6623954a515e5e4e3299e4f6db6f37babbbb85f1f1719014549317cd36cbea331d0337a2452ea872c07b3ee8d6c1ed0087086611ac565095f99cead9c6aaa63a42a190796464c474e5a6ea5300f6eddb274c4d4d61369b01902489a2a222162e5c485d5d1d2693095dd7f1fbfd241289e9ce329d419404e459aa883083e2337a314582b515b068027e3300c525902f4e07bfa2480c0ffa18192962efdebd86c3e1101289c4ac72444dd332e5e5e5783c1e1c0e07a228e2f7fb397ffe3c797979489284aeebd4d5d5a169dab48b8503c4124748e85ce302dcc085aea6d3417867184a8ac12442cc8034104f46191feaa3bfbf9f542a95080683993d7bf6cc2a430a068327044198d4342d5c5b5bab2d5fbe3ce7b6db6ea3acac0c4dd370b95c84c3615c2e5776f1e2c5627b7b3ba9a924caa2524acb1763514016a633cb0c872250970bf275aa4c2c055bcec04901dcf9609240ba34772a03c7baf632b16f17de02373939392743a150339058b76edd35b2e473e7ce1d058e02d86cb6c28a8a8ae585858535555555cb2b2b2b1befbfff7e97cd6623100808f3e7cf377ef4a31f095bb66ce1f860007f105c1a648ce94c03d3c52b91e5ba2e747800daa3e02901cf2c007d63901aeac5ebb2210802369bad37994cc654559d55dea7bc381a8d8e00db2e31aaaa969f3e7dfa5d8fc753bd61c30651d775c3ed760bf7dc730f8143473973768285a54ecc574a11662fef1723b0bd0f4c455096373bb88c0edd67e264cff761b7db31994cd95028b42f9148a4474646669d73c35e2891480cf8fdfed7df7df75d8e1f3f2e489284aaaad86c36d62f5b4a72f8553a07a6fd57913e61e98ad5d70dd8750ab65c80c205d319e7cadf5ec92787c0dffd3cdad8c8cc76542a2f2fff567e7efe7753a9d42c15e7269ab9fefefef7e7cd9bc789132718181810144531dc6e376693407d4e015d1f3773c4371d07caa52c326390fe5178e123487961fedc4b8a8ad7b249802e3f741c6ec6e99f606e7931aaaa525353c3dab56b5758add64d3e9fcf744b00bababa0e64b3d9edb22cd3dddd2d0c0f0f1b0e8783e2e262f25221921f1fe3d8b17769e93788a7a615920cd8fa31b44dc1c2a5e0d066575c11219d817d0370e8c8bb88a77b6928cf63d9b265545656525b5b4b4f4f0ffbf6edfb8f0b172e8ccda6df4ded07262727778d8f8fafa9acaca4a3a34358bb76ade176bb85542a45ce703fd1c3594e67603cbd82f94e27f30aa1c006a659d76c9ac2493839063da118235dfb114e1fa2b1c0494545392693898a8a0a6459a6a5a5c5181b1bdb7753413c1b298a627bf9e597ffc6e97472f0e041aaabab85f6f6767dfefcf99c397346c8b1597186428cb5b7713e7896c41d77d1ebb061331552643563574095a65364220391348c4ca509a7864986a38c7cb497eaac9505851e4a8a8b5114054dd3282b2ba3a7a707afd72b343434fcbda669876f09c037bef18d27d6af5fbf6c70709063c78ef1e1871fe2f178c4783c6e2c5ebc988181012291084e31ca94cfc2c0f01b087317e09c338798b708f1aa165acf4274d8cfc4b97364ce76d350309745e53998cdd37b004551f07abd24120992c924535353dc77df7d8f8c8c8cbc06bc7fb57e373cd8aaabab5b7ee0c0810fac56ab391c0e138d46f9d5af7ec57befbd476565252b57ae34f2f30bf0fb4785683486ae1b489289b06ec69f8a7251cf90ce7122aaae69e513e3a853110a4d2a8e8c883747a2b8d88ba65988c5a2288acc9c397300839e9e1e1445e1d5575fe56b5ffb1a4343435dbb76ed5ab97dfbf6c99bb280288aa6d6d6d667344d3303389d4e244966cd9a0770bb8b292a2aa5b3f3b8303818362a2b2b0db339234c4dc5c864740a248142cd8c2ccb08a248321bc3d00dac7627a22397787c0a5114309934e2718189890914452127278f6030c5f0f0053c9e420281614a4acad8be7d3b0f3ef8e0a2850b177e1bf8c14d0178ecb1c71e6b6a6a6a9cf91e8bc5e8ed3dcbd0d03077de790ff1788ac2c2620e1d3a245cba56320a0b3d489220e8ba81284ac8b20945312349068944145d57309bcd582c1a89449cf1f1317a7b2f52513197bc3c37f1789240e022cb962d232747c3307414c54c3018a4edd021162d5af4cdd5ab57bfb16bd7aeee1bbad0c2850b6f3f70e0c05eb7db6d0788442274747470fcf871e2f138fdfdfd58ad361e7c701df9f91e464783b4b51d26181ca7b8b854f7780a85dc5c17369b1545510d93c924c4e309e2f12921168b323232caf0f010f17882c58b6ba9aeae24954aa0eb19bcde428a8b8bb05a2d0402a3b4b6b6f2c1071f303c3c4c7d7d3de170f8cde6e6e6af0e0e0e1ad7b5c08a152bee9a513e1a8dd2d1d1414b4b0b3d3d3d00343434d0d8d8c81b6fbcd1d3d2d2f2bf0f3ffcf09af5ebbfbc24180cf2f6db6f8b79790ab1589c8e8e6eec763b8090cd668dc9c9497c3e1fa150887befbd97a6a62f118fc779e595ffdad1d9d979f4c73ffef1a6aaaab997cf503c1e0f4d4d4d00b4b6b672e4c811cacacad6381c8e25c0b1eb5a4092a4bc679f7df6c5471e79e42b870f1fa6a5a58513274ee072b958bd7a359224c57ffdeb5fbfb867cf9e67745d1f1404a1a0a6a6e6cbebd6adfbeb152b56d4070201db810307387af4e8e593e9dcdc5c4a4b4b71381cac5ab50ac3308677efdeddb263c78e57868686f6020997cb75fb4f7ef2939f6edcb8f18b33972300c3c3c3ecdbb78f3d7bf6100804f6747676ae191c1c4c5c170080a228b99b366dfa8ddd6e5fdbd5d54565652577dc7107478f1eddffd24b2f7d2f1008ecbd8ef5bef9c20b2f3cebf7fbc966b364b359a2d1281e8f87fcfc7cc2e130fbf7ef3ff7e4934fde0bf4ce22c2b266cd9a879f7ffef97f2b2f2f2f9c19eceeee66e7ce9dd4d7d7b36bd7aeef3efdf4d3cf00b3df61cdb02449aee5cb97eff8ce77be637cfffbdfbf505f5fff4d409b15f1252a282858dcd7d7179f9a9a3292c9a4313535657cf8e187c6ebafbf6e6cdebcd9d8b66d9bb179f3e61d379201909f9fbff097bffce59b86611863636389575e79e5424b4b8bf1f1c71f1ba74e9d329e7aeaa9ef1a8671e34296c964c65555dd188bc51e3c77eedcee582cd6f3592f0e8542fe582c16b0582c6500894482c9c9494e9e3c49281442d7754e9d3e7de8b3e45cbc78f1d4a64d9b1edab265cbdf8aa228b5b4b4b46eddbaf5bfed76fbb2d1d151ce9c3993066e6c816b6e176f92de79e79d3dc6258a46a3c6abafbe6a6cd8b0c178f4d1478de6e6e6acd7eb5d79d3c2ae2087c351d5dcdcfce1dab56b9f9cd1e9a69ab9cf4badadad07d6ac59733770f98230994c525252422412098c8f8ff7df8adc8989891e5114bf6818467266ec8f0260fffefd07673e5f79cb62369be9ebebeb4a2412fe5b95adebfaa7ce573e733f702bd4dbdb7b3610088cc3f431cdcc75513299e4f0e1c3bbff90effaa35820140af9b76edddaded8d8784728144af6f7f7138fc785a1a121a1a7a7a7ed0ff9ae1b76a3d7fcf873dcaacbb2ec9065d9c127e71382aeeba9743a7dd1308c5bfaa7c86cbafe1fb85a1e157b8593e90000000049454e44ae426082</data>
+ </image>
+ <image name="image7">
+ <data format="PNG" length="4640">89504e470d0a1a0a0000000d49484452000000300000003008060000005702f987000011e7494441546881c59a69745cd591c77f6fe97d6f2ddddaba65635992651be44d36c8c22c61496c089cc0640f9b0732101298409299099904b29c432667189819320927246430e0c4c1601bf06e2ce105cbb28d25db9225599225596b4b6a75f75377bf77e7836cb02d793d24f33fa73edc2bbdbaf57f55b7aaee7d2d0921381befad5dbb203b37f7da6432f9ab8a8a0afdd4fcc0c0002693899a9a1a0281001d1d1d8c8e8e323030c0d8d8180303fdecfcf043860bbe8e52af911a3b8a243bb098a690b00e62f665417f1a25354c321d03ec2832c8d65c0c4f82f94bca190aba28d0f2d92cad404603e48feddabd7cf9045bd5b327b66cda5c09d24abbc51af47abd99c0f70ed537ccb0da6c231eafe7b81082c948ff7f413e7bc26ab5de15ccc9090ef40f90d4b4275a9a5bfed7ed766ff0fb7db576bbfdab922461b55ad1757d327d7f734c20e0f37abe9bd6d37fc8c8f473bcbd4332d2e92fe715e4e77abcde6cabd5fa8ad3e95c555e5e5ee876bb39db1b4280a1eb7f530f4d20505256964aa552f7ecd9fde1aacd1b36d2dc7494782cfec903b27c87cbe5dae97438ee0f0602288a0280611892aa28aa3f23134535811048184842471220848e3004920049faf4084ed803001f547f90dddad434b7eb782766b309abcdcabc8a0a1c4ec7f843aa1a703a9dbf753a1cb7dbacb6ef6af18461369b7e30bde88a547e61d943afd4fa88122125f9d15189a755c962cb1116879d643c863ea220090324c6e5d32660b559fba71517b7daedf6f0a1fa062449461882b915f371b9dd8c691a86ae63b558970d45228b0ba714ca656565eef663addd077a3ccf16045cf63d996315ed47ecc58ad39a2529a801c5ab9794e5f5d7ed3cd618ed4aee719a9506aba427ac920186002ecf2b9312f8876f3da2bffeea8aeffbfdbe6df144c272a8be1e8bc58ccd6e6756f995c892cca14387d87fe0001278478647880c8e9011cc093a82a155bd2dd17c7b28c73f6f7a1efe4c3b66554637049a22a304b2188988d19eeee13a979e7c33c3a7bee1f5715c46410803e9123d229d6fc3fde9b5d79fd7128947de59bb8e29530ab9b2bc9c99b367311c8df2d6ead5f4f6f4222b2616565ecbecca1bd8df6366ebbe21ccb2a0a4c04d30c38ec3a2a0ca12694360560c72fd0af194cef3ab8eb16eed516247236df3aaf27ee950b4df9595e7c77afc0ea624436ce632ebc0e9188e467f9ce1f57ebee2ea45f92dcd2dcc5b309fb6f60efef385e7e9ede9a5a8a48c5bbff055c8b98a5fbddb8f9e8a72c3957e4c59367a246836eb24d19190b02950e232e1702a5c693353f64809bf9b9dc5f04822dcdf1e7bde67936f7607eddf4e0c275b846e201481e0c2a1755e02f72f7fa0ff674f3ff3a3aac58b5f1a1c1ce468730b23c3c3f4f5f46271e672d592af63be62218f3d57c794a08dd26b82ecf5a41968394aa26b2a5ec3890550641893a0564ea2061ac89912e433b91eee5f9281cb2cd16b40ef304b5bdb1221d7f1f8373a22f17db2a6a00805a40989f20c9c378400967df673d2c2050b36545655dde0f2b89933772e2b56aee3473fdc8f129a4fc17579242d12458b7df41d692263b492398510ce1a37fc740801c707e0c316e8735433adbc84af4df1916f55e88bc248020622a986bea8f677273ad307a55e09217f62df93cb7d13ec3b3f3de0ed756bc5de7dfb7e98360ca374c60c9e7ffebfd8be3749537326874f0c336c1714cc49d1f7412637072af9c242981a0445e19334795224190ab2e0ce0ab829bb92a68d5efebdb6815d91311c165025f0b94d33f27c8eff999aebcace0a78c84cfac84c8dcb64b8200180bbbff295dccac595f2db6fada5a9b39748321f1c268a964d656aa94eb261165f5aa810ca0283b3443e2967cd87b3e18b0b54a2fb67f14a6d23f5d1240e2b2475b0d9e4457697f1842990221d16e861d0c393db76de3d700aa525c5df498e8db17dc76e86e41b194aa9e4dd1862ee128564d32cee2c07b3099206a87630db41b581acf2715a14028c34a43548c52119038b059695c35fea4a79dd7298fb4a4bb0a82a310d7c6ef383ba96fcb3366f6ca71eb49eb3de5dd003df7de2c9eb4a8a8b2bf7eca9a3a07826767f88775fae65f61d01469a25ae2b055505c9018e02b007417503263024d01917431a9f535d600b802b048a132c66b8b644a5e7d010ef74f5a1caa00b4819b8ec2ef50177bb244b9b3a90b6b45f1a01abd56af6fbfd797eaff73eb3d94c52b6b07bbf9f95bfff88822521ec7683e999b3f03ac191038e0048a64942e81c820af66c70e543960fa6fa2a696ceda725964295213e06568b74abc32aa625d30aa7b563674005f0b8ddb6825028afb8b83854555575edccb2b2ca5d3b76841445cd33dbac366d2cc9b0c864e3faa30c77c698fdcd5c5243018a8bc1530026ebb851fd7138119b7ca1b3939d4986e28cf150f315c0cc24741c0ef0d16027376415a225c16692726593a9ca95d41b9343bd40682281679e7efab1bababac7c28585014551cca7fea0a7d3b4b51ec3edf3602053db9c10c3c3425233ed64141a648b6c32f3413d693c40d30094bb21683f975f3fc1ca160879c06a02d90c8110e47665d3dcfb01d76684490b09dd008bd9a834cc8197d27aeea4f95e7d70f9dfdf9e150c144c7863402a9dc66eb3a1a505473ac703d33f3b030c892b0ac0e13ef3194387191e28f25e98c09a56cea8b316071485a1e69841249d229536a3a5c065266c76249ca352220ac1097ae4c8d09031a669a4532952c924a96492743a0d022459469665122983130386849ec691292119d3c9cb01219d25e989a1722e88d449e34fab1305b92019f9acd9de826a1a4fa966058fdd2aec9a6c9a548fbaa3ba9afa8f3ec26ab17c7c92b23b1c389d4eb46492703884a6e92c5990299a3f0c48b245c16acac0e19ca8ccd0b9e8ae584f43570a9c327864b0c860b783d59c47f5962d58343b777d2e445744b7b4f58c9a1ad21a903191c0f66ddb242dae61b15800901599604e0ea5336630bbfc2a54938a30e23474a5898eeab8d22ab222a14e52410ce3e23d60a4010952c0800159329865309b15741d6a6b3ba99893c3eb9bba44be2f2e1d4c2727d5233b1dce74381c263b10c0e571832cd375a29bd663ad646665a2282a18696e9eeb22d36b21de1325a6d5a3194c6815c4257840a4c0248d1b6d922126c6c924c6122492298e36f7d3d83c484f12adbb7f303dba6acfa47ad4d5efbdf3c4ccd2195f2a0c87679695955d5550909f6b3299511485d8e8284218284692c5d3acbaf3e757ab8ffe730d49ad857e6d160107984f2b91860ec298749d09d0f5936ffcb44a34948258742f435d3afa4882c35d0982d9b641ad339a484d8b4e4ea0b5b5751fb00fc0e97406a71416560403c119c5d38b2a8a8aa62f5efaf9dbfd2ea79bdebeb834735a8ef8b75fde2cbd51b381ee7ef03b202d403e49229de6b23c700a1d03d07f7c8831938cab3883986222e44c36356b46cc629a9028c7099c3e181d1d3d01ac3e2958adb670c39123ef06b3b34bbe78efb7644dd7453843958a72a772e4688cd2020796d334884bd8037a7abcfb349d249036a0e1c8185d2d124adac0e573229b54dd186c7adf9b684e19dd0dc0dde7277036342dd176db6db7bdb1bf6eef53b3e72c944a17dd245c16985d308d35752ba96bbb9bc5459f346c7e173cf3eec473c064488b140e8b09d3f8ad0cfbdbe158c3eb1c3fe8c79a61c393954189b54399e78d7fe7c8405f786f6bf38bc0c8251100686e69d970e5acd94f351cd88b2f5828654c9b21a6644ad215998b38b8f72d6cd6db58141e0fa3abe78ccbc5613caf0b01755df0e1aeb738d696474e890d4f860bbb5de2ba522737cd9db1f0b9c6bd81b68eee9726d372c177557ff060755ad7d7a8aaccd1fa3aa9ff7887c8f4c08d5716a0445cecdf5fcde61648243fd994172ba934bcdf063bf75433d46e42d7dd2c9a9bc3f50ba7b074bac682d23c9a8e34b26dfbf6ffeee8ec1cb82c0200232323eb0723117c1e2bf5bbab25c530449e1f321cc51caa3ec2e17dd5bcdd1263671744c72e6c7822057b4ec0eae6041fd556233a7b31c45416cdc8a2684a0e85ee116e9dedc6aa186cd9bc590c0c0cbcef359b27b5ed822164369b9d7ffcc32b5ff77abdd47c50c3f492d9d2c19def1bce9225bcd5909086225791dcd1c3d4fe95687397d014b5e334f9c8b19b709bc1aa8cef112d0dd1149c88eb0c2707181b8ed35dbb95f8408885336fc4e38812cacfc26b1e65ba35c2b4fc425a1b0f919b9b2b5dbdf0eae58d16ebaecb22f0c8c30f3f71f75d77cd6b6b6b63ff8103ecaad94a46302cdb936eb170ee953434f7a18db868699b4aa4730bd95764e09d3285586e0059395397a1c368570f43adad443b86e88a5530a7c88bd524c82b08124fc628513b280afa486b31346d0c2d1ee7b3b7dc725ff789eed7810d67db77de5b89f2f2f28a9aea9a6d76bbdd323c34c4682cc6af5f7c91f5efad27bf781ea1aa2f8991c03534756a52221a45320c14631429d984647461719950ade3ad695a1b42c4d3789d61547b313d31132eab4c71be0babc34a323ec834f918730bed980c8dc6238dd8cc165e7b6d0577dd7d379dc73b0faedbf0de356bd6ac3923139dd303b22c9bb66eddfaacdd61b700b83c5e90546ebdf50e7cde02823979ec3a502ba55a5ac4ac92eb44bfd52e454705a44d981dd331a9d331a93a92141fef34acc538022a26248613490add26148b84914a90eaee20a4f453906d233618a3abab9d405680be9e4e42f905ac5bb386dbefb863665949c963c08f2f8ac0e38f3ffe785555d5e253e3582cc6d1c6663a3bba58b2e47a6289048160901dbbeaa4831ffc0177a84c64e64c236db24986a1a3ca3a56b381dd6c6056938ca555d2691d8f4dc699548827a224fa7b881c6a6456d84b7e5e36e9c4301d3d232c98bf00b7c7463d0616733d837d03ecdab193d933673d7acb4d37ad7c77fdfa86f312282d2d9d53535dfd4fa7c6a3d151f6eedecdc1030788c7136cd8f0160e878bdbeeb893db972da1a2a78fea9dfba4cefa567cf945862b77aa64f3676077dab09865a15a14694cd3d1e249491b8d21453ad03b9a30c5075938eb0aca4a0a498d69184262665919b9b91958ed5664690691815e8622431caeafc7e970f8cbafbaea27e150f8aeb6f636714e028b162ebcce9f91e106888dc6a8ddbd9b6d9b36d3d4d8882141c5a245542daee28d956f346ed8b2f94ff7dc73efd22fdf75c3ecfefe0156af5e2be7f847310db939b8e3080eb70721499248a7c4e8f010dd1ded44077bb9e5e6eb595275235a22c11f5ffdddda7d7575fb7efed39f3e3475dad48f9bfeec6080ca6bab00a8deb295ba3d7bc80b85967a3ceed9c07e38c726561425f33f9e7beea5fbeebdefb60f77ed62eba64dd47f7410afdfc78d37df84aaa8895fffe6372f6dd8bce959c330da2549ca9e31a3ecb377de79e7d7162dac58d0d7d3ebaca9aea16e5f1db2ac6018063e9f8f7041014e8f9bcac5951842746dd8b871f3bab56b5f3d7efcf81640f3fbfd737ef1b39fffe2fee50f7c46963f295127babaa8deb69d2d1b37d2ddd7bba9765fddd2b6f676ed9c04004c6693efe107bff97b9fcbbdace1603d57144d63eebcb9d4eeabdbfed2cb2fffa8b7b777cb39bcf7e86f7ff3dbe7ba4f9c40d775745d67341a25100890959dc5f0d030d5dbab5b9ff8fe9337034d93a8b02d5dbaf49e175e78e1a97038fcf121f8707d03efac7b87f915f359ffdefa277ff2d3679e05f8f843dd64a2288aff9af9156b7ff0d83f8a679efad7ce8a050b1e051c93323ee5f6ecec59adcdcd092d1e17c9b1319188c7c5ae9a1d62d5eb6f88ef3cfc8858f3e66af1ed871f597b3e1d00595959a52fbef8e29f8510627060505bf1eaab9d5b376d16fb6a6bc5918643e2a97ff9e1934288f317b2743a3d68b35a1f1889c7ee6839d6ba31168b355e68e14824d23d1a8bf55a6cb61080a1698c8c0cd370b09ec86004c33068387c68e785f4f4f5f51d7ae8a187befc9755abee956459d9b479d3d6d56fae7e39ec0ecdebe9e9e148e39114707e0f9c2d178bb7df7e7b933889d8e8a858b9e235b1fc6bdf100f3ff0a078e3d5157a5e6ede3517adec34783c9ee9afad58f1c16dcb967def944d1775b97ba9d8b6755bf5d2a54baf074092108641726c8cbcfc7ca2d168efc0e040cbe5e81d1a1a6a9465f9334288b153737f1502ef6f7fbfe6e38110274f3c12168b85e6e696839aa6755fae6ec330ceb8bcbca876fa52d1d4d474b4b7b7771040511464494288712fecd8b573e3a7b9d65fc5039148a47bf55fdedcbdb8aa6a6e243238d6dcd2423c9190da8f1f971a9b9a767c9a6b5df01bd919ff7c091f715555f5a8aaeae1e43d850049184632954af509212eeb972293d9fa7f576314f818f93bfa0000000049454e44ae426082</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>downloadTor</sender>
+ <signal>clicked()</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>downloadTor_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>usingAnotherProxy</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>usingAnotherProxy_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>monitorRemote</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>monitorRemote_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>TorLocation</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>TorLocation_textChanged(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>torStartsAutomatically</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>torStartsAutomatically_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>downloadPrivoxy</sender>
+ <signal>clicked()</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>downloadPrivoxy_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>pushButton1</sender>
+ <signal>clicked()</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>pushButton1_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>pushButton1_2</sender>
+ <signal>clicked()</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>pushButton1_2_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>pushButton1_3</sender>
+ <signal>clicked()</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>pushButton1_3_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>WizardQuickConfigure</sender>
+ <signal>activated(int)</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>WizardQuickConfigure_activated(int)</slot>
+ </connection>
+ <connection>
+ <sender>modifyConfs</sender>
+ <signal>clicked()</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>modifyConfs_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>testTorAgain</sender>
+ <signal>clicked()</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>testTorAgain_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>torStartsManually</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>torStartsManually_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>pushButton6</sender>
+ <signal>clicked()</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>pushButton6_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>RemoteTorAddress</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>RemoteTorAddress_textChanged(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>modifyConfPrivoxy</sender>
+ <signal>clicked()</signal>
+ <receiver>FirstRunWizard</receiver>
+ <slot>modifyConfPrivoxy_clicked()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="global" impldecl="in declaration">kprocio.h</include>
+ <include location="global" impldecl="in implementation">kprocio.h</include>
+ <include location="local" impldecl="in implementation">newfirstrunwizard.ui.h</include>
+</includes>
+<forwards>
+ <forward>class KURL;</forward>
+</forwards>
+<slots>
+ <slot>monitorRemote_toggled( bool remoteTor )</slot>
+ <slot>usingAnotherProxy_toggled( bool state )</slot>
+ <slot>torStartsAutomatically_toggled( bool state )</slot>
+ <slot>torStartsManually_toggled( bool state )</slot>
+ <slot>processWhich( KProcIO * whichproc )</slot>
+ <slot>downloadPrivoxy_clicked()</slot>
+ <slot>downloadTor_clicked()</slot>
+ <slot>accept()</slot>
+ <slot>reject()</slot>
+ <slot>WizardQuickConfigure_activated( int item )</slot>
+ <slot>saveNonAnonymousProxySettings()</slot>
+ <slot>saveAnonymousProxySettings()</slot>
+ <slot>TorLocation_textChanged( const QString &amp; text )</slot>
+ <slot>pushButton1_clicked()</slot>
+ <slot>pushButton1_2_clicked()</slot>
+ <slot>pushButton1_3_clicked()</slot>
+ <slot>testTorAgain_clicked()</slot>
+ <slot>testTor()</slot>
+ <slot>modifyConfs_clicked()</slot>
+ <slot>cannotContactTor()</slot>
+ <slot>contactedTor()</slot>
+ <slot>examineConfigFiles()</slot>
+ <slot>pushButton6_clicked()</slot>
+ <slot>rootifyNetstat()</slot>
+ <slot>sighupTor( const QString &amp; text )</slot>
+ <slot>appendControlDirective( const QString &amp; text )</slot>
+ <slot>RemoteTorAddress_textChanged( const QString &amp; text )</slot>
+ <slot>modifyConfPrivoxy_clicked()</slot>
+ <slot>examinePrivoxyConfigFiles()</slot>
+ <slot>appendPrivoxyConfig( const QString &amp; text )</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+ <function access="protected">showPage( QWidget * w )</function>
+ <function access="private" specifier="non virtual">guessDataDir()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+ <includehint>kactivelabel.h</includehint>
+</includehints>
+</UI>
diff --git a/src/newfirstrunwizard.ui.h b/src/newfirstrunwizard.ui.h
new file mode 100644
index 0000000..32d33a4
--- /dev/null
+++ b/src/newfirstrunwizard.ui.h
@@ -0,0 +1,770 @@
+/***************************************************************************
+ ** $Id: newfirstrunwizard.ui.h,v 1.29 2008/12/08 19:39:02 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "torkconfig.h"
+#include "update.h"
+#include "crypto.h"
+#include "torclient.h"
+
+#include <kapplication.h>
+#include <qpushbutton.h>
+#include <qpixmap.h>
+#include <qtimer.h>
+#include <stdlib.h>
+#include <kstandarddirs.h>
+#include <kurl.h>
+#include <kprocio.h>
+#include <kdebug.h>
+#include <stdlib.h>
+#include <dcopref.h>
+#include <kconfig.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <krun.h>
+#include <qvaluevector.h>
+
+#include "functions.h"
+
+TorClient* client;
+KProcIO *whichproc;
+bool torRunning;
+bool privoxyRunning;
+QString tor;
+QString privoxy;
+QString netstat;
+QString torknetstat;
+
+QString OriginalHttpProxy;
+QString OriginalHttpsProxy;
+QString OriginalFtpProxy;
+QString OriginalProxyType;
+
+QString KonqHttpProxy;
+QString KonqHttpsProxy;
+QString KonqFtpProxy;
+uint KonqHttpProxyPort;
+uint KonqHttpsProxyPort;
+uint KonqFtpProxyPort;
+
+QString OriginalCookies;
+QString OriginalUseCache;
+QString OriginalSendUserAgent;
+QString OriginalEnableJavascript;
+QString OriginalEnableJava;
+QString OriginalEnablePlugins;
+
+QValueVector<QString> descriptions(6);
+
+void
+FirstRunWizard::init()
+{
+
+ torRunning = false;
+ privoxyRunning = false;
+
+ descriptions[0] = i18n("This will run a client and an exit server with Tor's default settings.<br>"
+ "An exit server carries the can for traffic leaving the Tor network.");
+ descriptions[1] = i18n("This will run a client and a relay server with Tor's default settings.<br>"
+ "A relay server carries traffic along the Tor network but does not transmit"
+ "tor traffic outside the network.");
+ descriptions[2] = i18n("This will run an exit server with Tor's default settings.<br>"
+ "An exit server carries the can for traffic leaving the Tor network.");
+ descriptions[3] = i18n("This will run a relay server with Tor's default settings.<br>"
+ "A relay server carries traffic along the Tor network but does not transmit"
+ "tor traffic outside the network.");
+ descriptions[4] = i18n("This will run a client with Tor's default settings.<br>");
+ descriptions[5] = i18n("You're too clever for your own good.<br>");
+
+
+
+ settingsDescription->setText(descriptions[0]);
+
+ setAppropriate ( CheckNotUsing, false );
+ setAppropriate ( CheckUsing, false );
+ setAppropriate ( NonPrivoxyConfirmation, false );
+ setAppropriate ( Remote_Tor, false );
+ setAppropriate ( Locate_Tor, false );
+ setAppropriate ( Locate_Privoxy, false );
+ setNextEnabled ( Locate_Tor,false );
+ setAppropriate ( TorServer, false );
+
+ TorkConfig::setUser(getenv("USER"));
+ const char *paths = ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin";
+
+ privoxy = getFullLocation(paths,"privoxy");
+ tor = getFullLocation(paths,"tor");
+ netstat = getFullLocation(paths,"netstat");
+
+
+ if (!tor)
+ setAppropriate ( Locate_Tor, true );
+ else
+ TorLocation_2->setURL(tor);
+
+ if (!privoxy){
+ setAppropriate ( Locate_Privoxy, true );
+ whichProxyText->setText(i18n("I did not find an installation of Privoxy on your system."));
+ }else{
+ PrivoxyLocation_2->setURL(privoxy);
+ whichProxyText->setText(i18n("I found an installation of Privoxy on your system."));
+ }
+
+ serverName->setText("TorKServer");
+
+ KConfig emailConf( QString::fromLatin1("emaildefaults") );
+ emailConf.setGroup(QString::fromLatin1("Defaults"));
+ QString profile = QString::fromLatin1("PROFILE_");
+ profile += emailConf.readEntry(QString::fromLatin1("Profile"), QString::fromLatin1("Default"));
+ emailConf.setGroup(profile);
+
+ contactMail->setText(emailConf.readEntry(QString::fromLatin1("EmailAddress")));
+
+ guessDataDir();
+ //aesthetics
+ cancelButton()->setFixedSize( cancelButton()->sizeHint() );
+ helpButton()->hide();
+
+
+ whichproc = new KProcIO();
+ whichproc->setUseShell(TRUE);
+ QString whichCommand="ps -C tor;ps -C privoxy";
+
+ *whichproc<<whichCommand;
+
+ connect( whichproc, SIGNAL(readReady(KProcIO * )),
+ SLOT(processWhich(KProcIO * )) );
+ whichproc->start(KProcIO::NotifyOnExit,TRUE);
+
+
+}
+
+void FirstRunWizard::monitorRemote_toggled( bool remoteTor)
+{
+
+ if ((!tor) && (!remoteTor))
+ setAppropriate ( Locate_Tor, true );
+ else
+ setAppropriate ( Locate_Tor, false );
+ setAppropriate ( HowDoesTorStart, !remoteTor );
+ setAppropriate ( TorUsage, !remoteTor );
+ setAppropriate ( TorServer, !remoteTor );
+ setAppropriate ( Remote_Tor, remoteTor );
+ setAppropriate ( TestingTor, remoteTor );
+}
+
+void FirstRunWizard::usingAnotherProxy_toggled( bool state)
+{
+
+ setAppropriate ( CheckNotUsing, state );
+ setAppropriate ( CheckUsing, state );
+ setAppropriate ( NonPrivoxyConfirmation, state );
+ setAppropriate ( PrivoxyConfirmation, !state );
+ if ((!privoxy) && (!state))
+ setAppropriate ( Locate_Privoxy, !state );
+ setAppropriate ( HowDoesPrivoxyStart, !state );
+ setAppropriate ( PrivoxyConfiguration, !state );
+ setAppropriate ( FinalPrivoxy, !state );
+}
+
+void FirstRunWizard::torStartsAutomatically_toggled( bool state)
+{
+ setAppropriate ( TorUsage, !state );
+ setAppropriate ( TorServer, !state );
+ setAppropriate ( TestingTor , state );
+}
+
+void FirstRunWizard::torStartsManually_toggled( bool state)
+{
+ setAppropriate ( TorUsage, state );
+ setAppropriate ( TorServer, state );
+ setAppropriate ( TestingTor , !state );
+}
+
+void FirstRunWizard::processWhich(KProcIO *whichproc)
+{
+ QString item = "";
+ int pos;
+
+ while ((pos = (whichproc->readln(item,true))) != -1) {
+ if (item.find("tor") != -1)
+ torRunning = true;
+ if (item.find("privoxy") != -1)
+ privoxyRunning = true;
+ }
+ whichproc->ackRead();
+
+}
+
+void
+FirstRunWizard::showPage( QWidget *w ) //virtual
+{
+ QWizard::showPage( w );
+
+
+ if (currentPage() == HowDoesTorStart){
+ torStartsAutomatically->setChecked(torRunning);
+ torStartsManually->setChecked(!torRunning);
+ }
+
+ if (currentPage() == LocalOrRemote){
+ torStartsAutomatically->setChecked(false);
+ torStartsManually->setChecked(false);
+ }
+
+ if (currentPage() == HowDoesPrivoxyStart){
+ privoxyStartsAutomatically->setChecked(privoxyRunning);
+ privoxyStartsManually->setChecked(!privoxyRunning);
+ if (privoxyRunning){
+ privoxyText->setText(i18n("<p>To be honest, I'm not that bright."
+ "It looks as if Privoxy is configured to start up by itself when "
+ "your computer boots up, but I can't be sure. So can you help me?"
+ "Does Privoxy start by itself at boot-time?</p>"));
+ }else{
+ privoxyText->setText(i18n("<p>To be honest, I'm not that bright."
+ "It looks as if Privoxy does not start up by itself when "
+ "your computer boots up, but I can't be sure. So can you help me?"
+ "Does Privoxy start by itself at boot-time?</p>"));
+
+ }
+ }
+
+ if (currentPage() == CheckUsing){
+ saveAnonymousProxySettings();
+ }
+
+ if (currentPage() == TestingTor){
+ testTor();
+ }
+
+
+ if (currentPage() == NonPrivoxyConfirmation){
+ saveNonAnonymousProxySettings();
+ }
+ if (currentPage() == PrivoxyConfirmation){
+ saveNonAnonymousProxySettings();
+ }
+
+ setFinishEnabled ( Final,true );
+
+
+// cancelButton()->setText( w == WizardPage_0 ? i18n("&Skip") : i18n("&Cancel") );
+}
+
+
+
+void FirstRunWizard::downloadPrivoxy_clicked()
+{
+ TorkUpdate* updater = new TorkUpdate(this);
+ updater->checkForNewPrivoxyDirectly();
+
+}
+
+
+void FirstRunWizard::downloadTor_clicked()
+{
+
+ TorkUpdate* updater = new TorkUpdate(this);
+ updater->checkForNewTorDirectly(false);
+
+}
+
+void
+FirstRunWizard::accept()
+{
+
+ QString paths;
+ paths = ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin";
+ paths.replace("::",":");
+
+ torknetstat = getFullLocation(paths,"torknetstat");;
+
+ if (torknetstat)
+ TorkConfig::setNetstatLocation("torknetstat");
+ else
+ TorkConfig::setNetstatLocation("netstat");
+
+ if (torStartsAutomatically->isChecked())
+ TorkConfig::setQuickConfigure(7);
+ else if (monitorRemote->isChecked())
+ TorkConfig::setQuickConfigure(6);
+ else
+ TorkConfig::setQuickConfigure(WizardQuickConfigure->currentItem());
+
+ TorkConfig::setTorLocation(TorLocation_2->url());
+ TorkConfig::setPrivoxyLocation(PrivoxyLocation_2->url());
+ TorkConfig::setNickName(serverName->text());
+ TorkConfig::setContactInfo(contactMail->text());
+
+ if (monitorRemote->isChecked()){
+ TorkConfig::setRemoteTorAddress(RemoteTorAddress->text());
+ TorkConfig::setRemoteTorPort(RemoteTorPort->text().toInt());
+ }
+
+ if ((usingAnotherProxy->isChecked()) || (privoxyStartsAutomatically->isChecked())){
+ TorkConfig::setSystemProxy(true);
+ TorkConfig::setTorkProxy(false);
+ }else{
+ TorkConfig::setSystemProxy(false);
+ TorkConfig::setTorkProxy(true);
+ }
+
+
+ //Non-Anon Proxy Settings
+ TorkConfig::setOriginalHttpProxy(OriginalHttpProxy);
+ TorkConfig::setOriginalHttpsProxy(OriginalHttpsProxy);
+ TorkConfig::setOriginalProxyType(OriginalProxyType);
+ TorkConfig::setOriginalCookies(OriginalCookies);
+ TorkConfig::setOriginalUseCache(OriginalUseCache);
+ TorkConfig::setOriginalSendUserAgent(OriginalSendUserAgent);
+ TorkConfig::setOriginalEnableJavascript(OriginalEnableJavascript);
+ TorkConfig::setOriginalEnableJava(OriginalEnableJava);
+ TorkConfig::setOriginalEnablePlugins(OriginalEnablePlugins);
+
+ //Anon Proxy Settings
+
+ TorkConfig::setKonqHttpProxy(KonqHttpProxy);
+ TorkConfig::setKonqHttpProxyPort(KonqHttpProxyPort);
+ TorkConfig::setKonqHttpsProxy(KonqHttpsProxy);
+ TorkConfig::setKonqHttpsProxyPort(KonqHttpsProxyPort);
+ TorkConfig::setKonqFtpProxy(KonqFtpProxy);
+ TorkConfig::setKonqFtpProxyPort(KonqFtpProxyPort);
+
+ if (!usingAnotherProxy->isChecked()){
+ TorkConfig::setKonqHttpProxy("http://localhost");
+ TorkConfig::setKonqHttpProxyPort(8118);
+ TorkConfig::setKonqHttpsProxy("http://localhost");
+ TorkConfig::setKonqHttpsProxyPort(8118);
+ }
+
+ TorkConfig::writeConfig();
+ QDialog::accept();
+}
+void
+FirstRunWizard::reject()
+{
+ QDialog::reject();
+}
+
+void FirstRunWizard::WizardQuickConfigure_activated( int item)
+{
+
+ if (item == 4)
+ setAppropriate ( TorServer, false );
+ else
+ setAppropriate ( TorServer, true );
+
+ settingsDescription->setText(descriptions[item]);
+
+}
+
+void
+FirstRunWizard::saveNonAnonymousProxySettings()
+{
+
+
+ KConfig* config = new KConfig("kioslaverc", false, false);
+ config->setGroup( "Proxy Settings" );
+ OriginalHttpProxy = config->readEntry( "httpProxy" );
+ OriginalHttpsProxy = config->readEntry( "httpsProxy" );
+ OriginalProxyType = config->readEntry( "ProxyType" );
+ config = new KConfig("kcookiejarrc", false, false);
+ config->setGroup( "Cookie Policy" );
+ OriginalCookies = config->readEntry( "Cookies" );
+ config = new KConfig("kio_httprc", false, false);
+ OriginalUseCache = config->readEntry( "UseCache" );
+ OriginalSendUserAgent = config->readEntry( "SendUserAgent" );
+ config = new KConfig("konquerorrc", false, false);
+ config->setGroup( "Java/JavaScript Settings" );
+ OriginalEnableJavascript = config->readEntry( "EnableJavaScript" );
+ OriginalEnableJava = config->readEntry( "EnableJava" );
+ OriginalEnablePlugins = config->readEntry( "EnablePlugins" );
+
+ if (currentPage() == PrivoxyConfirmation){
+ KonqHttpProxy = "http://localhost";
+ KonqHttpProxyPort = 8118;
+ KonqHttpsProxy = "http://localhost";
+ KonqHttpsProxyPort = 8118;
+ KonqFtpProxy = "http://localhost";
+ KonqFtpProxyPort = 8118;
+ }
+
+}
+
+void
+FirstRunWizard::saveAnonymousProxySettings()
+{
+
+
+
+ KConfig* config = new KConfig("kioslaverc", false, false);
+ config->setGroup( "Proxy Settings" );
+ KonqHttpProxy = config->readEntry( "httpProxy" ).section(":",0,1);
+ KonqHttpProxyPort = config->readEntry( "httpProxy" ).section(":",-1,-1).toInt();
+ KonqHttpsProxy = config->readEntry( "httpsProxy" ).section(":",0,1);
+ KonqHttpsProxyPort = config->readEntry( "httpsProxy" ).section(":",-1,-1).toInt();
+ KonqFtpProxy = config->readEntry( "ftpProxy" ).section(":",0,1);
+ KonqFtpProxyPort = config->readEntry( "ftpProxy" ).section(":",-1,-1).toInt();
+
+}
+
+void FirstRunWizard::TorLocation_textChanged( const QString & text)
+{
+ if (text.contains("tor"))
+ setNextEnabled ( Locate_Tor,true );
+}
+
+
+
+
+void FirstRunWizard::pushButton1_clicked()
+{
+ KRun::runCommand( "kcmshell proxy" );
+
+}
+
+
+void FirstRunWizard::pushButton1_2_clicked()
+{
+ KRun::runCommand( "kcmshell proxy" );
+}
+
+
+void FirstRunWizard::pushButton1_3_clicked()
+{
+ KRun::runCommand( "kcmshell proxy" );
+}
+
+void FirstRunWizard::testTorAgain_clicked()
+{
+ testTor();
+
+}
+
+void FirstRunWizard::testTor()
+{
+ kdDebug() << "testing tor" << endl;
+ QString host;
+ int port;
+ if (monitorRemote->isChecked()){
+ host = RemoteTorAddress->text();
+ port = RemoteTorPort->text().toInt();
+ TorkConfig::setCookieAuthentication(false);
+ }else{
+ host = "localhost";
+ port = TorkConfig::controlPort();
+ TorkConfig::setCookieAuthentication(false);
+ }
+
+ if (!TorPassword->text().isEmpty() && TorPassword->isEnabled())
+ TorkConfig::setHashedControlPassword(TorPassword->text());
+
+ if (client)
+ delete client;
+
+ client = new TorClient(host,port);
+ connect( client, SIGNAL(fatalError()),this, SLOT(cannotContactTor()));
+ connect( client, SIGNAL(authenticationFailed()),this, SLOT(cannotContactTor()));
+ connect( client, SIGNAL(authenticated()),this, SLOT(contactedTor()) );
+ client->authenticate();
+
+}
+
+void FirstRunWizard::modifyConfs_clicked()
+{
+ examineConfigFiles();
+}
+
+void FirstRunWizard::cannotContactTor()
+{
+
+ disconnect( client, SIGNAL(fatalError()),this, SLOT(cannotContactTor()));
+ disconnect( client, SIGNAL(authenticationFailed()),this, SLOT(cannotContactTor()));
+ disconnect( client, SIGNAL(authenticated()),this, SLOT(contactedTor()) );
+ if (client != 0L){
+ client->socketReadyRead();
+ client->deleteLater();
+ client = 0L;
+ }
+
+ if (monitorRemote->isChecked()){
+ torControlStatus->setText(i18n("<p>I can't contact or authenticate to Tor.<br>"
+ "This means you will need to modify Tor's settings if it is to be usable by Tork in future.</p>"
+ "On the machine that your remote Tor installation runs on add the following to Tor's config file:<br>"
+ "<br>"
+ "<b>ControlPort %2</b><br>"
+ "<br>"
+ "Alternatively, you may have entered the wrong password in the previous page.<br>"
+ "When you've attempted to fix the problem, click <b>'Test Tor'</b> to try connecting again.")
+ .arg(RemoteTorPort->text()));
+ }else{
+ torControlStatus->setText(i18n("<p>I can't contact or authenticate to Tor.<br>"
+ "This means Tork will need to modify Tor's settings if it is to be usable by Tork in future.</p>"
+ "To the right is a list of the possible files that Tor may be using for it's configuration.<br>"
+ "If you click the <b>'Modify Tor's Control File'</b> button, I'll modify any that exist to make Tor controllable by TorK.<br>"
+ "Once that's done you can click <b>'Test Tor'</b> to re-test the connection."));
+ modifyConfigs->setEnabled(true);
+ }
+ testTorAgain->setEnabled(true);
+
+}
+
+void FirstRunWizard::contactedTor()
+{
+
+ disconnect( client, SIGNAL(fatalError()),this, SLOT(cannotContactTor()));
+ disconnect( client, SIGNAL(authenticated()),this, SLOT(contactedTor()) );
+ if (client != 0L){
+ client->socketReadyRead();
+ client->deleteLater();
+ client = 0L;
+ }
+
+ if (!monitorRemote->isChecked())
+ torControlStatus->setText(i18n("<p>I contacted Tor successfully.<br>"
+ "This means TorK can contact and control Tor. That's a good thing.<br>"
+ "<b>By default, TorK will secure its session with Tor using a random "
+ "password.</b> However, you should consider using a security option on "
+ "Tor that will secure it even when you're not using TorK.<br>"
+ "See the 'My Tor Client' configuration section for more info"
+ " when you're finished the wizard. <br>"
+ "You can now click <b>'Next'</b>."));
+ else
+ torControlStatus->setText(i18n("<p>I contacted Tor successfully.<br>"
+ "This means TorK can contact and control Tor. That's a good thing. "
+ "As a security precaution, you should configure your remote instance "
+ "of Tor to require a password. You can inform TorK of the password "
+ "using the 'My Tor Client' configuration section. "
+ ));
+
+ modifyConfigs->setEnabled(false);
+ testTorAgain->setEnabled(true);
+ TorkConfig::setGenerateRandomPassword(true);
+// if (!monitorRemote->isChecked())
+// QTimer::singleShot( 3000, this, SLOT(examineConfigFiles()) );
+
+}
+
+void FirstRunWizard::examineConfigFiles()
+{
+
+ bool foundone = false;
+
+ for (unsigned int index = 0; index != configCandidates->count(); ++index){
+ if (QFile::exists(configCandidates->item(index)->text()))
+ {
+ appendControlDirective(configCandidates->item(index)->text());
+ foundone = true;
+ }
+ }
+
+ if (!foundone){
+ appendControlDirective("/usr/local/etc/tor/torrc");
+ appendControlDirective("/etc/tor/torrc");
+ appendControlDirective("/usr/etc/tor/torrc");
+ torControlStatus->setText(i18n("<p>OK, I didn't find any of the config files in the list.<br>"
+ "To make tor usable I'm creating config files in three locations: /usr/local/etc/tor/torrc, /usr/etc/tor/torrc and /etc/tor/torrc."
+ "I've also asked Tor to reload and it will catch and use one of these files. "
+ "<b> You'll be asked for your root password in a moment. "
+ "<b> This is to modify the file and necessary to get Tor working.</b> "
+ "When you've entered your password "
+ "click <b>'Test Tor'</b> to see if it worked. "));
+ }
+}
+
+void FirstRunWizard::pushButton6_clicked()
+{
+ rootifyNetstat();
+}
+
+void FirstRunWizard::rootifyNetstat()
+{
+
+ QString newnetstat = QString(netstat).replace("netstat","torknetstat");
+
+ KProcIO *catproc = new KProcIO();
+ catproc->setUseShell(TRUE);
+ QString whichCommand= QString("kdesu -t -c 'cp %1 %2;chmod u+s %3'").arg(netstat).arg(newnetstat).arg(newnetstat);
+ *catproc<<whichCommand;
+ catproc->start(KProcIO::NotifyOnExit,TRUE);
+
+}
+
+void FirstRunWizard::sighupTor(const QString& text)
+{
+
+ KProcIO *catproc = new KProcIO();
+ catproc->setUseShell(TRUE);
+ QString whichCommand= QString("killall -s HUP %1").arg(text);
+ *catproc<<whichCommand;
+ catproc->start(KProcIO::NotifyOnExit,TRUE);
+
+}
+
+void FirstRunWizard::appendControlDirective(const QString& text)
+{
+
+ int result = KMessageBox::questionYesNo(this,
+ i18n( "<p>I'm going to modify the Tor configuration file: <b>%1</b>.<br>"
+ "This is so that I can ensure"
+ "TorK can communicate with Tor.<br>"
+ " If you say Yes, I may have to ask for your <b>root password</b>.").arg(text));
+ switch (result) {
+ case KMessageBox::No :
+ return;
+ }
+
+ QFile inf(text);
+ if ( inf.open(IO_WriteOnly | IO_Append) ) {
+
+ QTextStream ts( &inf );
+
+ ts << "ControlPort 9051" << "\n";
+
+ inf.close();
+ sighupTor("tor");
+
+ }else{
+
+ QString directory = KURL(text).directory();
+ KProcIO *catproc = new KProcIO();
+ catproc->setUseShell(TRUE);
+ QString whichCommand= QString("kdesu -c \"sh -c 'mkdir -p %1;printf \\\"ControlPort 9051\\n\\\""
+ " >> %2;killall -s HUP tor'\"").arg(directory).arg(text);
+ *catproc<<whichCommand;
+ catproc->start(KProcIO::NotifyOnExit,TRUE);
+ //-c "sh -c 'printf \"ControlPort 9051\n\" >> /etc/tor/torrc'"
+
+ }
+
+}
+
+void FirstRunWizard::guessDataDir( )
+{
+
+ QStringList dataDirCands;
+ dataDirCands << QString("%1/.tor/").arg(getenv("HOME"));
+ dataDirCands << QString("/var/lib/tor/");
+
+ for ( QStringList::Iterator it = dataDirCands.begin(); it != dataDirCands.end(); ++it ) {
+ QDir inf((*it));
+ if ( inf.exists() ) {
+ TorkConfig::setDataDirectory((*it));
+ return;
+ }
+ }
+}
+
+
+void FirstRunWizard::RemoteTorAddress_textChanged( const QString & text)
+{
+ if ((text == "127.0.0.1") || (text == "localhost"))
+ TorPassword->setEnabled(false);
+ else
+ TorPassword->setEnabled(true);
+}
+
+
+void FirstRunWizard::modifyConfPrivoxy_clicked()
+{
+ examinePrivoxyConfigFiles();
+}
+
+void FirstRunWizard::examinePrivoxyConfigFiles()
+{
+
+ bool foundone = false;
+
+ for (unsigned int index = 0; index != configCandidatesPrivoxy->count(); ++index){
+ if (QFile::exists(configCandidatesPrivoxy->item(index)->text()))
+ {
+ appendPrivoxyConfig(configCandidatesPrivoxy->item(index)->text());
+ foundone = true;
+ }
+ }
+
+
+ if (!foundone){
+ appendPrivoxyConfig("/etc/privoxy/config");
+ privoxyStatus->setText(i18n("<p>OK, I didn't find any of the config files in the list.<br>"
+ "Tork has created a basic config in /etc/privoxy/config."
+ "This <i>may</i> get things working, but possibly not.<br>"
+ "You should:"
+ "- Check Privoxy is properly installed."
+ "- Re-install privoxy and try running the wizard again."
+ ));
+ }
+}
+
+void FirstRunWizard::appendPrivoxyConfig(const QString& text)
+{
+
+ QString privoxyConf = QString(
+ "confdir %1\\n"
+ "logdir .\\n"
+ "listen-address %2:%3\\n"
+ "debug 1 # URLs\\n"
+ "debug 4096 # Info\\n"
+ "debug 8192 # Errors\\n"
+ "toggle 1\\n"
+ "buffer-limit 4069\\n"
+ "forward 192.168.*.*/ .\\n"
+ "forward 10.*.*.*/ .\\n"
+ "forward 127.*.*.*/ .\\n"
+ "forward-socks4a / %4:%5 .\\n")
+ .arg(locate("data","tork/privoxy/"))
+ .arg(TorkConfig::konqHttpProxy().replace("http://",""))
+ .arg(TorkConfig::konqHttpProxyPort())
+ .arg(TorkConfig::sOCKSBindAddressHost())
+ .arg(TorkConfig::sOCKSBindAddressPort());
+
+ int result = KMessageBox::questionYesNo(this,
+ i18n( "<p>I'm going to modify the Privoxy configuration file: <b>%1</b>.<br>"
+ "This is so that I can ensure"
+ "Privoxy can communicate with Tor.<br>"
+ " If you say Yes, I'll ask for your root password.").arg(text));
+ switch (result) {
+ case KMessageBox::No :
+ return;
+ }
+
+ QFile inf(text);
+ if ( inf.open(IO_WriteOnly | IO_Append) ) {
+
+ QTextStream ts( &inf );
+
+ ts << privoxyConf;
+
+ inf.close();
+ sighupTor("privoxy");
+
+ }else{
+
+ KProcIO *catproc = new KProcIO();
+ catproc->setUseShell(TRUE);
+ QString whichCommand= QString("kdesu -c \"sh -c 'printf \\\"%1\\\""
+ " >> %2;killall -s HUP privoxy'\"")
+ .arg(privoxyConf)
+ .arg(text);
+ *catproc<<whichCommand;
+ catproc->start(KProcIO::NotifyOnExit,TRUE);
+
+ }
+
+}
diff --git a/src/newstreamosd.cpp b/src/newstreamosd.cpp
new file mode 100644
index 0000000..4ed437c
--- /dev/null
+++ b/src/newstreamosd.cpp
@@ -0,0 +1,537 @@
+/***************************************************************************
+ * $Id: newstreamosd.cpp,v 1.22 2008/08/20 16:49:22 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+/*
+ *
+ * Copyright (C) 2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ *
+ * Some minor changes for TorK:
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ */
+
+#include "newstreamosd.h"
+#include "torkview.h"
+
+#include <kwin.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kcursor.h>
+#include <kconfig.h>
+#include <klocale.h>
+#include <kpopupmenu.h>
+#include <qlistview.h>
+#include <qlayout.h>
+#include <qheader.h>
+
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qapplication.h>
+#include <qframe.h>
+#include <qtoolbutton.h>
+#include <kapplication.h>
+#include <kiconloader.h>
+
+#include <X11/Xlib.h>
+#include <qtooltip.h> //QToolTip::palette()
+
+
+StreamOSD::StreamOSD( torkView* parent, bool tortraffic, const char* name )
+ : QWidget( parent, name, WType_TopLevel | WNoAutoErase | WStyle_Customize | WX11BypassWM | WStyle_StaysOnTop ),
+ m_dirty(true),
+ m_dragging(false),
+ m_screen(0),
+ m_position(s_outerMargin, s_outerMargin),
+ m_parent(parent),
+ m_tortraffic(tortraffic)
+{
+ setFocusPolicy( NoFocus );
+ setBackgroundMode( NoBackground );
+ // dummy size
+ resize( 250, 125 );
+
+ // make sure we are always visible
+ KWin::setOnAllDesktops( winId(), true );
+
+ if (m_tortraffic)
+ renderOSD();
+ else
+ renderNonTorOSD();
+
+}
+
+
+StreamOSD::~StreamOSD()
+{
+}
+
+
+
+
+void StreamOSD::setText( const QString& text )
+{
+ if( m_text != text ) {
+ m_text = text;
+ refresh();
+ }
+}
+
+
+void StreamOSD::setProgress( int p )
+{
+
+ if( m_progress != p ) {
+ m_progress = p;
+ refresh();
+ }
+}
+
+
+void StreamOSD::setPosition( const QPoint& p )
+{
+ m_position = p;
+ reposition();
+}
+
+
+void StreamOSD::refresh()
+{
+ if( isVisible() ){
+ if (m_tortraffic)
+ renderOSD();
+ else
+ renderNonTorOSD();
+ }else
+ m_dirty = true;
+}
+
+
+void StreamOSD::renderOSD()
+{
+ QColor osdcolor = QToolTip::palette().color(QPalette::Active, QColorGroup::Background);
+ int large = font().pointSize();
+ int small = font().pointSize() - 1;
+ QFont f( font().rawName(), small );
+ setFont( f );
+ setWFlags( Qt::WX11BypassWM );
+ setPalette(osdcolor);
+ setPaletteBackgroundColor(osdcolor);
+ //setBackgroundMode( PaletteBase );
+ QGridLayout* TabPageLayout = new QGridLayout( this, 3, 8, 11, 6, "TabPageLayout");
+ TabPageLayout->setMargin(2);
+ QLabel* textLabel = new QLabel( this, "textLabel2" );
+ textLabel->setText(i18n("<b>Tor Traffic</b>"));
+ QFont f2( font().rawName(), large );
+ textLabel->setFont( f2 );
+
+ TabPageLayout->addMultiCellWidget( textLabel, 0,0,0,3 );
+
+ changeID = new QToolButton( this,"changeid" );
+ changeID->setIconSet( SmallIconSet( "tork_identity" ) );
+ changeID->setUsesTextLabel(false);
+ changeID->setMaximumSize(SmallIconSet( "tork_identity" ).iconSize(QIconSet::Small));
+ changeID->adjustSize();
+ TabPageLayout->addWidget(changeID,0,5);
+ QToolTip::add( changeID, i18n( "Change the 'Exit' used for current traffic.") );
+
+
+ toggleKDE = new QToolButton( this,"konq" );
+ toggleKDE->setIconSet( SmallIconSet( "tork_konqueroroff" ) );
+ toggleKDE->setUsesTextLabel(false);
+ toggleKDE->setMaximumSize(SmallIconSet( "tork_konqueroroff" ).iconSize(QIconSet::Small));
+ toggleKDE->adjustSize();
+ TabPageLayout->addWidget(toggleKDE,0,6);
+ QToolTip::add( toggleKDE,i18n("Enable/Disable Konqueror's use of Tor"));
+
+ QToolButton* hideMonitor = new QToolButton( this,"hide" );
+ hideMonitor->setIconSet( SmallIconSet( "cancel" ) );
+/* hideMonitor->setTextLabel(i18n( "Hide" ));
+ hideMonitor->setTextPosition(QToolButton::Right);
+ hideMonitor->setUsesTextLabel(true);*/
+ hideMonitor->setUsesTextLabel(false);
+ hideMonitor->setMaximumSize(SmallIconSet( "cancel" ).iconSize(QIconSet::Small));
+ hideMonitor->adjustSize();
+ TabPageLayout->addWidget(hideMonitor,0,7);
+ QToolTip::add( hideMonitor,i18n("Hide this Display."));
+
+ QToolTip::add( this,i18n("This displays all network activity currently being handled by Tor."));
+
+ connect( hideMonitor, SIGNAL(clicked()),
+ SLOT(slotHideMonitor()) );
+ connect( toggleKDE, SIGNAL(clicked()),
+ SLOT(slotToggleKDE()) );
+ connect( changeID, SIGNAL(clicked()),
+ SLOT(slotChangeID()) );
+
+// connect( toggleKDE, SIGNAL(clicked()),
+// SLOT(slotToggleKDE()) );
+
+
+ infoList = new QListView( this, "infoList" );
+ infoList->addColumn( "StreamID" );
+ infoList->addColumn( "Host" );
+ infoList->addColumn( kapp->iconLoader()->loadIconSet("tork_torsmall", KIcon::Small),"", 24 );
+ infoList->addColumn( "KB/s" );
+ infoList->addColumn( "Exit" );
+ infoList->setColumnWidthMode(0, QListView::Manual);
+ infoList->hideColumn(0);
+ infoList->hideColumn(2);
+ infoList->header()->setResizeEnabled(FALSE, 0);
+ infoList->setResizeMode( QListView::NoColumn );
+ infoList->setHScrollBarMode(QScrollView::AlwaysOff);
+ infoList->setVScrollBarMode(QScrollView::AlwaysOff);
+ infoList->setSelectionMode( QListView::Single );
+ TabPageLayout->addMultiCellWidget( infoList, 1,1,0,7 );
+ infoList->setPaletteBackgroundColor(osdcolor);
+// infoList->header()->hide();
+
+ m_graphOut = new StatGraph(this,1,0,"Up");
+ m_graphIn = new StatGraph(this,1,0,"Down");
+ m_graphOut->setReadingColor(Qt::red);
+ m_graphIn->setReadingColor(Qt::green);
+/* chart = new Chart(this, m_parent->speedHistoryTx(), m_parent->speedHistoryRx(), m_parent->historyBufferSize(), m_parent->historyPointer(), m_parent->maxSpeed());
+ TabPageLayout->addMultiCellWidget( chart, 2,2, 0,3 );
+ chart->setMinimumHeight(10);*/
+ TabPageLayout->addMultiCellWidget( m_graphOut, 2,2, 0,3 );
+ TabPageLayout->addMultiCellWidget( m_graphIn, 2, 2, 4,7 );
+
+ //infoList->adjustSize();
+ //frame->update();
+ connect( infoList, SIGNAL( contextMenuRequested(QListViewItem*,const QPoint&,int) ), this, SLOT( contextMenuRequested(QListViewItem*,const QPoint&,int) ) );
+
+
+
+ QPoint point;
+ QRect rect( point, size() );
+ const uint M = fontMetrics().width( 'x' );
+
+
+ const uint xround = (M * 200) / size().width();
+ const uint yround = (M * 200) / size().height();
+
+
+ { /// apply the mask
+ static QBitmap mask;
+
+ mask.resize( size() );
+ mask.fill( Qt::black );
+
+ QPainter p( &mask );
+ p.setBrush( Qt::white );
+ p.drawRoundRect( rect, xround, yround );
+ setMask( mask );
+ }
+
+ m_osdBuffer.resize( rect.size() );
+ QPainter p( &m_osdBuffer );
+ p.fillRect( rect, backgroundColor() );
+ p.setPen( backgroundColor().dark() );
+ p.drawRoundRect( rect, xround, yround );
+ p.end();
+
+}
+
+void StreamOSD::renderNonTorOSD()
+{
+ QColor osdcolor = Qt::green;
+ int large = font().pointSize();
+ int small = font().pointSize() - 1;
+ QFont f( font().rawName(), small );
+ setFont( f );
+ setWFlags( Qt::WX11BypassWM );
+ setPalette(osdcolor);
+ setPaletteBackgroundColor(osdcolor);
+ //setBackgroundMode( PaletteBase );
+ QGridLayout* TabPageLayout = new QGridLayout( this, 3, 8, 11, 6, "TabPageLayout");
+ TabPageLayout->setMargin(2);
+ QLabel* textLabel = new QLabel( this, "textLabel2" );
+ textLabel->setText(i18n("<b>Tor Traffic</b>"));
+ QFont f2( font().rawName(), large );
+ textLabel->setFont( f2 );
+
+ TabPageLayout->addMultiCellWidget( textLabel, 0,0,0,3 );
+
+ QToolButton* hideMonitor = new QToolButton( this,"hide" );
+ hideMonitor->setIconSet( SmallIconSet( "cancel" ) );
+ hideMonitor->setUsesTextLabel(false);
+ hideMonitor->setMaximumSize(SmallIconSet( "cancel" ).iconSize(QIconSet::Small));
+ hideMonitor->adjustSize();
+ TabPageLayout->addWidget(hideMonitor,0,7);
+ QToolTip::add( hideMonitor,i18n("Hide this Display."));
+
+ QToolTip::add( this,i18n("This displays all your system's network activity."));
+
+ connect( hideMonitor, SIGNAL(clicked()),
+ SLOT(slotHideMonitor()) );
+
+
+ infoList = new QListView( this, "infoList" );
+ infoList->addColumn( "Program" );
+ infoList->addColumn( "Host" );
+ infoList->addColumn( "KB/s" );
+ infoList->setColumnWidthMode(0, QListView::Manual);
+ infoList->header()->setResizeEnabled(FALSE, 0);
+ infoList->setResizeMode( QListView::NoColumn );
+ infoList->setHScrollBarMode(QScrollView::AlwaysOff);
+ infoList->setVScrollBarMode(QScrollView::AlwaysOff);
+ infoList->setSelectionMode( QListView::Single );
+ TabPageLayout->addMultiCellWidget( infoList, 1,1,0,7 );
+ infoList->setPaletteBackgroundColor(osdcolor);
+
+ m_graphOut = new StatGraph(this,1,0,"Up");
+ m_graphIn = new StatGraph(this,1,0,"Down");
+ m_graphOut->setReadingColor(Qt::red);
+ m_graphIn->setReadingColor(Qt::green);
+ TabPageLayout->addMultiCellWidget( m_graphOut, 2,2, 0,3 );
+ TabPageLayout->addMultiCellWidget( m_graphIn, 2, 2, 4,7 );
+
+ QPoint point;
+ QRect rect( point, size() );
+ const uint M = fontMetrics().width( 'x' );
+
+
+ const uint xround = (M * 200) / size().width();
+ const uint yround = (M * 200) / size().height();
+
+
+ { /// apply the mask
+ static QBitmap mask;
+
+ mask.resize( size() );
+ mask.fill( Qt::black );
+
+ QPainter p( &mask );
+ p.setBrush( Qt::white );
+ p.drawRoundRect( rect, xround, yround );
+ setMask( mask );
+ }
+
+ m_osdBuffer.resize( rect.size() );
+ QPainter p( &m_osdBuffer );
+ p.fillRect( rect, backgroundColor() );
+ p.setPen( backgroundColor().dark() );
+ p.drawRoundRect( rect, xround, yround );
+ p.end();
+
+}
+
+
+void StreamOSD::setScreen( int screen )
+{
+ const int n = QApplication::desktop()->numScreens();
+ m_screen = (screen >= n) ? n-1 : screen;
+ reposition();
+}
+
+
+void StreamOSD::reposition( QSize newSize )
+{
+ if( !newSize.isValid() )
+ newSize = size();
+
+ QPoint newPos = m_position;
+ const QRect& screen = QApplication::desktop()->screenGeometry( m_screen );
+
+ // now to properly resize if put into one of the corners we interpret the position
+ // depending on the quadrant
+ int midH = screen.width()/2;
+ int midV = screen.height()/2;
+ if( newPos.x() > midH )
+ newPos.rx() -= newSize.width();
+ if( newPos.y() > midV )
+ newPos.ry() -= newSize.height();
+
+ newPos = fixupPosition( newPos );
+
+ // correct for screen position
+ newPos += screen.topLeft();
+
+ // ensure we are painted before we move
+ if( isVisible() )
+ paintEvent( 0 );
+
+ // fancy X11 move+resize, reduces visual artifacts
+ XMoveResizeWindow( x11Display(), winId(), newPos.x(), newPos.y(), newSize.width(), newSize.height() );
+}
+
+
+void StreamOSD::paintEvent( QPaintEvent* )
+{
+
+ bitBlt( this, 0, 0, &m_osdBuffer );
+}
+
+
+void StreamOSD::mousePressEvent( QMouseEvent* e )
+{
+ m_dragOffset = e->pos();
+
+ if( e->button() == LeftButton && !m_dragging ) {
+ grabMouse( KCursor::sizeAllCursor() );
+ m_dragging = true;
+ }
+/* else if( e->button() == RightButton ) {
+ KPopupMenu m;
+ if( m.insertItem( i18n("Hide OSD") ) == m.exec( e->pos() ) )
+ hide();
+ }*/
+}
+
+
+void StreamOSD::mouseReleaseEvent( QMouseEvent* )
+{
+ if( m_dragging ) {
+ m_dragging = false;
+ releaseMouse();
+ }
+}
+
+
+void StreamOSD::mouseMoveEvent( QMouseEvent* e )
+{
+ if( m_dragging && this == mouseGrabber() ) {
+
+ // check if the osd has been dragged out of the current screen
+ int currentScreen = QApplication::desktop()->screenNumber( e->globalPos() );
+ if( currentScreen != -1 )
+ m_screen = currentScreen;
+
+ const QRect& screen = QApplication::desktop()->screenGeometry( m_screen );
+
+ // make sure the position is valid
+ m_position = fixupPosition( e->globalPos() - m_dragOffset - screen.topLeft() );
+
+ // move us to the new position
+ move( m_position );
+
+ // fix the position
+ int midH = screen.width()/2;
+ int midV = screen.height()/2;
+ if( m_position.x() + width() > midH )
+ m_position.rx() += width();
+ if( m_position.y() + height() > midV )
+ m_position.ry() += height();
+ }
+}
+
+
+QPoint StreamOSD::fixupPosition( const QPoint& pp )
+{
+ QPoint p(pp);
+ const QRect& screen = QApplication::desktop()->screenGeometry( m_screen );
+ int maxY = screen.height() - height() - s_outerMargin;
+ int maxX = screen.width() - width() - s_outerMargin;
+
+ if( p.y() < s_outerMargin )
+ p.ry() = s_outerMargin;
+ else if( p.y() > maxY )
+ p.ry() = maxY;
+
+ if( p.x() < s_outerMargin )
+ p.rx() = s_outerMargin;
+ else if( p.x() > maxX )
+ p.rx() = screen.width() - s_outerMargin - width();
+
+ p += screen.topLeft();
+
+ return p;
+}
+
+
+void StreamOSD::readSettings( KConfigBase* c )
+{
+ QString oldGroup = c->group();
+ if (m_tortraffic)
+ c->setGroup( "TorKOSD Position" );
+ else
+ c->setGroup( "NonTorOSD Position" );
+
+ setPosition( c->readPointEntry( "Position", 0 ) );
+ setScreen( c->readNumEntry( "Screen", 0 ) );
+
+ c->setGroup( oldGroup );
+}
+
+
+void StreamOSD::saveSettings( KConfigBase* c )
+{
+ QString oldGroup = c->group();
+ if (m_tortraffic)
+ c->setGroup( "TorKOSD Position" );
+ else
+ c->setGroup( "NonTorOSD Position" );
+
+ c->writeEntry( "Position", m_position );
+ c->writeEntry( "Screen", m_screen );
+
+ c->setGroup( oldGroup );
+}
+
+void StreamOSD::slotHideMonitor( )
+{
+ emit requestHideMonitor();
+}
+
+void StreamOSD::slotChangeID( )
+{
+ emit requestChangeID();
+}
+
+void StreamOSD::slotToggleKDE( )
+{
+ emit requestToggleKDE();
+}
+
+void StreamOSD::contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( infoList );
+
+ menu->clear();
+ menu->insertItem( "Close Stream", this,SLOT(slotCloseStream()) );
+ menu->popup( point );
+
+}
+
+
+void StreamOSD::slotCloseStream( )
+{
+
+ QListViewItemIterator it(infoList, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (infoList->isSelected( it.current()))
+ emit closeStream(it.current()->text(0));
+ ++it;
+ }
+
+
+}
+
+#include "newstreamosd.moc"
diff --git a/src/newstreamosd.h b/src/newstreamosd.h
new file mode 100644
index 0000000..9675968
--- /dev/null
+++ b/src/newstreamosd.h
@@ -0,0 +1,117 @@
+/*
+ *
+ * $Id: newstreamosd.h,v 1.7 2008/08/20 16:49:23 hoganrobert Exp $
+ * Copyright (C) 2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This file is part of the K3b project.
+ * Copyright (C) 1998-2005 Sebastian Trueg <trueg@k3b.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * See the file "COPYING" for the exact licensing terms.
+ */
+
+#ifndef _K3B_JOB_PROGRESS_OSD_H_
+#define _K3B_JOB_PROGRESS_OSD_H_
+
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qlistview.h>
+#include <qtoolbutton.h>
+
+#include "statgraph.h"
+#include "chart.h"
+
+class QPaintEvent;
+class QMouseEvent;
+class KConfigBase;
+class QHBox;
+class QListView;
+class QToolButton;
+class StatGraph;
+class Chart;
+class torkView;
+/**
+ * An OSD displaying a text and a progress bar.
+ *
+ * Insprired by Amarok's OSD (I also took a bit of their code. :)
+ */
+class StreamOSD : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ StreamOSD( torkView* parent = 0, bool tortraffic = true , const char* name = 0);
+ ~StreamOSD();
+
+ int screen() const { return m_screen; }
+ const QPoint& position() const { return m_position; }
+
+ void readSettings( KConfigBase* );
+ void saveSettings( KConfigBase* );
+
+ signals:
+ void requestHideMonitor();
+ void requestToggleKDE();
+ void requestChangeID();
+ void closeStream(const QString &);
+
+ public slots:
+ void setScreen( int );
+ void setText( const QString& );
+ void setProgress( int );
+ void slotHideMonitor();
+ void slotToggleKDE();
+ void slotChangeID();
+
+ /**
+ * The position refers to one of the corners of the widget
+ * regarding on the value of the x and y coordinate.
+ * If for example the x coordinate is bigger than half the screen
+ * width it refers to the left edge of the widget.
+ */
+ void setPosition( const QPoint& );
+
+ void contextMenuRequested( QListViewItem *, const QPoint & point, int );
+ void slotCloseStream();
+
+ protected:
+ void paintEvent( QPaintEvent* );
+ void mousePressEvent( QMouseEvent* );
+ void mouseReleaseEvent( QMouseEvent* );
+ void mouseMoveEvent( QMouseEvent* );
+ void renderOSD();
+ void renderNonTorOSD();
+ void refresh();
+ void reposition( QSize size = QSize() );
+
+ public:
+ QListView* infoList;
+ StatGraph* m_graphIn;
+ StatGraph* m_graphOut;
+ Chart* chart;
+ QToolButton* toggleKDE;
+ QToolButton* changeID;
+ private:
+ /**
+ * Ensure that the position is inside m_screen
+ */
+ QPoint fixupPosition( const QPoint& p );
+ static const int s_outerMargin = 15;
+
+ QPixmap m_osdBuffer;
+ bool m_dirty;
+ QString m_text;
+ int m_progress;
+ bool m_dragging;
+ QPoint m_dragOffset;
+ int m_screen;
+ QPoint m_position;
+ torkView* m_parent;
+ bool m_tortraffic;
+
+};
+
+#endif
diff --git a/src/overlayWidget.cpp b/src/overlayWidget.cpp
new file mode 100644
index 0000000..331a66e
--- /dev/null
+++ b/src/overlayWidget.cpp
@@ -0,0 +1,90 @@
+/***************************************************************************
+** $Id: overlayWidget.cpp,v 1.2 2006/06/22 18:56:03 hoganrobert Exp $
+ * Copyright (C) 2005 by Max Howell <max.howell@methylblue.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "overlayWidget.h"
+//#include "statusbar.h"
+
+#include <qpoint.h>
+
+
+namespace KDE {
+
+
+OverlayWidget::OverlayWidget( QWidget *parent, QWidget *anchor, const char* name )
+ : QFrame( parent->parentWidget(), name )
+ , m_anchor( anchor )
+ , m_parent( parent )
+{
+ parent->installEventFilter( this );
+
+ hide();
+}
+
+void
+OverlayWidget::reposition()
+{
+ setMaximumSize( parentWidget()->size() );
+ adjustSize();
+
+ // p is in the alignWidget's coordinates
+ QPoint p;
+
+ p.setX( m_anchor->width() - width() );
+ p.setY( -height() );
+
+ // Position in the toplevelwidget's coordinates
+ QPoint pTopLevel = m_anchor->mapTo( topLevelWidget(), p );
+
+ // Position in the widget's parentWidget coordinates
+ QPoint pParent = parentWidget() ->mapFrom( topLevelWidget(), pTopLevel );
+ // keep it on the screen
+ if( pParent.x() < 0 )
+ pParent.rx() = 0;
+
+ // Move 'this' to that position.
+ move( pParent );
+}
+
+bool
+OverlayWidget::eventFilter( QObject* o, QEvent* e )
+{
+ if ( e->type() == QEvent::Move || e->type() == QEvent::Resize )
+ reposition();
+
+ return QFrame::eventFilter( o, e );
+}
+
+void
+OverlayWidget::resizeEvent( QResizeEvent* ev )
+{
+ reposition();
+ QFrame::resizeEvent( ev );
+}
+
+bool
+OverlayWidget::event( QEvent *e )
+{
+ if ( e->type() == QEvent::ChildInserted )
+ adjustSize();
+
+ return QFrame::event( e );
+}
+
+}
diff --git a/src/overlayWidget.h b/src/overlayWidget.h
new file mode 100644
index 0000000..94d635a
--- /dev/null
+++ b/src/overlayWidget.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Max Howell <max.howell@methylblue.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef KDEOVERLAYWIDGET_H
+#define KDEOVERLAYWIDGET_H
+
+#include <qhbox.h>
+
+namespace KDE
+{
+ class OverlayWidget : public QFrame
+ {
+ public:
+ /**
+ * The widget is parented to the toplevelwidget of alignWidget,
+ * this could be an issue if that widget has an autoAdd Layout
+ */
+ OverlayWidget( QWidget *parent, QWidget *anchor, const char *name = 0 );
+ virtual void reposition();
+
+ protected:
+ virtual void resizeEvent( QResizeEvent* );
+ virtual bool eventFilter( QObject*, QEvent* );
+ virtual bool event( QEvent* );
+
+ private:
+ QWidget *m_anchor;
+ QWidget *m_parent;
+ };
+}
+
+#endif
diff --git a/src/paranoia.ui b/src/paranoia.ui
new file mode 100644
index 0000000..26ccdb2
--- /dev/null
+++ b/src/paranoia.ui
@@ -0,0 +1,312 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>FilterTable</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>FilterTable</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>531</width>
+ <height>411</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>MyDialog1</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget8</cstring>
+ </property>
+ <attribute name="title">
+ <string>DNS FailSafe</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView" row="2" column="0" rowspan="1" colspan="3">
+ <column>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Firewall Rule</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>FilterRules</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="4" column="2">
+ <property name="name">
+ <cstring>pushAdd</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add</string>
+ </property>
+ <property name="accel">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="3" column="1">
+ <property name="name">
+ <cstring>Description</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel1_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Description:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Rule:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="4" column="1">
+ <property name="name">
+ <cstring>Filter</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>This is a list of filter rules that will route all DNS requests to Tor:</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>kcfg_DNSFailSafeParanoia</cstring>
+ </property>
+ <property name="text">
+ <string>Use different Tor circuits for every connection while in this mode.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>System FailSafe</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel1_3_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Description:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel1_3_4</cstring>
+ </property>
+ <property name="text">
+ <string>Rule:</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="2" column="0" rowspan="1" colspan="3">
+ <column>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Firewall Rule</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>SystemFilterRules</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>kcfg_SystemFailSafeParanoia</cstring>
+ </property>
+ <property name="text">
+ <string>Use different Tor circuits for every connection while in this mode.</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel1_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>This is a list of filter rules that will route certain system traffic to Tor:</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="4" column="2">
+ <property name="name">
+ <cstring>pushAdd_Sys</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add</string>
+ </property>
+ <property name="accel">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="3" column="1">
+ <property name="name">
+ <cstring>SystemDescription</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="4" column="1">
+ <property name="name">
+ <cstring>SystemFilter</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>pushAdd</sender>
+ <signal>clicked()</signal>
+ <receiver>FilterTable</receiver>
+ <slot>pushAdd_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>pushAdd_Sys</sender>
+ <signal>clicked()</signal>
+ <receiver>FilterTable</receiver>
+ <slot>pushAdd_Sys_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>FilterRules</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>FilterTable</receiver>
+ <slot>FilterRules_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>SystemFilterRules</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>FilterTable</receiver>
+ <slot>SystemFilterRules_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">paranoia.ui.h</include>
+</includes>
+<slots>
+ <slot>pushAdd_clicked()</slot>
+ <slot>pushAdd_Sys_clicked()</slot>
+ <slot>FilterRules_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>SystemFilterRules_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotDeleteEntry()</slot>
+ <slot>slotToggleEntry()</slot>
+ <slot>slotDeleteSystemEntry()</slot>
+ <slot>slotToggleSystemEntry()</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/paranoia.ui.h b/src/paranoia.ui.h
new file mode 100644
index 0000000..4529e49
--- /dev/null
+++ b/src/paranoia.ui.h
@@ -0,0 +1,209 @@
+/***************************************************************************
+ * $Id: paranoia.ui.h,v 1.5 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "torkconfig.h"
+#include <klocale.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+
+
+void FilterTable::init()
+{
+ FilterRules->setSelectionMode( QListView::Extended );
+ FilterRules->setColumnWidthMode(0, QListView::Manual);
+ FilterRules->hideColumn(0);
+ FilterRules->header()->setResizeEnabled(FALSE, 0);
+ FilterRules->setResizeMode( QListView::NoColumn );
+
+ SystemFilterRules->setSelectionMode( QListView::Extended );
+ SystemFilterRules->setColumnWidthMode(0, QListView::Manual);
+ SystemFilterRules->hideColumn(0);
+ SystemFilterRules->header()->setResizeEnabled(FALSE, 0);
+ SystemFilterRules->setResizeMode( QListView::NoColumn );
+
+ QStringList filterRules = TorkConfig::filterRules();
+
+ QListViewItem *tm;
+ for ( QStringList::Iterator it = filterRules.begin(); it != filterRules.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString active = (*it).section("%:%",0,0);
+ QString desc = (*it).section("%:%",1,1);
+ QString entry = (*it).section("%:%",2,2);
+
+ tm = new QListViewItem(FilterRules,active,desc,entry);
+
+ tm->setPixmap( 1, QPixmap(SmallIcon(active )));
+ }
+
+
+ QStringList systemFilterRules = TorkConfig::systemFilterRules();
+
+ for ( QStringList::Iterator it = systemFilterRules.begin(); it != systemFilterRules.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString active = (*it).section("%:%",0,0);
+ QString desc = (*it).section("%:%",1,1);
+ QString entry = (*it).section("%:%",2,2);
+
+ tm = new QListViewItem(SystemFilterRules,active,desc,entry);
+
+ tm->setPixmap( 1, QPixmap(SmallIcon(active )));
+ }
+
+
+}
+
+void FilterTable::pushAdd_clicked()
+{
+ new QListViewItem(FilterRules,Description->text().replace("%:%",""),Filter->text().replace("%:%",""));
+
+}
+
+void FilterTable::pushAdd_Sys_clicked()
+{
+ new QListViewItem(SystemFilterRules,SystemDescription->text().replace("%:%",""),SystemFilter->text().replace("%:%",""));
+
+}
+
+
+void FilterTable::FilterRules_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( FilterRules );
+
+ menu->clear();
+ menu->insertItem( "Delete Entry", this,SLOT(slotDeleteEntry()) );
+ menu->insertItem( "Toggle Entry", this,SLOT(slotToggleEntry()) );
+
+ menu->popup( point );
+
+}
+
+void FilterTable::SystemFilterRules_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( SystemFilterRules );
+
+ menu->clear();
+ menu->insertItem( "Delete Entry", this,SLOT(slotDeleteSystemEntry()) );
+ menu->insertItem( "Toggle Entry", this,SLOT(slotToggleSystemEntry()) );
+
+ menu->popup( point );
+
+}
+
+
+void FilterTable::slotDeleteEntry( )
+{
+
+ QListViewItemIterator it(FilterRules, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (FilterRules->isSelected( it.current()))
+ delete it.current();
+ ++it;
+ }
+
+
+}
+
+void FilterTable::slotToggleEntry( )
+{
+
+ QListViewItemIterator it(FilterRules, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (FilterRules->isSelected( it.current())){
+ QString active = "button_cancel";
+ if (it.current()->text(0).contains("button_cancel"))
+ active = "button_ok";
+
+ it.current()->setText(0,active);
+ it.current()->setPixmap( 1, QPixmap(SmallIcon(active)));
+ }
+ ++it;
+ }
+
+
+}
+
+void FilterTable::slotDeleteSystemEntry( )
+{
+
+ QListViewItemIterator it(SystemFilterRules, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (SystemFilterRules->isSelected( it.current()))
+ delete it.current();
+ ++it;
+ }
+
+
+}
+
+void FilterTable::slotToggleSystemEntry( )
+{
+
+ QListViewItemIterator it(SystemFilterRules, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (SystemFilterRules->isSelected( it.current())){
+ QString active = "button_cancel";
+ if (it.current()->text(0).contains("button_cancel"))
+ active = "button_ok";
+
+ it.current()->setText(0,active);
+ it.current()->setPixmap( 1, QPixmap(SmallIcon(active)));
+ }
+ ++it;
+ }
+
+
+}
+
+// <connections>
+// <connection>
+// <sender>pushAdd</sender>
+// <signal>clicked()</signal>
+// <receiver>FilterTable</receiver>
+// <slot>pushAdd_clicked()</slot>
+// </connection>
+// <connection>
+// <sender>FilterRules</sender>
+// <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+// <receiver>FilterTable</receiver>
+// <slot>FilterRules_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+// </connection>
+// </connections>
+// <includes>
+// <include location="local" impldecl="in implementation">firewallsproxies.ui.h</include>
+// </includes>
+// <slots>
+// <slot>pushAdd_clicked()</slot>
+// <slot>FilterRules_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+// <slot>slotDeleteEntry()</slot>
+// </slots>
+// <functions>
+// <function access="private" specifier="non virtual">init()</function>
+// </functions>
+// <layoutdefaults spacing="6" margin="11"/>
+// </UI>
diff --git a/src/popupMessage.cpp b/src/popupMessage.cpp
new file mode 100644
index 0000000..d14c171
--- /dev/null
+++ b/src/popupMessage.cpp
@@ -0,0 +1,430 @@
+/***************************************************************************
+ * $Id: popupMessage.cpp,v 1.17 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+/***************************************************************************
+ * Copyright (C) 2005 by Max Howell <max.howell@methylblue.com> *
+ * 2005 by Seb Ruiz <me@sebruiz.net> *
+ * *
+ * Dissolve Mask (c) Kicker Authors kickertip.cpp, 2005/08/17 *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "popupMessage.h"
+#include "torkconfig.h"
+
+#include <kactivelabel.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+
+#include <qfont.h>
+#include <qframe.h>
+#include <qlabel.h>
+#include <qmessagebox.h>
+#include <qpainter.h>
+#include <qtimer.h>
+#include <qcheckbox.h>
+
+namespace KDE
+{
+
+PopupMessage::PopupMessage( QWidget *parent, QWidget *anchor, int timeout, const char *name )
+ : OverlayWidget( parent, anchor, name )
+ , m_anchor( anchor )
+ , m_parent( parent )
+ , m_maskEffect( Dissolve )
+ , m_dissolveSize( 0 )
+ , m_dissolveDelta( -1 )
+ , m_offset( 0 )
+ , m_counter( 0 )
+ , m_stage( 1 )
+ , m_timeout( timeout )
+ , m_showCounter( true )
+ , m_respondedTo( false )
+ , m_name( name )
+
+{
+ setFrameStyle( QFrame::Panel | QFrame::Raised );
+ setFrameShape( QFrame::StyledPanel );
+ setWFlags( Qt::WX11BypassWM );
+
+ QHBoxLayout *hbox;
+ QLabel *label;
+ KActiveLabel *alabel;
+
+ m_layout = new QVBoxLayout( this, 9 /*margin*/, 6 /*spacing*/ );
+
+ hbox = new QHBoxLayout( m_layout, 12 );
+
+ hbox->addWidget( m_countdownFrame = new QFrame( this, "counterVisual" ) );
+ m_countdownFrame->setFixedWidth( fontMetrics().width( "X" ) );
+ m_countdownFrame->setFrameStyle( QFrame::Plain | QFrame::Box );
+ m_countdownFrame->setPaletteForegroundColor( paletteBackgroundColor().dark() );
+
+ label = new QLabel( this, "image" );
+ hbox->add( label );
+
+ alabel = new KActiveLabel( this, "label" );
+ alabel->setTextFormat( Qt::RichText );
+ alabel->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Preferred );
+
+ hbox->add( alabel );
+
+ hbox = new QHBoxLayout( m_layout );
+
+ if (configurableType()){
+ hbox->add( new QCheckBox( this, "showWarnings" ) );
+ static_cast<QCheckBox*>(child( "showWarnings" ))->setText(QString("%1 in Future.").arg(m_name));
+ static_cast<QCheckBox*>(child( "showWarnings" ))->setChecked(TRUE);
+ connect( child( "showWarnings" ), SIGNAL(toggled( bool )), SLOT(toggled( bool )) );
+ }
+ hbox->addItem( new QSpacerItem( 4, 4, QSizePolicy::Expanding, QSizePolicy::Preferred ) );
+ hbox->add( new KPushButton( KStdGuiItem::yes(), this, "yesButton" ) );
+ hbox->add( new KPushButton( KStdGuiItem::no(), this, "closeButton" ) );
+ hbox->add( new KPushButton( KStdGuiItem::ok(), this, "okButton" ) );
+
+ connect( child( "yesButton" ), SIGNAL(clicked()), SLOT(yes()) );
+ connect( child( "closeButton" ), SIGNAL(clicked()), SLOT(no()) );
+ connect( child( "okButton" ), SIGNAL(clicked()), SLOT(no()) );
+
+}
+
+void PopupMessage::addWidget( QWidget *widget )
+{
+ m_layout->add( widget );
+ adjustSize();
+}
+
+
+void PopupMessage::showBothButton( const bool show )
+{
+ static_cast<KPushButton*>(child( "yesButton" ))->setShown( show );
+ static_cast<KPushButton*>(child( "closeButton" ))->setShown( show );
+ static_cast<KPushButton*>(child( "okButton" ))->setShown( !show );
+ adjustSize();
+}
+
+void PopupMessage::showOkButton( const bool show )
+{
+ static_cast<KPushButton*>(child( "yesButton" ))->setShown( !show );
+ static_cast<KPushButton*>(child( "closeButton" ))->setShown( !show );
+ static_cast<KPushButton*>(child( "okButton" ))->setShown( show );
+ adjustSize();
+}
+
+void PopupMessage::showCounter( const bool show )
+{
+ m_showCounter = show;
+ static_cast<QFrame*>(child( "counterVisual" ))->setShown( show );
+ adjustSize();
+}
+
+void PopupMessage::setText( const QString &text )
+{
+ static_cast<KActiveLabel*>(child( "label" ))->setText( text );
+ adjustSize();
+}
+
+void PopupMessage::setImage( const QString &location )
+{
+ static_cast<QLabel*>(child( "image" ))->setPixmap( QPixmap( location ) );
+ adjustSize();
+}
+
+void PopupMessage::setImage( const QPixmap &pix )
+{
+ static_cast<QLabel*>(child( "image" ))->setPixmap( pix );
+ adjustSize();
+}
+
+
+////////////////////////////////////////////////////////////////////////
+// Public Slots
+////////////////////////////////////////////////////////////////////////
+
+void PopupMessage::yes() //SLOT
+{
+
+ m_respondedTo = true;
+ close();
+ emit yesClicked( );
+
+}
+
+void PopupMessage::no() //SLOT
+{
+ m_respondedTo = true;
+ close();
+ emit noClicked();
+}
+
+
+void PopupMessage::close() //SLOT
+{
+ m_stage = 3;
+ killTimer( m_timerId );
+ m_timerId = startTimer( 10 );
+}
+
+void PopupMessage::toggled( bool on) //SLOT
+{
+ QString mtype = QString("%1").arg(m_name);
+
+ if (mtype.contains("Usage"))
+ TorkConfig::setShowUsageWarnings(on);
+ else if (mtype.contains("DNS"))
+ TorkConfig::setShowDNSLeaks(on);
+ else if (mtype.contains("Feedback"))
+ TorkConfig::setShowGuideQuestions(on);
+ else if (mtype.contains("Settings"))
+ TorkConfig::setShowApplySettingsQuestions(on);
+ else if (mtype.contains("Security"))
+ TorkConfig::setShowSecurityWarnings(on);
+
+
+}
+
+bool PopupMessage::configurableType() //SLOT
+{
+ QString mtype = QString(m_name);
+ if ((mtype.contains("Usage"))
+ || (mtype.contains("DNS"))
+ || (mtype.contains("Security"))
+ || (mtype.contains("Apply"))
+ || (mtype.contains("Feedback")))
+ return true;
+
+ return false;
+
+}
+
+void PopupMessage::display() //SLOT
+{
+ m_dissolveSize = 24;
+ m_dissolveDelta = -1;
+
+ if( m_maskEffect == Dissolve )
+ {
+ // necessary to create the mask
+ m_mask.resize( width(), height() );
+ // make the mask empty and hence will not show widget with show() called below
+ dissolveMask();
+ m_timerId = startTimer( 1000 / 30 );
+ }
+ else
+ {
+ m_timerId = startTimer( 1 );
+ }
+ show();
+}
+
+////////////////////////////////////////////////////////////////////////
+// Protected
+////////////////////////////////////////////////////////////////////////
+
+void PopupMessage::timerEvent( QTimerEvent* )
+{
+ switch( m_maskEffect )
+ {
+ case Plain:
+ plainMask();
+ break;
+
+ case Slide:
+ slideMask();
+ break;
+
+ case Dissolve:
+ dissolveMask();
+ break;
+ }
+}
+
+void PopupMessage::countDown()
+{
+ if( !m_timeout )
+ {
+ killTimer( m_timerId );
+ return;
+ }
+
+ QFrame *&h = m_countdownFrame;
+
+ if( m_counter < h->height() - 3 )
+ QPainter( h ).fillRect( 2, 2, h->width() - 4, m_counter, palette().active().highlight() );
+
+ if( !hasMouse() )
+ m_counter++;
+
+ if( m_counter > h->height() )
+ {
+ m_stage = 3;
+ killTimer( m_timerId );
+ m_timerId = startTimer( 1 );
+ }
+ else
+ {
+ killTimer( m_timerId );
+ m_timerId = startTimer( m_timeout / h->height() );
+ }
+}
+
+void PopupMessage::dissolveMask()
+{
+ if( m_stage == 1 )
+ {
+ repaint( false );
+ QPainter maskPainter(&m_mask);
+
+ m_mask.fill(Qt::black);
+
+ maskPainter.setBrush(Qt::white);
+ maskPainter.setPen(Qt::white);
+ maskPainter.drawRect( m_mask.rect() );
+
+ m_dissolveSize += m_dissolveDelta;
+
+ if( m_dissolveSize > 0 )
+ {
+ maskPainter.setRasterOp( Qt::EraseROP );
+
+ int x, y, s;
+ const int size = 16;
+
+ for (y = 0; y < height() + size; y += size)
+ {
+ x = width();
+ s = m_dissolveSize * x / 128;
+
+ for ( ; x > size; x -= size, s -= 2 )
+ {
+ if (s < 0)
+ break;
+
+ maskPainter.drawEllipse(x - s / 2, y - s / 2, s, s);
+ }
+ }
+ }
+ else if( m_dissolveSize < 0 )
+ {
+ m_dissolveDelta = 1;
+ killTimer( m_timerId );
+
+ if( m_timeout )
+ {
+ m_timerId = startTimer( 40 );
+ m_stage = 2;
+ }
+ }
+
+ setMask(m_mask);
+ }
+ else if ( m_stage == 2 )
+ {
+ countDown();
+ }
+ else
+ {
+ if (!m_respondedTo)
+ emit Closed();
+ deleteLater();
+ }
+}
+
+
+void PopupMessage::plainMask()
+{
+ switch( m_stage )
+ {
+ case 1: // Raise
+ killTimer( m_timerId );
+ if( m_timeout )
+ {
+ m_timerId = startTimer( 40 );
+ m_stage = 2;
+ }
+
+ break;
+
+ case 2: // Counter
+ countDown();
+ break;
+
+ case 3: // Lower/Remove
+ if (!m_respondedTo)
+ emit Closed();
+ deleteLater();
+ }
+}
+
+
+void PopupMessage::slideMask()
+{
+ switch( m_stage )
+ {
+ case 1: //raise
+ move( 0, m_parent->y() - m_offset );
+
+ m_offset=m_offset + 5;
+ if( m_offset > height() )
+ {
+ killTimer( m_timerId );
+
+ if( m_timeout )
+ {
+ m_timerId = startTimer( 40 );
+ m_stage = 2;
+ }
+ }
+
+ break;
+
+ case 2: //fill in pause timer bar
+ countDown();
+ break;
+
+ case 3: //lower
+ m_offset=m_offset-5;
+ move( 0, m_parent->y() - m_offset );
+
+ if( m_offset < 0 ){
+ if (!m_respondedTo)
+ emit Closed();
+ deleteLater();
+ }
+ }
+}
+
+}
+
+#include "popupMessage.moc"
diff --git a/src/popupMessage.h b/src/popupMessage.h
new file mode 100644
index 0000000..9dc73b7
--- /dev/null
+++ b/src/popupMessage.h
@@ -0,0 +1,123 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Max Howell <max.howell@methylblue.com> *
+ * 2005 by Seb Ruiz <me@sebruiz.net> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+
+//WARNING this is not meant for use outside this unit!
+
+
+#ifndef KDE_POPUPMESSAGE_H
+#define KDE_POPUPMESSAGE_H
+
+#include "overlayWidget.h"
+//#include "functor.h"
+
+#include <qbitmap.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+
+namespace KDE
+{
+ /**
+ * @class PopupMessage
+ * @short Widget that animates itself into a position relative to an anchor widget
+ */
+ class PopupMessage : public OverlayWidget
+ {
+ Q_OBJECT
+
+ signals:
+ void yesClicked();
+ void noClicked();
+ void Closed();
+
+ public:
+ /**
+ * @param anchor : which widget to tie the popup widget to.
+ * @param timeout : how long to wait before auto closing. A value of 0 means close
+ * only on pressing the closeButton or close() is called.
+ */
+ PopupMessage( QWidget *parent, QWidget *anchor, int timeout = 5000 /*milliseconds*/, const char* name = 0 );
+
+ enum MaskEffect { Plain, Slide, Dissolve };
+
+ void addWidget( QWidget *widget );
+ void showBothButton( const bool show );
+ void showOkButton( const bool show );
+ void showCounter( const bool show );
+ void setImage( const QString &location );
+ void setImage( const QPixmap &pix );
+ void setMaskEffect( const MaskEffect type ) { m_maskEffect = type; }
+ void setText( const QString &text );
+ void setTimeout( const int time ) { m_timeout = time; }
+
+ public slots:
+ void close();
+ void yes();
+ void no();
+ void display();
+ void toggled( bool );
+
+ protected:
+ void timerEvent( QTimerEvent* );
+ void countDown();
+
+ /**
+ * @short Gradually show widget by dissolving from background
+ */
+ void dissolveMask();
+
+ /**
+ * @short instantly display widget
+ */
+ void plainMask();
+
+ /**
+ * @short animation to slide the widget into view
+ */
+ void slideMask();
+
+ private:
+
+ bool configurableType();
+ QVBoxLayout *m_layout;
+ QFrame *m_countdownFrame;
+ QWidget *m_anchor;
+ QWidget *m_parent;
+ QBitmap m_mask;
+ MaskEffect m_maskEffect;
+
+ int m_dissolveSize;
+ int m_dissolveDelta;
+
+ int m_offset;
+ int m_counter;
+ int m_stage;
+ int m_timeout;
+ int m_timerId;
+
+ bool m_showCounter;
+ bool m_question;
+ bool m_respondedTo;
+
+ QString m_name;
+ };
+}
+
+#endif
diff --git a/src/portsandicons.h b/src/portsandicons.h
new file mode 100644
index 0000000..a55ee55
--- /dev/null
+++ b/src/portsandicons.h
@@ -0,0 +1,72 @@
+/***************************************************************************
+** $Id: portsandicons.h,v 1.15 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * Based on config method in Tor
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+/** Enumeration of types which option values can take */
+typedef enum display_once_t {
+ DISPLAY = 0, /**< An arbitrary string. */
+ DONT_DISPLAY_AGAIN, /**< A non-negative integer less than MAX_INT */
+} display_once_t;
+
+typedef struct portsandicons_t {
+ const char *port; /**< The full keyword (case insensitive). */
+ const char *icon; /**< String (or null) describing initial value. */
+ int secure; /**< String (or null) describing initial value. */
+ int screaminglyinsecure; /**< String (or null) describing initial value. */
+ display_once_t display;
+} portsandicons_t;
+
+
+#define MSG(port,icon,secure, screaminglyinsecure, display) \
+ { port,icon,secure, screaminglyinsecure,display }
+
+static portsandicons_t _port_icon[] = {
+ MSG("80","konqueror", 0,0 , DISPLAY),
+ MSG("443","tork_konqueror_https",1 ,0 , DISPLAY),
+ MSG("http","konqueror",0 ,0 , DISPLAY),
+ MSG("https","tork_konqueror_https",1 ,0 , DISPLAY),
+ MSG("21","ftp",0 , 1 ,DISPLAY),
+ MSG("22","tork_konsole_https",1 ,0 , DISPLAY),
+ MSG("ssh","tork_konsole_https",1 ,0 , DISPLAY),
+ MSG("telnet","konsole",0 ,1 , DISPLAY),
+ MSG("23","konsole",0 ,1 , DISPLAY),
+ MSG("25","tork_mail",0 ,1 , DISPLAY),
+ MSG("smtp","tork_mail",0 ,1 , DISPLAY),
+ MSG("53","error",0 ,0 , DISPLAY),
+ MSG("domain","error",0 ,0 , DISPLAY),
+ MSG("110","tork_mail",0 ,1 , DISPLAY),
+ MSG("pop3","tork_mail",0 ,1 , DISPLAY),
+ MSG("1863","tork_msn_protocol",0 ,0 , DISPLAY),
+ MSG("mmcc","tork_yahoo_protocol",0 ,0 , DISPLAY),
+ MSG("5050","tork_yahoo_protocol",0 ,0 , DISPLAY),
+ MSG("6667","tork_irc_protocol",0 ,0 , DISPLAY),
+ MSG("ircd","tork_irc_protocol",0 ,0 , DISPLAY),
+ MSG("9030","tork_tor",1 , 0 ,DISPLAY),
+ MSG("9031","tork_tor",1 , 0 ,DISPLAY),
+ MSG("9032","tork_tor",1 , 0 ,DISPLAY),
+ MSG("9001","tork_tor",1 , 0 ,DISPLAY),
+ MSG("9051","tork_tor",1 , 0 ,DISPLAY),
+ MSG("9050","tork_tor",1 , 0 ,DISPLAY),
+ { NULL, NULL, 0, 0, DISPLAY }
+};
+#undef MSG
+
diff --git a/src/portsandnames.h b/src/portsandnames.h
new file mode 100644
index 0000000..e5f1c40
--- /dev/null
+++ b/src/portsandnames.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+** $Id: portsandnames.h,v 1.3 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * Based on config method in Tor
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+typedef struct portsandnames_t {
+ const char *port; /**< The full keyword (case insensitive). */
+ const char *name; /**< String (or null) describing initial value. */
+} portsandnames_t;
+
+
+#define MSG(port,icon) \
+ { port,icon }
+
+static portsandnames_t _port_name[] = {
+ MSG("21","ftp"),
+ MSG("22","ssh"),
+ MSG("23","telnet"),
+ MSG("5050","msn"),
+ MSG("5190","aol"),
+ MSG("5222","jabber"),
+ MSG("6667","irc"),
+ { NULL, NULL }
+};
+#undef MSG
+
diff --git a/src/privoxytemplates/Makefile.am b/src/privoxytemplates/Makefile.am
new file mode 100644
index 0000000..ed754df
--- /dev/null
+++ b/src/privoxytemplates/Makefile.am
@@ -0,0 +1,34 @@
+privoxy_DATA = \
+ blocked \
+ cgi-error-404 \
+ cgi-error-bad-param \
+ cgi-error-disabled \
+ cgi-error-file \
+ cgi-error-modified \
+ cgi-error-parse \
+ cgi-style.css \
+ connect-failed \
+ default \
+ edit-actions-add-url-form \
+ edit-actions-for-url \
+ edit-actions-for-url-filter \
+ edit-actions-list \
+ edit-actions-list-section \
+ edit-actions-list-url \
+ edit-actions-remove-url-form \
+ edit-actions-url-form \
+ mod-local-help \
+ mod-support-and-service \
+ mod-title \
+ mod-unstable-warning \
+ no-such-domain \
+ show-request \
+ show-status \
+ show-status-file \
+ show-url-info \
+ show-version \
+ toggle \
+ toggle-mini \
+ untrusted
+
+privoxydir = $(kde_datadir)/tork/privoxy/templates
diff --git a/src/privoxytemplates/blocked b/src/privoxytemplates/blocked
new file mode 100644
index 0000000..e323b9e
--- /dev/null
+++ b/src/privoxytemplates/blocked
@@ -0,0 +1,270 @@
+##########################################################
+#
+# "Blocked" Error Output template for Privoxy.
+#
+# NOTE: UNLIKE THE OTHER TEMPLATES, THIS ONE USES
+# JavaScript write() TO GENERATE THE PAGE IN JS_AWARE
+# BROWSERS. SYMBOL SUBSTITUTIONS THAT RESULT IN MULTILINE
+# STRINGS WILL BREAK THE JavaScript SYNTAX.
+# USE WITH CAUTION.
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written in plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# protocol:
+# The request's protocol: http:// or https://
+# hostport:
+# The host and port part of the request that lead to this problem
+# path:
+# The path part of the request that lead to this problem
+#
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# This is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+# force-support:
+# Privoxy has been compiled with support for forced loading
+# of blocked content. In that case, the symbol "force-prefix" is
+# avaiable, which translates to the FORCE_PREFIX
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <title>Request blocked (Privoxy@@my-hostname@)</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+ <script type="text/javascript" language="javascript">
+ <!--
+ /*
+ * Is this window or frame too small
+ * for the full-blown "blocked" page?
+ */
+ function isSmallFrame()
+ {
+ minWidth = 650;
+ minHeight = 330;
+
+ /*
+ * Navigator, Mozilla, Opera
+ */
+ if (window.innerWidth
+ && (window.innerWidth >= minWidth)
+ && (window.innerHeight >= minHeight))
+ {
+ return false;
+ }
+
+ /*
+ * MSIE
+ */
+ else if (document.body && document.body.clientWidth
+ && (document.body.clientWidth >= minWidth)
+ && (document.body.clientHeight >= minHeight))
+ {
+ return false;
+ }
+
+ /*
+ * Small window or unsupported browser
+ */
+ return true;
+ }
+ //-->
+ </script>
+ </head>
+ <body>
+ <script type="text/javascript" language="javascript">
+ <!--
+# Note: The same small version is used at the bottom
+# of this file in the <noscript> context. If you
+# make changes here, keep the other version in sync!
+
+ if (isSmallFrame())
+ {
+ document.write('\
+ <p class="small" align="center"> \
+ <a href="@default-cgi@" target="_blank">Privoxy</a> blocked <b>@protocol@@hostport@@path@</b>. \
+ <br><a href="@default-cgi@show-url-info?url=@hostport@@path@" target="_blank">See why</a> \
+ <!-- @if-force-support-start --> \
+ or <a href="http://@hostport@@force-prefix@@path@">go there anyway</a>. \
+ <!-- if-force-support-end@ --> \
+ </p> \
+ ');
+
+ }
+ else
+ {
+ document.write('\
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">\
+ <tr> \
+ <td class="status"> \
+ BLOCKED \
+ </td> \
+ <td class="title" width=100%> \
+ <h1> \
+ This is <a href="@homepage@">Privoxy</a> @version@ on @my-hostname@ (@my-ip-address@), port @my-port@, \
+ @if-enabled-display-then@enabled@else-not-enabled-display@disabled@endif-enabled-display@ \
+ </h1> \
+ </td> \
+ </tr> \
+ \
+<!-- @if-unstable-start --> \
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in \
+ <tr> \
+ <td class="warning" colspan="2"> \
+ <h2>Warning:</h2> \
+ <p> \
+ <b>Please note that this <font color=red>@code-status@</font> release \
+ of the proxy software is not intended for production systems! \
+ <br>Use at your own risk. See the <a href="http://www.gnu.org/copyleft/gpl.html">license</a> for details.</b> \
+ </p> \
+ </td> \
+ </tr> \
+<!-- if-unstable-end@ --> \
+ \
+ <tr> \
+ <td class="box" colspan="2"> \
+ <h2>Request for blocked URL</h2> \
+ <p>Your request for <b>@protocol@@hostport@@path@</b> was blocked. \
+ <br><a href="@default-cgi@show-url-info?url=@hostport@@path@">See why</a> \
+ <!-- @if-force-support-start --> \
+ or <a href="http://@hostport@@force-prefix@@path@">go there anyway</a>. \
+<!-- if-force-support-end@ --> \
+ </p> \
+ </td> \
+ </tr> \
+ \
+ <tr> \
+ <td class="box" colspan="2"> \
+ <h2>More Privoxy:</h2> \
+ <ul>@menu@</ul> \
+ </td> \
+ </tr> \
+ \
+ <tr> \
+ <td class="info" colspan="2"> \
+ <big><b>Support and Service via Sourceforge:</b></big> \
+ <p> \
+ We value your feedback. To provide you with the best support, \
+ we ask that you: \
+ </p> \
+ <ul> \
+ <li> \
+ use the <a href="http://sourceforge.net/tracker/?group_id=11118&amp;atid=211118">support forum</a> or (better) the \
+ <a href="http://sourceforge.net/mail/?group_id=11118">mailing lists</a> to get help. \
+ </li> \
+ <li> \
+ submit banners and all problems with the actions file only through the \
+ <a href="javascript:void(window.open(\'http://www.privoxy.org/actions\',\'Feedback\',\'width=600,scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no\').focus());">actions \
+ file feedback system</a>. \
+ </li> \
+ <li> \
+ submit bugs only through our <a href="http://sourceforge.net/tracker/?group_id=11118&amp;atid=111118">bug tracker</a>. \
+ Make sure that the bug has not yet been submitted. \
+ </li> \
+ <li> \
+ submit feature requests only through our <a href="http://sourceforge.net/tracker/?atid=361118&amp;group_id=11118&amp;func=browse">feature \
+ request tracker</a>. \
+ </li> \
+ </ul> \
+ </td> \
+ </tr> \
+ \
+<!-- @if-have-help-info-start --> \
+ <tr> \
+ <td class="info" colspan="2"> \
+ <h2>Local Privoxy support:</h2> \
+ \
+<!-- @if-have-proxy-info-start --> \
+ <p>You can consult the <a href="@proxy-info-url@">online documentation</a> for more information about this Privoxy installation.</p> \
+<!-- if-have-proxy-info-end@ --> \
+ \
+<!-- @if-have-adminaddr-info-start --> \
+ <p>Address e-mail questions about this service to \
+ <a href="mailto:@admin-address@"><code>@admin-address@</code></a>, \
+ who will be glad to help you. \
+ </p> \
+<!-- if-have-adminaddr-info-end@ --> \
+ </td> \
+ </tr> \
+<!-- if-have-help-info-end@ --> \
+ \
+ </table> \
+ ');
+ }
+ //-->
+ </script>
+
+# Note: The same small version is used above via JavaScript
+# If you make changes here, keep the other version in sync!
+
+ <noscript>
+ <p class="small" align="center">
+ <a href="@default-cgi@" target="_blank">Privoxy</a> blocked <b>@protocol@@hostport@@path@</b>.
+ <br><a href="@default-cgi@show-url-info?url=@hostport@@path@" target="_blank">See why</a>
+ <!-- @if-force-support-start -->
+ or <a href="http://@hostport@@force-prefix@@path@">go there anyway</a>.
+ <!-- if-force-support-end@ -->
+ </p>
+ </noscript>
+
+ </body>
+</html>
diff --git a/src/privoxytemplates/cgi-error-404 b/src/privoxytemplates/cgi-error-404
new file mode 100644
index 0000000..ee70d49
--- /dev/null
+++ b/src/privoxytemplates/cgi-error-404
@@ -0,0 +1,154 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>404 - Privoxy Configuration Page not found</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="status">
+ 404
+ </td>
+ <td class="title" style="width: 100%">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning" colspan="2">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="warning" colspan="2">
+ <h2>Privoxy Configuration page not found</h2>
+ <p>You typed in what looks like a URL used to configure
+ Privoxy, but it cannot be recognised. Maybe it's
+ for a different Privoxy version, or you typed it
+ in wrong? Or maybe the Privoxy administrator
+ has decided to disable the feature.</p>
+ <p>If you got here by clicking a link in the
+ configuration interface, please file a bug report!</p>
+ <p>You can use the menu below to select from the available
+ configuration options</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box" colspan="2">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info" colspan="2">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info" colspan="2">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td colspan="2">
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/cgi-error-bad-param b/src/privoxytemplates/cgi-error-bad-param
new file mode 100644
index 0000000..a9803db
--- /dev/null
+++ b/src/privoxytemplates/cgi-error-bad-param
@@ -0,0 +1,161 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Privoxy: Bad parameter</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="warning">
+ <h2>Bad parameter to Privoxy configuration page</h2>
+ <p>You've found a page used to configure Privoxy, but the
+ parameters (the part of the web page address after the
+ "?" mark) are wrong or missing.</p>
+ <p>Possible causes:</p>
+ <ul>
+ <li>If you just typed a URL pattern into a form, then you got
+ something wrong. Press the "back" button on your browser
+ once and correct what you typed.</li>
+ <li>If you tried to type in the URL, then you've found a
+ page where you can't do that. You can only view this
+ page by following links from elsewhere in the configuration
+ interface.</li>
+ <li>If you got here using your browser's "back" button, then
+ that is deliberately disabled for this page.</li>
+ <li>If you got here by clicking a link in the
+ configuration interface, please file a bug report!</li>
+ </ul>
+ <p>You can use the menu below to select from the available
+ configuration options</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>Privoxy Menu:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/cgi-error-disabled b/src/privoxytemplates/cgi-error-disabled
new file mode 100644
index 0000000..fd7f01f
--- /dev/null
+++ b/src/privoxytemplates/cgi-error-disabled
@@ -0,0 +1,148 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Configuration Page Disabled</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="warning">
+ <h2>Privoxy Configuration page diasabled</h2>
+ <p>The Privoxy administrator has decided to disable this
+ feature. If you want to use it, you must ask them to
+ enable it.</p>
+ <p>If you are the Privoxy administrator, you can enable
+ this feature by changing the appropriate line in your
+ configuration file.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/cgi-error-file b/src/privoxytemplates/cgi-error-file
new file mode 100644
index 0000000..dab262a
--- /dev/null
+++ b/src/privoxytemplates/cgi-error-file
@@ -0,0 +1,138 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Privoxy: Actions file not found</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="warning">
+ <h2>Actions file not found</h2>
+ <p>The actions file you are trying to edit (<code>@f@.action</code>)
+ does not exist, or cannot be read.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>Privoxy Menu:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/cgi-error-modified b/src/privoxytemplates/cgi-error-modified
new file mode 100644
index 0000000..c42bc69
--- /dev/null
+++ b/src/privoxytemplates/cgi-error-modified
@@ -0,0 +1,162 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Privoxy: URL out of date</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="warning">
+ <h2>URL out of date - file has changed since it was generated</h2>
+ <p>The URL you're viewing is out of date. To prevent possible
+ damage to your configuration file, this action has been ignored.
+ </p>
+ <p>Possible causes:</p>
+ <ul>
+ <li>If you got here using your browser's "back" button, then
+ that is deliberately disabled for this page. Please
+ navigate around the configuration editor using the
+ links provided.</li>
+ <li>Perhaps you've got more than one browser window open, and
+ you're trying to change the same file in both? You can
+ only have one editor window open at a time. Your other edit
+ window should continue to function.</li>
+ <li>You may have modified the file some other way - perhaps by
+ editing it with a text editor. Simply go back in to the
+ configuration interface using the links below.</li>
+ </ul>
+ <p>You can go back into the edit interface using the menu below,
+ or by clicking <a href="edit-actions-list?f=@f@">here</a>.
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/cgi-error-parse b/src/privoxytemplates/cgi-error-parse
new file mode 100644
index 0000000..723eb67
--- /dev/null
+++ b/src/privoxytemplates/cgi-error-parse
@@ -0,0 +1,175 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Privoxy: Parse error</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="warning">
+ <h2>Parse error</h2>
+ <p>The file you're trying to edit is not valid. You need to fix
+ it using a text editor before you can edit it using the
+ web-based editor.</p>
+ <p>This error should only occur if you edited the file using a text
+ editor. If you managed to take a valid file and break it this
+ badly using the web-based editor, please file a bug report!</p>
+ <p>When you've fixed the problem, you can go back into the edit
+ interface using the menu below, or by clicking <a
+ href="edit-actions-list?f=@f@">here</a>.
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>Problem description:</h2>
+ <p>@parse-error@</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>The line which caused the problem:</h2>
+ <pre>@line-raw@</pre>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>The line which caused the problem, with comments removed</h2>
+ <p><code>@line-data@</code></p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>Note</h2>
+ <p>Only the first error is reported - the file may contain other
+ errors, as well as the one reported above.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/cgi-style.css b/src/privoxytemplates/cgi-style.css
new file mode 100644
index 0000000..487ae34
--- /dev/null
+++ b/src/privoxytemplates/cgi-style.css
@@ -0,0 +1,69 @@
+/*
+ * CSS for Privoxy CGI and script output
+ *
+ * $Id: cgi-style.css,v 1.1 2007/01/01 17:52:38 hoganrobert Exp $
+ */
+
+/*
+ * General rules: Font, Color, Headings, Margins, Links
+ */
+body,td,th { font-family: arial, helvetica, helv, sans-serif; }
+body { background-color: #ffffff; color: #000000; }
+
+h1 { font-size: 140%; margin: 0px; }
+h2 { font-size: 120%; margin: 0px; }
+h3 { font-size: 110%; margin: 0px; }
+
+p,pre { margin-left: 15px; }
+li { margin: 2px 15px; }
+dl { margin: 2px 15px; }
+
+a:link { color: #0000dd; text-decoration: none; }
+a:visited { color: #330099; text-decoration: none; }
+a:active { color: #3333ff; text-decoration: none; }
+
+/*
+ * Boxen as Table elements:
+ */
+td.title { border: solid black 1px; background-color: #dddddd; }
+td.box { border: solid black 1px; background-color: #eeeeee; }
+td.info { border: solid black 1px; background-color: #ccccff; }
+td.warning { border: solid black 1px; background-color: #ffdddd; }
+
+/*
+ * Special Table Boxen: for nesting, naked container and for
+ * the Status field in CGI Output:
+ */
+td.wrapbox { border: solid black 1px; padding: 5px; }
+td.container { padding: 0px; }
+td.status { border: solid black 1px; background-color: #ff0000; color: #ffffff; font-size: 300%; font-weight: bolder; }
+
+/*
+ * Same Boxen as <div>s:
+ */
+div.title { border: solid black 1px; background-color: #dddddd; margin: 20px; padding: 20px; }
+div.box { border: solid black 1px; background-color: #eeeeee; margin: 20px; padding: 20px; }
+div.info { border: solid black 1px; background-color: #ccccff; margin: 20px; padding: 20px; }
+div.warning { border: solid black 1px; background-color: #ffdddd; margin: 20px; padding: 20px; }
+div.wrapbox { border: solid black 1px; margin: 20px; padding: 5px; }
+
+
+/*
+ * Bold definitions in <dl>s, Grey BG for Table headings
+ */
+dt { font-weight: bold; }
+th { background-color: #dddddd; }
+
+/*
+ * Special purpose paragraphs: Small for page footers,
+ * Important for quoting wrong or dangerous examples,
+ * Whiteframed for the toggle?mini=y CGI
+ */
+p.small { font-size: 10px; margin: 0px; }
+p.important { border: solid black 1px; background-color: #ffdddd; font-weight: bold; padding: 2px; }
+p.whiteframed { margin: 5px; padding: 5px; border: solid black 1px; text-align: center; background-color: #eeeeee; }
+
+/*
+ * Special red emphasis:
+ */
+em.warning { color: #ff0000 }
diff --git a/src/privoxytemplates/connect-failed b/src/privoxytemplates/connect-failed
new file mode 100644
index 0000000..8e6de60
--- /dev/null
+++ b/src/privoxytemplates/connect-failed
@@ -0,0 +1,159 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# host-ip:
+# The IP address of the host that could not be reached
+# hostport:
+# The host and port part of the request that lead to this problem
+# path:
+# The path part of the request that lead to this problem
+#
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>503 - Connect failed (Privoxy@@my-hostname@)</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="status">
+ 503
+ </td>
+ <td class="title" style="width: 100%">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning" colspan="2">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="warning" colspan=2>
+ <h2>Connect failed</h2>
+ <p>Your request for <a href="@protocol@@hostport@@path@"><b>@protocol@@hostport@@path@</b></a> could
+ not be fulfilled, because the connection to <b>@host@</b> (@host-ip@) could not be established.
+ </p>
+ <p>This is often a temporary failiure, so you might just
+ <a href="@protocol@@hostport@@path@">try again</a>.
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box" colspan="2">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info" colspan="2">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info" colspan="2">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td colspan="2">
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/default b/src/privoxytemplates/default
new file mode 100644
index 0000000..f11c3f6
--- /dev/null
+++ b/src/privoxytemplates/default
@@ -0,0 +1,136 @@
+##########################################################
+#
+# Default-CGI Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Privoxy@@my-hostname@</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>Privoxy Menu:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/edit-actions-add-url-form b/src/privoxytemplates/edit-actions-add-url-form
new file mode 100644
index 0000000..51eb89b
--- /dev/null
+++ b/src/privoxytemplates/edit-actions-add-url-form
@@ -0,0 +1,205 @@
+##############################################################################
+#
+# File : $Source: /cvsroot/tork/tork/src/privoxytemplates/edit-actions-add-url-form,v $
+#
+# Purpose : Template used to add a URL pattern to the actions file.
+#
+#
+# Copyright : Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Original Author: Copyright (C) 2001 Jonathan Foster
+# http://www.jon-foster.co.uk/
+#
+# This program is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file. If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Revisions :
+# $Log: edit-actions-add-url-form,v $
+# Revision 1.1 2007/01/01 17:52:53 hoganrobert
+# *** empty log message ***
+#
+# Revision 1.13 2002/04/10 13:32:53 oes
+# Made templates modular
+#
+# Revision 1.12 2002/04/08 17:08:14 oes
+# Cosmetic: make status in title lowercase
+#
+# Revision 1.11 2002/04/05 16:01:33 oes
+# Correct HTML, external Stylesheets, eye candy, some fixes
+#
+# Revision 1.10 2002/03/26 22:29:56 swa
+# we have a new homepage!
+#
+# Revision 1.9 2002/03/24 15:23:33 jongfoster
+# Name changes
+#
+# Revision 1.8 2002/03/24 11:01:06 swa
+# name change
+#
+# Revision 1.7 2002/03/23 16:18:15 swa
+# renamed every reference to the old name with foobar.
+# fixed "application foobar application" tag, fixed
+# "the foobar" with "foobar". left junkbuster in cvs
+# comments and remarks to history untouched. should
+# make final rename easier.
+#
+# Revision 1.6 2002/03/16 15:22:19 jongfoster
+# Moving 'alpha' warning to the end of the page
+#
+# Revision 1.5 2002/03/03 10:29:12 swa
+# point users to the right feedback forms,
+# not necessarily the developer list.
+#
+# Revision 1.4 2002/01/23 00:26:45 jongfoster
+# Reducing length of URLs
+# Where encoded and unencoded versions of a string existed, removing
+# the unencoded one.
+#
+# Revision 1.3 2002/01/17 21:33:00 jongfoster
+# Replacing all references to the URL of the config interface
+# with @default-cgi@
+#
+# Revision 1.2 2002/01/17 21:21:03 jongfoster
+# DOS->Unix line endings
+#
+# Revision 1.1 2001/11/13 00:58:18 jongfoster
+# New version of actions file editor templates
+#
+#
+##############################################################################
+#
+# Standard support:
+#
+# This file currently produces valid HTML 4.01 Strict.
+#
+# If you change it, please save the generated page from your web browser
+# and then upload it to http://validator.w3.org/ for checking.
+#
+#############################################################################
+#
+# Available variables include:
+#
+# filename
+# ver
+# section
+#
+#############################################################################
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+
+ <title>Privoxy@@my-hostname@: Edit URL Pattern</title>
+
+ <script type="text/javascript">
+<!--
+ function validate(text)
+ {
+ if (text=="")
+ {
+ alert("You need to type a pattern in order to continue!");
+ return false;
+ }
+
+ return true;
+}
+//-->
+ </script>
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>Add URL Pattern</h2>
+ <form method="GET" action="edit-actions-add-url"
+ onSubmit="return validate(u.value);">
+ <p>
+ <input type="hidden" name="f" value="@f@">
+ <input type="hidden" name="v" value="@v@">
+ <input type="hidden" name="s" value="@s@">
+ <input type="text" name="u" value="" size="78"><br>
+ <input type="submit" value="Submit"> &nbsp;
+ <input type="reset" value="Reset"> &nbsp;
+ <a href="edit-actions-list?f=@f@">Cancel</a>
+ </p>
+ </form>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+
+ </table>
+
+</body>
+</html>
+
diff --git a/src/privoxytemplates/edit-actions-for-url b/src/privoxytemplates/edit-actions-for-url
new file mode 100644
index 0000000..0941264
--- /dev/null
+++ b/src/privoxytemplates/edit-actions-for-url
@@ -0,0 +1,863 @@
+##############################################################################
+#
+# File : $Source: /cvsroot/tork/tork/src/privoxytemplates/edit-actions-for-url,v $
+#
+# Purpose : Template used to edit the actions associated with a
+# particular section in an actions file.
+#
+#
+# Copyright : Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Original Author: Copyright (C) 2001 Jonathan Foster
+# http://www.jon-foster.co.uk/
+#
+# This program is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file. If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Revisions :
+# $Log: edit-actions-for-url,v $
+# Revision 1.1 2007/01/01 17:53:02 hoganrobert
+# *** empty log message ***
+#
+# Revision 1.22 2002/04/10 13:32:53 oes
+# Made templates modular
+#
+# Revision 1.21 2002/04/08 17:05:18 oes
+# Inline a style exception
+#
+# Revision 1.20 2002/04/05 16:01:30 oes
+# Correct HTML, external Stylesheets, eye candy, some fixes
+#
+# Revision 1.19 2002/03/26 22:29:56 swa
+# we have a new homepage!
+#
+# Revision 1.18 2002/03/24 16:32:08 jongfoster
+# Removing logo option
+#
+# Revision 1.17 2002/03/24 15:23:33 jongfoster
+# Name changes
+#
+# Revision 1.16 2002/03/24 11:01:06 swa
+# name change
+#
+# Revision 1.15 2002/03/23 16:18:15 swa
+# renamed every reference to the old name with foobar.
+# fixed "application foobar application" tag, fixed
+# "the foobar" with "foobar". left junkbuster in cvs
+# comments and remarks to history untouched. should
+# make final rename easier.
+#
+# Revision 1.14 2002/03/16 15:22:19 jongfoster
+# Moving 'alpha' warning to the end of the page
+#
+# Revision 1.13 2002/03/16 14:28:38 jongfoster
+# First version of modular filters support
+#
+# Revision 1.12 2002/03/12 01:42:50 oes
+# Introduced modular filters
+#
+# Revision 1.11 2002/03/08 18:19:14 jongfoster
+# Adding +image-blocker{pattern} option to edit interface
+#
+# Revision 1.10 2002/03/03 10:29:12 swa
+# point users to the right feedback forms,
+# not necessarily the developer list.
+#
+# Revision 1.9 2002/01/23 00:26:45 jongfoster
+# Reducing length of URLs
+# Where encoded and unencoded versions of a string existed, removing
+# the unencoded one.
+#
+# Revision 1.8 2002/01/17 21:33:00 jongfoster
+# Replacing all references to the URL of the config interface
+# with @default-cgi@
+#
+# Revision 1.7 2002/01/17 21:21:03 jongfoster
+# DOS->Unix line endings
+#
+# Revision 1.6 2001/11/22 21:58:41 jongfoster
+# Adding action +no-cookies-keep
+#
+# Revision 1.5 2001/11/13 21:12:17 jongfoster
+# Added support for the following actions:
+# +downgrade, +limit-connect, +no-compression
+#
+# Revision 1.4 2001/11/13 00:58:18 jongfoster
+# New version of actions file editor templates
+#
+#
+##############################################################################
+#
+# Browser support for the JavaScript on this page:
+# MS Internet Explorer 5.5 - Tested, Yes
+# Netscape 6.0 - Tested, Yes
+# Netscape 4.75 - Tested, NO
+# Opera 5.12 - Tested, NO
+# MS Internet Explorer 4+ - Untested, Yes
+# MS IE 3.x, NS3.x - Untested, NO
+# Mozilla >=0.6 - Untested, Yes
+#
+# All browsers should work, you just might not get the pretty DHTML effects.
+#
+# The effects that only work under the browsers marked "Yes" above are:
+# - Text edit boxes that won't have any effect are disabled.
+# - Table rows containing additional settings are hidden if the feature in
+# question is disabled.
+#
+# There are major kludges to get around these problems with NS4, but they
+# screw up the HTML too much for other browsers. If anyone wants to try,
+# here's some descriptions of the kludges:
+# http://www.webreference.com/js/tips/991114.html
+# http://www.webreference.com/dhtml/column12/outDisplay.html
+#
+# If you're favorite browser isn't listed, please test and add it.
+#
+#
+#############################################################################
+#
+# Standard support:
+#
+# This file currently produces valid HTML 4.01 Strict.
+#
+# If you change it, please save the generated page from your web browser
+# and then upload it to http://validator.w3.org/ for checking.
+#
+#############################################################################
+#
+# Available variables include:
+#
+# action-name-y
+# action-name-n
+# action-name-x
+#
+# deanimate-gifs-param-first
+# deanimate-gifs-param-last
+# hide-from-param-block
+# hide-from-param-custom
+# hide-from-param
+# hide-referer-param-forge
+# hide-referer-param-block
+# hide-referer-param-custom
+# hide-referer-param
+# hide-user-agent-param
+# image-blocker-param-pattern
+# image-blocker-param-blank
+# image-blocker-param-custom
+#
+#
+#############################################################################
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+
+ <title>Privoxy@@my-hostname@: Edit actions</title>
+
+<style type="text/css">
+td.action { font-weight: bold;
+ font-style: italic;
+ white-space: nowrap }
+td.subaction { font-style: italic }
+th { font-weight: bold; }
+# This is the key to the color names below:
+# bg=background, en="Enable", dis="Disable", noc="No Change", hdr=header
+# 1=odd rows, 2=even rows, h=Table header
+tr.hdr { background-color: #999999 }
+tr.bg1 { background-color: #eeeeee }
+td.en1 { background-color: #eeffee }
+td.dis1 { background-color: #ffeeee }
+td.noc1 { background-color: #eeeeff }
+tr.bg2 { background-color: #dddddd }
+td.en2 { background-color: #ddffdd }
+td.dis2 { background-color: #ffdddd }
+td.noc2 { background-color: #ddddff }
+th.enh { background-color: #99ff99 }
+th.dish { background-color: #ff9999 }
+th.noch { background-color: #9999ff }
+table.wide { padding: 5px; }
+td.green { border: solid black 1px; background-color: #ddffdd; }
+</style>
+
+<!--
+border-color: white;
+ border-style: solid;
+ border-left-width: 10px;
+ border-right-width: 10px;
+ border-top-width: 0px;
+ border-bottom-width: 0px }
+-->
+
+<script type="text/javascript">
+<!--
+
+function hide_from_param_disable(tf)
+{
+ if (document.getElementById) {
+ // NS6 or IE5
+ document.getElementById("hide_from_param").disabled = tf;
+ } else if (document.all) {
+ // IE4
+ document.myform.hide_from_param.disabled = tf;
+ }
+}
+
+function hide_referer_param_disable(tf)
+{
+ if (document.getElementById) {
+ document.getElementById("hide_referer_param").disabled = tf;
+ } else if (document.all) {
+ document.myform.hide_referer_param.disabled = tf;
+ }
+}
+
+function image_blocker_param_disable(tf)
+{
+ if (document.getElementById) {
+ document.getElementById("image_blocker_param").disabled = tf;
+ } else if (document.all) {
+ document.myform.image_blocker_param.disabled = tf;
+ }
+}
+
+function show_add_header_opts(tf)
+{
+ if (document.getElementById) {
+ target = document.getElementById("add_header_opts");
+ } else if (document.all) {
+ target = document.add_header_opts;
+ } else {
+ return;
+ }
+ target.style.display = (tf ? "" : "none");
+}
+
+function show_deanimate_opts(tf)
+{
+ if (document.getElementById) {
+ target = document.getElementById("deanimate_opts");
+ } else if (document.all) {
+ target = document.deanimate_opts;
+ } else {
+ return;
+ }
+ target.style.display = (tf ? "" : "none");
+}
+
+function show_hide_from_opts(tf)
+{
+ if (document.getElementById) {
+ target = document.getElementById("hide_from_opts");
+ } else if (document.all) {
+ target = document.hide_from_opts;
+ } else {
+ return;
+ }
+ target.style.display = (tf ? "" : "none");
+}
+
+function show_hide_referer_opts(tf)
+{
+ if (document.getElementById) {
+ target = document.getElementById("hide_referer_opts");
+ } else if (document.all) {
+ target = document.hide_referer_opts;
+ } else {
+ return;
+ }
+ target.style.display = (tf ? "" : "none");
+}
+
+function show_user_agent_opts(tf)
+{
+ if (document.getElementById) {
+ target = document.getElementById("user_agent_opts");
+ } else if (document.all) {
+ target = document.user_agent_opts;
+ } else {
+ return;
+ }
+ target.style.display = (tf ? "" : "none");
+}
+
+function show_image_blocker_opts(tf)
+{
+ if (document.getElementById) {
+ target = document.getElementById("image_blocker_opts");
+ } else if (document.all) {
+ target = document.image_blocker_opts;
+ } else {
+ return;
+ }
+ target.style.display = (tf ? "" : "none");
+}
+
+function show_limit_connect_opts(tf)
+{
+ if (document.getElementById) {
+ target = document.getElementById("limit_connect_opts");
+ } else if (document.all) {
+ target = document.limit_connect_opts;
+ } else {
+ return;
+ }
+ target.style.display = (tf ? "" : "none");
+}
+
+function show_wafer_opts(tf)
+{
+ if (document.getElementById) {
+ target = document.getElementById("wafer_opts");
+ } else if (document.all) {
+ target = document.wafer_opts;
+ } else {
+ return;
+ }
+ target.style.display = (tf ? "" : "none");
+}
+
+//-->
+</script>
+</head>
+
+<body>
+
+<form method="GET" action="edit-actions-submit" id="myform" name="myform">
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>Edit Actions
+ <input type="hidden" name="f" value="@f@">
+ <input type="hidden" name="v" value="@v@">
+ <input type="hidden" name="s" value="@s@">
+ </h2>
+ </td>
+ </tr>
+
+<tr><td class="wrapbox">
+
+ <table border="0" cellspacing="2" width="100%" class="wide">
+ <tr class="hdr" align="left">
+ <th class="enh" align="center">Enable</th>
+ <th class="dish" align="center">Disable</th>
+ <th class="noch" align="center">No Change</th>
+ <th>Action</th>
+ <th>Description</th>
+ </tr>
+ <tr class="bg1" align="left" valign="top">
+ <td class="en1" align="center" valign="middle"><input type="radio"
+ name="add_header" id="add_header_y" value="Y" @add-header-y@
+ onclick="show_add_header_opts(true)"></td>
+ <td class="dis1" align="center" valign="middle"><input type="radio"
+ name="add_header" value="N" @add-header-n@
+ onclick="show_add_header_opts(false)"></td>
+ <td class="noc1" align="center" valign="middle"><input type="radio"
+ name="add_header" value="X" @add-header-x@
+ onclick="show_add_header_opts(false)"></td>
+ <td class="action">+add-header</td>
+ <td>Adds HTTP headers.</td>
+ </tr>
+ <tr class="bg1" align="left" valign="top" id="add_header_opts">
+ <td class="en1">&nbsp;</td>
+ <td class="dis1">&nbsp;</td>
+ <td class="noc1">&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>Editing the settings for this option, or turning
+ it on if it was off, is not yet supported using this web-based
+ editor.</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2" align="center" valign="middle"><input type="radio"
+ name="block" value="Y" @block-y@
+ ></td>
+ <td class="dis2" align="center" valign="middle"><input type="radio"
+ name="block" value="N" @block-n@
+ ></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio"
+ name="block" value="X" @block-x@
+ ></td>
+ <td class="action">+block</td>
+ <td>Block the request</td>
+ </tr>
+ <tr class="bg1" align="left" valign="top">
+ <td class="en1" align="center" valign="middle"><input type="radio"
+ name="deanimate_gifs" id="deanimate_gifs_y" value="Y" @deanimate-gifs-y@
+ onclick="show_deanimate_opts(true)"></td>
+ <td class="dis1" align="center" valign="middle"><input type="radio"
+ name="deanimate_gifs" value="N" @deanimate-gifs-n@
+ onclick="show_deanimate_opts(false)"></td>
+ <td class="noc1" align="center" valign="middle"><input type="radio"
+ name="deanimate_gifs" value="X" @deanimate-gifs-x@
+ onclick="show_deanimate_opts(false)"></td>
+ <td class="action">+deanimate-gifs</td>
+ <td>Replace animated GIFs with their (first/last) frame.</td>
+ </tr>
+ <tr class="bg1" align="left" valign="top" id="deanimate_opts">
+ <td class="en1">&nbsp;</td>
+ <td class="dis1">&nbsp;</td>
+ <td class="noc1">&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>Use the <input type="radio" name="deanimate_gifs_mode"
+ value="first" id="deanimate_first" @deanimate-gifs-param-first@><label
+ for="deanimate_first">first frame</label>&nbsp;&nbsp; <input
+ type="radio" name="deanimate_gifs_mode" value="last"
+ id="deanimate_last" @deanimate-gifs-param-last@><label
+ for="deanimate_last">last frame</label></td>
+ </tr>
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2" align="center" valign="middle"><input type="radio"
+ name="fast_redirects" value="Y" @fast-redirects-y@
+ ></td>
+ <td class="dis2" align="center" valign="middle"><input type="radio"
+ name="fast_redirects" value="N" @fast-redirects-n@
+ ></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio"
+ name="fast_redirects" value="X" @fast-redirects-x@
+ ></td>
+ <td class="action">+fast-redirects</td>
+ <td>Bypass some tracking URLs.</td>
+ </tr>
+ <tr class="bg1" align="left" valign="top">
+ <td class="en1" align="center" valign="middle"><input type="radio"
+ name="downgrade" value="Y" @downgrade-y@></td>
+ <td class="dis1" align="center" valign="middle"><input type="radio"
+ name="downgrade" value="N" @downgrade-n@></td>
+ <td class="noc1" align="center" valign="middle"><input type="radio"
+ name="downgrade" value="X" @downgrade-x@></td>
+ <td class="action">+downgrade</td>
+ <td>Change HTTP/1.1 requests to HTTP/1.0. Only change if you know
+ what you're doing!</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2">&nbsp;</td>
+ <td class="dis2">&nbsp;</td>
+ <td class="noc2">&nbsp;</td>
+ <td class="action">+filter</td>
+ <td>Filter the website through regular expression filters.
+ You can enable or disable the filters individually.</td>
+ </tr>
+
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2">&nbsp;</td>
+ <td class="dis2" align="center" valign="middle"><input type="radio"
+ name="filter_all" id="filter_all_n" value="N" @filter-all-n@ ></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio"
+ name="filter_all" id="filter_all_x" value="X" @filter-all-x@ ></td>
+ <td class="subaction" colspan="2">&nbsp;&nbsp;All filters applied by previous rules</td>
+ </tr>
+@filter-params@
+ <tr class="bg1" align="left" valign="top">
+ <td class="en1" align="center" valign="middle"><input type="radio"
+ name="hide_forwarded" value="Y" @hide-forwarded-y@
+ ></td>
+ <td class="dis1" align="center" valign="middle"><input type="radio"
+ name="hide_forwarded" value="N" @hide-forwarded-n@
+ ></td>
+ <td class="noc1" align="center" valign="middle"><input type="radio"
+ name="hide_forwarded" value="X" @hide-forwarded-x@
+ ></td>
+ <td class="action">+hide-forwarded</td>
+ <td>Block any existing X-Forwarded-for header, and do not add a new one.</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2" align="center" valign="middle"><input type="radio"
+ name="hide_from" id="hide_from_y" value="Y" @hide-from-y@
+ onclick="show_hide_from_opts(true)"></td>
+ <td class="dis2" align="center" valign="middle"><input type="radio"
+ name="hide_from" value="N" @hide-from-n@
+ onclick="show_hide_from_opts(false)"></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio"
+ name="hide_from" value="X" @hide-from-x@
+ onclick="show_hide_from_opts(false)"></td>
+ <td class="action">+hide-from</td>
+ <td>Stop old web browsers from sending the user's e-mail address with
+ every request.</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top" id="hide_from_opts">
+ <td class="en2">&nbsp;</td>
+ <td class="dis2">&nbsp;</td>
+ <td class="noc2">&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><input type="radio" name="hide_from_mode" value="block"
+ onclick="hide_from_param_disable(true);"
+ @hide-from-param-block@ id="from_mode_block"><label
+ for="from_mode_block">Remove completely</label><br>
+ <input type="radio" name="hide_from_mode" value="CUSTOM"
+ onclick="hide_from_param_disable(false);"
+ @hide-from-param-custom@ id="from_mode_set"><label
+ for="from_mode_set">Fake e-mail address:</label><br>
+ <input type="text" name="hide_from_param" id="hide_from_param"
+ size="40" value="@hide-from-param@"></td>
+ </tr>
+ <tr class="bg1" align="left" valign="top">
+ <td class="en1" align="center" valign="middle"><input type="radio"
+ name="hide_referer" id="hide_referer_y" value="Y" @hide-referer-y@
+ onclick="show_hide_referer_opts(true)"></td>
+ <td class="dis1" align="center" valign="middle"><input type="radio"
+ name="hide_referer" id="hide_referer_n" value="N" @hide-referer-n@
+ onclick="show_hide_referer_opts(false)"></td>
+ <td class="noc1" align="center" valign="middle"><input type="radio"
+ name="hide_referer" id="hide_referer_x" value="X" @hide-referer-x@
+ onclick="show_hide_referer_opts(false)"
+ ></td>
+ <td class="action">+hide-referer</td>
+ <td>Helps prevent tracking by not sending the URL of the previous web
+ page.&nbsp;</td>
+ </tr>
+ <tr class="bg1" align="left" valign="top" id="hide_referer_opts">
+ <td class="en1">&nbsp;</td>
+ <td class="dis1">&nbsp;</td>
+ <td class="noc1">&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><input type="radio" name="hide_referer_mode" value="block"
+ onclick="hide_referer_param_disable(true)"
+ @hide-referer-param-block@ id="referer_mode_block"><label
+ for="referer_mode_block">Remove completely</label> (breaks images
+ on some free web hosts).<br>
+ <input type="radio" name="hide_referer_mode" value="forge"
+ onclick="hide_referer_param_disable(true)"
+ @hide-referer-param-forge@ id="referer_mode_forge"><label
+ for="referer_mode_forge">Fake as the root directory of the
+ site</label> (fools checks for in-site links.)<br>
+ <input type="radio" name="hide_referer_mode" value="CUSTOM"
+ onclick="hide_referer_param_disable(false)"
+ @hide-referer-param-custom@ id="referer_mode_set"><label
+ for="referer_mode_set">Fake as this web address:</label><br>
+ <input type="text" name="hide_referer_param"
+ id="hide_referer_param" size="40"
+ value="@hide-referer-param@"></td>
+ </tr>
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2" align="center" valign="middle"><input type="radio"
+ name="hide_user_agent" id="hide_user_agent_y" value="Y" @hide-user-agent-y@
+ onclick="show_user_agent_opts(true)"></td>
+ <td class="dis2" align="center" valign="middle"><input type="radio"
+ name="hide_user_agent" value="N" @hide-user-agent-n@
+ onclick="show_user_agent_opts(false)"></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio"
+ name="hide_user_agent" value="X" @hide-user-agent-x@
+ onclick="show_user_agent_opts(false)"></td>
+ <td class="action">+hide-user-agent</td>
+ <td>Pretend to be using a different web browser.&nbsp; (Breaks many web
+ sites).</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top" id="user_agent_opts">
+ <td class="en2">&nbsp;</td>
+ <td class="dis2">&nbsp;</td>
+ <td class="noc2">&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>User Agent string to send:<br>
+ <input type="text" name="hide_user_agent_mode" size="40"
+ value="@hide-user-agent-param@"></td>
+ </tr>
+ <tr class="bg1" align="left" valign="top">
+ <td class="en1" align="center" valign="middle"><input type="radio"
+ name="image" value="Y" @image-y@
+ ></td>
+ <td class="dis1" align="center" valign="middle"><input type="radio"
+ name="image" value="N" @image-n@
+ ></td>
+ <td class="noc1" align="center" valign="middle"><input type="radio"
+ name="image" value="X" @image-x@
+ ></td>
+ <td class="action">+image</td>
+ <td>Request is for an image (only useful in conjunction with the <i><b>+block</b></i>
+ and <i><b>+image-blocker</b></i> options).</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2" align="center" valign="middle"><input type="radio"
+ name="image_blocker" id="image_blocker_y" value="Y" @image-blocker-y@
+ onclick="show_image_blocker_opts(true)"></td>
+ <td class="dis2" align="center" valign="middle"><input type="radio"
+ name="image_blocker" value="N" @image-blocker-n@
+ onclick="show_image_blocker_opts(false)"></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio"
+ name="image_blocker" value="X" @image-blocker-x@
+ onclick="show_image_blocker_opts(false)"></td>
+ <td class="action">+image-blocker</td>
+ <td>Specifies how to block images.&nbsp; Disable to always send a HTML
+ &quot;blocked&quot; page.</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top" id="image_blocker_opts">
+ <td class="en2">&nbsp;</td>
+ <td class="dis2">&nbsp;</td>
+ <td class="noc2">&nbsp;</td>
+ <td>&nbsp;</td>
+ <td><input type="radio" name="image_blocker_mode"
+ onclick="image_blocker_param_disable(true)"
+ value="pattern" id="image_blocker_mode_pattern"
+ @image-blocker-param-pattern@><label
+ for="image_blocker_mode_pattern">Send a pattern (<img
+ src="send-banner?type=p" width="12" height="12"
+ alt="pattern">)</label><br>
+ <input type="radio" name="image_blocker_mode" value="blank"
+ onclick="image_blocker_param_disable(true)"
+ id="image_blocker_mode_blank" @image-blocker-param-blank@><label
+ for="image_blocker_mode_blank">Send a 1x1 transparent GIF</label><br>
+ <input type="radio" name="image_blocker_mode" value="CUSTOM"
+ onclick="image_blocker_param_disable(false)"
+ id="image_blocker_mode_set" @image-blocker-param-custom@><label
+ for="image_blocker_mode_set">Redirect
+ the browser to this image URL:</label><br>
+ <input type="text" name="image_blocker_param" id="image_blocker_param"
+ size="40" value="@image-blocker-param@"></td>
+ </tr>
+ <tr class="bg1" align="left" valign="top">
+ <td class="en1" align="center" valign="middle"><input type="radio"
+ name="limit_connect" id="limit_connect_y" value="Y" @limit-connect-y@
+ onclick="show_limit_connect_opts(true)"></td>
+ <td class="dis1" align="center" valign="middle"><input type="radio"
+ name="limit_connect" value="N" @limit-connect-n@
+ onclick="show_limit_connect_opts(false)"></td>
+ <td class="noc1" align="center" valign="middle"><input type="radio"
+ name="limit_connect" value="X" @limit-connect-x@
+ onclick="show_limit_connect_opts(false)"></td>
+ <td class="action">+limit-connect</td>
+ <td>Specify which ports are allowed for SSL (HTTP CONNECT) access.
+ Note that this allows arbitrary tunnelling, so opening all
+ ports would be a security hole.</td>
+ </tr>
+ <tr class="bg1" align="left" valign="top" id="limit_connect_opts">
+ <td class="en1">&nbsp;</td>
+ <td class="dis1">&nbsp;</td>
+ <td class="noc1">&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>Legal SSL ports (comma separated, ranges allowed):<br>
+ <input type="text" name="limit_connect_mode" size="40"
+ value="@limit-connect-param@"></td>
+ </tr>
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2" align="center" valign="middle"><input type="radio"
+ name="no_compression" value="Y" @no-compression-y@
+ ></td>
+ <td class="dis2" align="center" valign="middle"><input type="radio"
+ name="no_compression" value="N" @no-compression-n@
+ ></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio"
+ name="no_compression" value="X" @no-compression-x@
+ ></td>
+ <td class="action">+no-compression</td>
+ <td>Disables compression. Compressed web pages are faster to
+ download, but cannot be filtered with +filter or +no-popups.
+ This setting only affects the few web sites which support
+ compression.</td>
+ </tr>
+ <tr class="bg1" align="left" valign="top">
+ <td class="en1" align="center" valign="middle"><input type="radio"
+ name="no_cookies_keep" value="Y" @no-cookies-keep-y@
+ ></td>
+ <td class="dis1" align="center" valign="middle"><input type="radio"
+ name="no_cookies_keep" value="N" @no-cookies-keep-n@
+ ></td>
+ <td class="noc1" align="center" valign="middle"><input type="radio"
+ name="no_cookies_keep" value="X" @no-cookies-keep-x@
+ ></td>
+ <td class="action">+no-cookies-keep</td>
+ <td>Any cookies set by the website are changed to temporary
+ ("per-session") ones, which only last until you close your web
+ browser. This will allow you to use sites that require cookies, but
+ sites will not be able to track you across sessions. For this to
+ be useful, you should disable <b><i>no-cookies-read</i></b> and
+ <b><i>no-cookies-set</i></b>.</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2" align="center" valign="middle"><input type="radio"
+ name="no_cookies_read" value="Y" @no-cookies-read-y@
+ ></td>
+ <td class="dis2" align="center" valign="middle"><input type="radio"
+ name="no_cookies_read" value="N" @no-cookies-read-n@
+ ></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio"
+ name="no_cookies_read" value="X" @no-cookies-read-x@
+ ></td>
+ <td class="action">+no-cookies-read</td>
+ <td>Prevent the website from reading cookies.</td>
+ </tr>
+ <tr class="bg1" align="left" valign="top">
+ <td class="en1" align="center" valign="middle"><input type="radio"
+ name="no_cookies_set" value="Y" @no-cookies-set-y@
+ ></td>
+ <td class="dis1" align="center" valign="middle"><input type="radio"
+ name="no_cookies_set" value="N" @no-cookies-set-n@
+ ></td>
+ <td class="noc1" align="center" valign="middle"><input type="radio"
+ name="no_cookies_set" value="X" @no-cookies-set-x@
+ ></td>
+ <td class="action">+no-cookies-set</td>
+ <td>Prevent the website from setting cookies.</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2" align="center" valign="middle"><input type="radio"
+ name="no_popups" value="Y" @no-popups-y@
+ ></td>
+ <td class="dis2" align="center" valign="middle"><input type="radio"
+ name="no_popups" value="N" @no-popups-n@
+ ></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio"
+ name="no_popups" value="X" @no-popups-x@
+ ></td>
+ <td class="action">+no-popups</td>
+ <td>Filter the website through a built-in filter to disable JavaScript
+ pop-up windows.</td>
+ </tr>
+ <tr class="bg1" align="left" valign="top">
+ <td class="en1" align="center" valign="middle"><input type="radio"
+ name="vanilla_wafer" value="Y" @vanilla-wafer-y@
+ ></td>
+ <td class="dis1" align="center" valign="middle"><input type="radio"
+ name="vanilla_wafer" value="N" @vanilla-wafer-n@
+ ></td>
+ <td class="noc1" align="center" valign="middle"><input type="radio"
+ name="vanilla_wafer" value="X" @vanilla-wafer-x@
+ ></td>
+ <td class="action">+vanilla-wafer</td>
+ <td>If you use a jarfile, automatically adds a special wafer.</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top">
+ <td class="en2" align="center" valign="middle"><input type="radio"
+ name="wafer" id="wafer_y" value="Y" @wafer-y@
+ onclick="show_wafer_opts(true)"></td>
+ <td class="dis2" align="center" valign="middle"><input type="radio"
+ name="wafer" id="wafer_n" value="N" @wafer-n@
+ onclick="show_wafer_opts(false)"></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio"
+ name="wafer" id="wafer_x" value="X" @wafer-x@
+ onclick="show_wafer_opts(false)"></td>
+ <td class="action">+wafer</td>
+ <td>Adds user-specified cookies.</td>
+ </tr>
+ <tr class="bg2" align="left" valign="top" id="wafer_opts">
+ <td class="en2">&nbsp;</td>
+ <td class="dis2">&nbsp;</td>
+ <td class="noc2">&nbsp;</td>
+ <td>&nbsp;</td>
+ <td>Editing the settings for this option, or turning
+ it on if it was off, is not yet supported using this web-based
+ editor.</td>
+ </tr>
+ </table>
+
+</td></tr>
+
+ <tr>
+ <td class="green" align="center">
+ <p><input type="submit" value="Submit" name="Submit"></p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <small><small>Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></small></small>
+ </td>
+ </tr>
+
+ </table>
+</form>
+
+
+<script type="text/javascript">
+<!--
+
+if (document.getElementById) {
+ // alert("Netscape 6 or IE5");
+ document.getElementById("hide_from_param").disabled = !(document.getElementById("from_mode_set").checked);
+ document.getElementById("hide_referer_param").disabled = !(document.getElementById("referer_mode_set").checked);
+ document.getElementById("image_blocker_param").disabled = !(document.getElementById("image_blocker_mode_set").checked);
+
+ show_add_header_opts (document.getElementById("add_header_y").checked);
+ show_deanimate_opts (document.getElementById("deanimate_gifs_y").checked);
+ show_hide_from_opts (document.getElementById("hide_from_y").checked);
+ show_hide_referer_opts (document.getElementById("hide_referer_y").checked);
+ show_user_agent_opts (document.getElementById("hide_user_agent_y").checked);
+ show_image_blocker_opts (document.getElementById("image_blocker_y").checked);
+ show_limit_connect_opts (document.getElementById("limit_connect_y").checked);
+ show_wafer_opts (document.getElementById("wafer_y").checked);
+} else if (document.all) {
+ // alert("IE4");
+ document.myform.hide_from_param.disabled = !(document.myform.from_mode_set.checked);
+ document.myform.hide_referer_param.disabled = !(document.myform.referer_mode_set.checked);
+ document.myform.image_blocker_param.disabled = !(document.myform.image_blocker_mode_set.checked);
+
+ show_add_header_opts (document.myform.add_header_y.checked);
+ show_deanimate_opts (document.myform.deanimate_gifs_y.checked);
+ show_hide_from_opts (document.myform.hide_from_y.checked);
+ show_hide_referer_opts (document.myform.hide_referer_y.checked);
+ show_user_agent_opts (document.myform.hide_user_agent_y.checked);
+ show_image_blocker_opts (document.myform.image_blocker_y.checked);
+ show_limit_connect_opts (document.myform.limit_connect_y.checked);
+ show_wafer_opts (document.myform.wafer_y.checked);
+} else if (document.layers) {
+ // alert("Netscape 4");
+}
+//-->
+</script>
+
+
+</body>
+
+</html>
diff --git a/src/privoxytemplates/edit-actions-for-url-filter b/src/privoxytemplates/edit-actions-for-url-filter
new file mode 100644
index 0000000..06020cb
--- /dev/null
+++ b/src/privoxytemplates/edit-actions-for-url-filter
@@ -0,0 +1,6 @@
+<tr class="bg2" align="left" valign="top">
+ <td class="en2" align="center" valign="middle"><input type="radio" name="filter_r@index@" value="Y" @this-filter-y@></td>
+ <td class="dis2" align="center" valign="middle"><input type="radio" name="filter_r@index@" value="N" @this-filter-n@></td>
+ <td class="noc2" align="center" valign="middle"><input type="radio" name="filter_r@index@" value="X" @this-filter-x@></td>
+ <td class="subaction" colspan="2">&nbsp;&nbsp;@description@ (@name@) <input type="hidden" name="filter_n@index@" value="@name@"></td>
+</tr>
diff --git a/src/privoxytemplates/edit-actions-list b/src/privoxytemplates/edit-actions-list
new file mode 100644
index 0000000..b80af78
--- /dev/null
+++ b/src/privoxytemplates/edit-actions-list
@@ -0,0 +1,294 @@
+##############################################################################
+#
+# File : $Source: /cvsroot/tork/tork/src/privoxytemplates/edit-actions-list,v $
+#
+# Purpose : Template used to edit the actions file.
+#
+#
+# Copyright : Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Original Author: Copyright (C) 2001 Jonathan Foster
+# http://www.jon-foster.co.uk/
+#
+# This program is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file. If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Revisions :
+# $Log: edit-actions-list,v $
+# Revision 1.1 2007/01/01 17:53:14 hoganrobert
+# *** empty log message ***
+#
+# Revision 1.17 2002/04/10 13:32:53 oes
+# Made templates modular
+#
+# Revision 1.16 2002/04/08 17:08:14 oes
+# Cosmetic: make status in title lowercase
+#
+# Revision 1.15 2002/04/05 16:01:32 oes
+# Correct HTML, external Stylesheets, eye candy, some fixes
+#
+# Revision 1.14 2002/03/26 22:29:56 swa
+# we have a new homepage!
+#
+# Revision 1.13 2002/03/24 15:23:33 jongfoster
+# Name changes
+#
+# Revision 1.12 2002/03/24 11:01:06 swa
+# name change
+#
+# Revision 1.11 2002/03/23 16:18:15 swa
+# renamed every reference to the old name with foobar.
+# fixed "application foobar application" tag, fixed
+# "the foobar" with "foobar". left junkbuster in cvs
+# comments and remarks to history untouched. should
+# make final rename easier.
+#
+# Revision 1.10 2002/03/16 15:22:19 jongfoster
+# Moving 'alpha' warning to the end of the page
+#
+# Revision 1.9 2002/03/05 00:24:51 jongfoster
+# Patch to always edit the current actions file.
+#
+# Revision 1.8 2002/03/03 10:29:12 swa
+# point users to the right feedback forms,
+# not necessarily the developer list.
+#
+# Revision 1.7 2002/01/23 00:26:45 jongfoster
+# Reducing length of URLs
+# Where encoded and unencoded versions of a string existed, removing
+# the unencoded one.
+#
+# Revision 1.6 2002/01/17 21:33:00 jongfoster
+# Replacing all references to the URL of the config interface
+# with @default-cgi@
+#
+# Revision 1.5 2002/01/17 21:21:05 jongfoster
+# DOS->Unix line endings
+#
+# Revision 1.4 2001/11/13 00:58:18 jongfoster
+# New version of actions file editor templates
+#
+#
+##############################################################################
+#
+# Browser support for the CSS on this page:
+# MS Internet Explorer 5.5 - Yes - everything works.
+# Netscape 6.2 - Yes - everything works.
+# Netscape 4.75 - No - CSS buttons look really bad, but they are
+# usable. Everything else works.
+# Opera 5.12 - Yes - everything works.
+# MS Internet Explorer 4+ - Untested
+# MS IE 3.x, NS3.x - Untested (Don't support CSS, so everything
+# should work, but will look ugly).
+# Mozilla >=0.6 - Untested
+#
+# All browsers should work, you just might not get the pretty CSS buttons.
+#
+# If you're favorite browser isn't listed/tested, please test and add it.
+#
+#
+#############################################################################
+#
+# Standard support:
+#
+# This file currently produces valid HTML 4.01 Strict.
+#
+# If you change it, please save the generated page from your web browser
+# and then upload it to http://validator.w3.org/ for checking.
+#
+#############################################################################
+#
+# Available variables include:
+#
+# filename
+# ver
+#
+#
+#############################################################################
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+
+ <title>Privoxy: Edit actions file</title>
+
+ <style type="text/css">
+
+table.wide {
+ padding: 5px;
+}
+table.framed {
+ border: solid black 1px;
+ margin: 10px 0px;
+}
+tr.actions {
+ background-color: #eeffee;
+}
+tr.url1 {
+ background-color: #d0d0ff;
+}
+tr.url2 {
+ background-color: #eeeeff;
+}
+tr.rule {
+ background-color: #c0c0c0;
+ height: 3px;
+ max-height: 3px;
+ font-size: 1px
+}
+tr.adv {
+ background-color: #FFFFD0;
+}
+td.header {
+ font-weight: bold;
+}
+td.url {
+ font-weight: bold;
+}
+td.action {
+ font-weight: bold;
+ font-style: italic;
+}
+td.nbr {
+ white-space: nowrap;
+}
+a.cmd, div.buttons a {
+ white-space: nowrap;
+ width: auto;
+ padding: 2px;
+ background-color: #dddddd;
+ color: #000000;
+ text-decoration: none;
+ border-top: 1px solid #ffffff;
+ border-left: 1px solid #ffffff;
+ border-bottom: 1px solid #000000;
+ border-right: 1px solid #000000;
+}
+a.cmd:hover, div.buttons a:hover {
+ background-color: #eeeeee;
+}
+a.cmd:active, div.buttons a:active {
+ border-top: 1px solid #000000;
+ border-left: 1px solid #000000;
+ border-bottom: 1px solid #ffffff;
+ border-right: 1px solid #ffffff;
+}
+
+</style>
+
+<script type="text/javascript">
+<!--
+function not_yet()
+{
+ window.alert("The feature you are trying to use has not been implemented yet.");
+}
+
+// Non-JS capable browsers will follow the link to a HTML "are you sure?" page
+// JavaScript-capable browsers will call this function, which does a
+// client-side prompt for speed. It may kick off the delete directly.
+// It always returns false to cancel following the link.
+function rm_p(pattern,curtext)
+{
+ if (window.confirm("Are you sure you want to delete this URL pattern?\nPattern is: "+unescape(curtext)))
+ { window.location.href="edit-actions-remove-url?f=@f@&v=@v@&p="+pattern+"#l"+pattern; }
+ return false;
+}
+
+//-->
+</script>
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+
+ <tr>
+ <td class="box">
+ <div class="buttons">
+ <h2>Editing Actions File</h2>
+ <p><a class="cmd" href="edit-actions-section-add?f=@f@&amp;v=@v@&amp;s=0">Insert new section at top</a></p>
+ </div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="container">
+ <div class="buttons">@sections@</div>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <small><small>Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></small></small>
+ </td>
+ </tr>
+
+ </table>
+</body>
+
+</html>
diff --git a/src/privoxytemplates/edit-actions-list-section b/src/privoxytemplates/edit-actions-list-section
new file mode 100644
index 0000000..b1bd3af
--- /dev/null
+++ b/src/privoxytemplates/edit-actions-list-section
@@ -0,0 +1,111 @@
+##############################################################################
+#
+# File : $Source: /cvsroot/tork/tork/src/privoxytemplates/edit-actions-list-section,v $
+#
+# Purpose : Template which forms part of edit-actions-list
+#
+#
+# Copyright : Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Original Author: Copyright (C) 2001 Jonathan Foster
+# http://www.jon-foster.co.uk/
+#
+# This program is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file. If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Revisions :
+# $Log: edit-actions-list-section,v $
+# Revision 1.1 2007/01/01 17:53:19 hoganrobert
+# *** empty log message ***
+#
+# Revision 1.8 2002/04/05 16:01:33 oes
+# Correct HTML, external Stylesheets, eye candy, some fixes
+#
+# Revision 1.7 2002/03/26 22:29:56 swa
+# we have a new homepage!
+#
+# Revision 1.6 2002/03/24 11:01:06 swa
+# name change
+#
+# Revision 1.5 2002/01/23 00:26:45 jongfoster
+# Reducing length of URLs
+# Where encoded and unencoded versions of a string existed, removing
+# the unencoded one.
+#
+# Revision 1.4 2002/01/17 21:33:00 jongfoster
+# Replacing all references to the URL of the config interface
+# with @default-cgi@
+#
+# Revision 1.3 2001/11/13 00:58:18 jongfoster
+# New version of actions file editor templates
+#
+#
+#############################################################################
+#
+# Available variables include:
+#
+# filename
+# ver
+# sectionid
+# urls
+#
+#############################################################################
+#
+# ** Important note: **
+#
+# It is important to keep this file small. That's why all the
+# identifiers in the HTML are short and cryptic. Currently, the main
+# edit-actions page is ~300k. Before it was optimized, it was ~550k.
+#
+#############################################################################
+<table border="0" width="100%" cellspacing="0" cellpadding="3" class="framed">
+<tr class="actions" valign="top">
+ <td class="header" align="right">Actions:</td>
+ <td align="center"><a name="l@s@" href="eas?f=@f@&amp;v=@v@&amp;s=@s@">Edit</a></td>
+ <td class="action" align="left">@actions@</td>
+</tr>
+<tr class="rule">
+ <td colspan="3"><img src="t" width="2" height="1" alt="----"></td>
+</tr>
+<tr class="url1" valign="top">
+ <td class="header" align="right">URLs:</td>
+ <td align="center"><a href="eaa?f=@f@&amp;v=@v@&amp;s=@s@">Add</a></td>
+ <td align="left">&nbsp;</td>
+</tr>
+@urls@
+<tr class="rule">
+ <td colspan="3"><img src="t" width="2" height="1" alt="-"></td>
+</tr>
+<tr class="adv" valign="top">
+ <td class="header" align="right"><b>Advanced:</b></td>
+ <td colspan="2">
+ <table border="0" cellspacing="0" cellpadding="4">
+ <tr valign="middle" align="center">
+ <td class="nbr"> &nbsp; @if-s-prev-exists-start@<a href="eass?f=@f@&amp;v=@v@&amp;s1=@s-prev@&amp;s2=@s@">Move section up</a> &nbsp; @if-s-prev-exists-end@</td>
+ <td class="nbr"> &nbsp; <a href="easa?f=@f@&amp;v=@v@&amp;s=@s@">Insert new section below</a> &nbsp; </td>
+ </tr>
+ <tr valign="middle" align="center">
+ <td class="nbr"> &nbsp; @if-s-next-exists-start@<a href="eass?f=@f@&amp;v=@v@&amp;s1=@s@&amp;s2=@s-next@">Move section down</a> &nbsp; @if-s-next-exists-end@</td>
+ <td class="nbr"> &nbsp; @if-empty-section-start@<a href="easr?f=@f@&amp;v=@v@&amp;s=@s@">Delete whole section</a>&nbsp; @if-empty-section-end@</td>
+ </tr>
+ </table>
+ </td>
+</tr>
+</table>
+
diff --git a/src/privoxytemplates/edit-actions-list-url b/src/privoxytemplates/edit-actions-list-url
new file mode 100644
index 0000000..1a81805
--- /dev/null
+++ b/src/privoxytemplates/edit-actions-list-url
@@ -0,0 +1,79 @@
+##############################################################################
+#
+# File : $Source: /cvsroot/tork/tork/src/privoxytemplates/edit-actions-list-url,v $
+#
+# Purpose : Template which forms part of edit-actions-list
+#
+#
+# Copyright : Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Original Author: Copyright (C) 2001 Jonathan Foster
+# http://www.jon-foster.co.uk/
+#
+# This program is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file. If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Revisions :
+# $Log: edit-actions-list-url,v $
+# Revision 1.1 2007/01/01 17:53:27 hoganrobert
+# *** empty log message ***
+#
+# Revision 1.7 2002/03/26 22:29:56 swa
+# we have a new homepage!
+#
+# Revision 1.6 2002/03/24 11:01:06 swa
+# name change
+#
+# Revision 1.5 2002/01/23 00:26:45 jongfoster
+# Reducing length of URLs
+# Where encoded and unencoded versions of a string existed, removing
+# the unencoded one.
+#
+# Revision 1.4 2002/01/17 21:33:00 jongfoster
+# Replacing all references to the URL of the config interface
+# with @default-cgi@
+#
+# Revision 1.3 2001/11/13 00:58:18 jongfoster
+# New version of actions file editor templates
+#
+#
+#############################################################################
+#
+# Available variables include:
+#
+# filename
+# ver
+# sectionid
+# urls
+#
+#############################################################################
+#
+# ** Important note: **
+#
+# It is *extremely* important to keep this file small. That's why all the
+# identifiers in the HTML are short and cryptic. Currently, the main
+# edit-actions page is ~300k. Before it was optimized, it was ~550k.
+#
+#############################################################################
+<tr class="url@url-1-2@" valign="top"><td align="left">&nbsp;</td>
+<td align="center" class="nbr"><a name="l@p@"
+href="ear?f=@f@&amp;v=@v@&amp;p=@p@" onclick="return rm_p(@p@,'@url@');">Remove</a>&nbsp;&nbsp;&nbsp;<a
+href="eau?f=@f@&amp;v=@v@&amp;p=@p@">Edit</a>&nbsp;</td>
+<td class="url" align="left">@url-html@</td>
+</tr>
diff --git a/src/privoxytemplates/edit-actions-remove-url-form b/src/privoxytemplates/edit-actions-remove-url-form
new file mode 100644
index 0000000..84fc932
--- /dev/null
+++ b/src/privoxytemplates/edit-actions-remove-url-form
@@ -0,0 +1,189 @@
+##############################################################################
+#
+# File : $Source: /cvsroot/tork/tork/src/privoxytemplates/edit-actions-remove-url-form,v $
+#
+# Purpose : Template used to confirm removal of a particular URL
+# pattern from an actions file. Only used on browsers that
+# don't support JavaScript.
+#
+#
+# Copyright : Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Original Author: Copyright (C) 2001 Jonathan Foster
+# http://www.jon-foster.co.uk/
+#
+# This program is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file. If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Revisions :
+# $Log: edit-actions-remove-url-form,v $
+# Revision 1.1 2007/01/01 17:53:31 hoganrobert
+# *** empty log message ***
+#
+# Revision 1.13 2002/04/10 13:32:53 oes
+# Made templates modular
+#
+# Revision 1.12 2002/04/08 17:08:14 oes
+# Cosmetic: make status in title lowercase
+#
+# Revision 1.11 2002/04/05 16:01:30 oes
+# Correct HTML, external Stylesheets, eye candy, some fixes
+#
+# Revision 1.10 2002/03/26 22:29:56 swa
+# we have a new homepage!
+#
+# Revision 1.9 2002/03/24 15:23:33 jongfoster
+# Name changes
+#
+# Revision 1.8 2002/03/24 11:01:06 swa
+# name change
+#
+# Revision 1.7 2002/03/23 16:18:15 swa
+# renamed every reference to the old name with foobar.
+# fixed "application foobar application" tag, fixed
+# "the foobar" with "foobar". left junkbuster in cvs
+# comments and remarks to history untouched. should
+# make final rename easier.
+#
+# Revision 1.6 2002/03/16 15:22:19 jongfoster
+# Moving 'alpha' warning to the end of the page
+#
+# Revision 1.5 2002/03/03 10:29:12 swa
+# point users to the right feedback forms,
+# not necessarily the developer list.
+#
+# Revision 1.4 2002/01/23 00:26:45 jongfoster
+# Reducing length of URLs
+# Where encoded and unencoded versions of a string existed, removing
+# the unencoded one.
+#
+# Revision 1.3 2002/01/17 21:33:00 jongfoster
+# Replacing all references to the URL of the config interface
+# with @default-cgi@
+#
+# Revision 1.2 2002/01/17 21:21:05 jongfoster
+# DOS->Unix line endings
+#
+# Revision 1.1 2001/11/13 00:58:18 jongfoster
+# New version of actions file editor templates
+#
+#
+##############################################################################
+#
+# Standard support:
+#
+# This file currently produces valid HTML 4.01 Strict.
+#
+# If you change it, please save the generated page from your web browser
+# and then upload it to http://validator.w3.org/ for checking.
+#
+#############################################################################
+#
+# Available variables include:
+#
+# filename
+# ver
+# section
+# pattern
+# oldval
+#
+#############################################################################
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+
+ <title>Privoxy@@my-hostname@: Remove URL Pattern</title>
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>Remove URL Pattern</h2>
+ <p>Are you sure you want to delete this URL pattern? The pattern is:</p>
+ <p class="important">@u@</p>
+ <p>
+ <a href="edit-actions-remove-url?f=@f@&amp;v=@v@&amp;p=@p@">OK</a>
+ &nbsp;
+ <a href="edit-actions-list?f=@f@">Cancel</a>
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <small><small>Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></small></small>
+ </td>
+ </tr>
+
+ </table>
+</body>
+
+</html>
diff --git a/src/privoxytemplates/edit-actions-url-form b/src/privoxytemplates/edit-actions-url-form
new file mode 100644
index 0000000..ea111d8
--- /dev/null
+++ b/src/privoxytemplates/edit-actions-url-form
@@ -0,0 +1,207 @@
+##############################################################################
+#
+# File : $Source: /cvsroot/tork/tork/src/privoxytemplates/edit-actions-url-form,v $
+#
+# Purpose : Template used to edit a URL pattern in an actions file.
+#
+#
+# Copyright : Written by and Copyright (C) 2001 the SourceForge
+# Privoxy team. http://www.privoxy.org/
+#
+# Original Author: Copyright (C) 2001 Jonathan Foster
+# http://www.jon-foster.co.uk/
+#
+# This program is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General
+# Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# The GNU General Public License should be included with
+# this file. If not, you can view it at
+# http://www.gnu.org/copyleft/gpl.html
+# or write to the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Revisions :
+# $Log: edit-actions-url-form,v $
+# Revision 1.1 2007/01/01 17:53:39 hoganrobert
+# *** empty log message ***
+#
+# Revision 1.13 2002/04/10 13:32:53 oes
+# Made templates modular
+#
+# Revision 1.12 2002/04/08 17:08:14 oes
+# Cosmetic: make status in title lowercase
+#
+# Revision 1.11 2002/04/05 16:01:32 oes
+# Correct HTML, external Stylesheets, eye candy, some fixes
+#
+# Revision 1.10 2002/03/26 22:29:56 swa
+# we have a new homepage!
+#
+# Revision 1.9 2002/03/24 15:23:33 jongfoster
+# Name changes
+#
+# Revision 1.8 2002/03/24 11:01:06 swa
+# name change
+#
+# Revision 1.7 2002/03/23 16:18:15 swa
+# renamed every reference to the old name with foobar.
+# fixed "application foobar application" tag, fixed
+# "the foobar" with "foobar". left junkbuster in cvs
+# comments and remarks to history untouched. should
+# make final rename easier.
+#
+# Revision 1.6 2002/03/16 15:22:19 jongfoster
+# Moving 'alpha' warning to the end of the page
+#
+# Revision 1.5 2002/03/03 10:29:13 swa
+# point users to the right feedback forms,
+# not necessarily the developer list.
+#
+# Revision 1.4 2002/01/23 00:26:45 jongfoster
+# Reducing length of URLs
+# Where encoded and unencoded versions of a string existed, removing
+# the unencoded one.
+#
+# Revision 1.3 2002/01/17 21:33:00 jongfoster
+# Replacing all references to the URL of the config interface
+# with @default-cgi@
+#
+# Revision 1.2 2002/01/17 21:21:05 jongfoster
+# DOS->Unix line endings
+#
+# Revision 1.1 2001/11/13 00:58:18 jongfoster
+# New version of actions file editor templates
+#
+#
+##############################################################################
+#
+# Standard support:
+#
+# This file currently produces valid HTML 4.01 Strict.
+#
+# If you change it, please save the generated page from your web browser
+# and then upload it to http://validator.w3.org/ for checking.
+#
+#############################################################################
+#
+# Available variables include:
+#
+# f - filename
+# v - version
+# s - section
+# p - pattern
+# u - old value of URL
+#
+#############################################################################
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+
+ <title>Privoxy@@my-hostname@: Edit URL Pattern</title>
+
+ <script type="text/javascript">
+<!--
+function validate(text)
+{
+ if (text=="")
+ {
+ alert("You need to type a pattern in order to continue!");
+ return false;
+ }
+
+ return true;
+}
+//-->
+ </script>
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>Edit URL Pattern</h2>
+ <form method="GET" action="edit-actions-url"
+ onSubmit="return validate(u.value);">
+ <p>
+ <input type="hidden" name="f" value="@f@">
+ <input type="hidden" name="v" value="@v@">
+ <input type="hidden" name="p" value="@p@">
+ <input type="text" name="u" value="@u@" size="78"><br>
+ <input type="submit" value="Submit"> &nbsp;
+ <input type="reset" value="Reset"> &nbsp;
+ <a href="edit-actions-list?f=@f@">Cancel</a>
+ </p>
+ </form>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <small><small>Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></small></small>
+ </td>
+ </tr>
+
+ </table>
+</body>
+
+</html>
diff --git a/src/privoxytemplates/mod-local-help b/src/privoxytemplates/mod-local-help
new file mode 100644
index 0000000..21d6596
--- /dev/null
+++ b/src/privoxytemplates/mod-local-help
@@ -0,0 +1,12 @@
+ <h2>Local Privoxy support:</h2>
+
+<!-- @if-have-proxy-info-start -->
+ <p>You can consult the <a href="@proxy-info-url@">online documentation</a> for more information about this Privoxy installation.</p>
+<!-- if-have-proxy-info-end@ -->
+
+<!-- @if-have-adminaddr-info-start -->
+ <p>Address e-mail questions about this service to
+ <a href="mailto:@admin-address@"><code>@admin-address@</code></a>,
+ who will be glad to help you.
+ </p>
+<!-- if-have-adminaddr-info-end@ -->
diff --git a/src/privoxytemplates/mod-support-and-service b/src/privoxytemplates/mod-support-and-service
new file mode 100644
index 0000000..720bd2e
--- /dev/null
+++ b/src/privoxytemplates/mod-support-and-service
@@ -0,0 +1,24 @@
+ <h2>Support and Service via Sourceforge:</h2>
+ <p>
+ We value your feedback. To provide you with the best support,
+ we ask that you:
+ </p>
+ <ul>
+ <li>
+ use the <a href="http://sourceforge.net/tracker/?group_id=11118&amp;atid=211118">support forum</a> or (better) the
+ <a href="http://sourceforge.net/mail/?group_id=11118">mailing lists</a> to get help.
+ </li>
+ <li>
+ submit banners and all problems with the actions file only through the
+ <a href="javascript:w=Math.floor(screen.width/2);h=Math.floor(screen.height*0.9);void(window.open('http://www.privoxy.org/actions','Feedback','screenx='+w+',width='+w+',height='+h+',scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">actions
+ file feedback system</a>.
+ </li>
+ <li>
+ submit bugs only through our <a href="http://sourceforge.net/tracker/?group_id=11118&amp;atid=111118">bug tracker</a>.
+ Make sure that the bug has not yet been submitted.
+ </li>
+ <li>
+ submit feature requests only through our <a href="http://sourceforge.net/tracker/?atid=361118&amp;group_id=11118&amp;func=browse">feature
+ request tracker</a>.
+ </li>
+ </ul>
diff --git a/src/privoxytemplates/mod-title b/src/privoxytemplates/mod-title
new file mode 100644
index 0000000..1829604
--- /dev/null
+++ b/src/privoxytemplates/mod-title
@@ -0,0 +1,4 @@
+ <h1>
+ This is <a href="@homepage@">Privoxy</a> @version@ on @my-hostname@ (@my-ip-address@), port @my-port@,
+ @if-enabled-display-then@enabled@else-not-enabled-display@disabled@endif-enabled-display@
+ </h1>
diff --git a/src/privoxytemplates/mod-unstable-warning b/src/privoxytemplates/mod-unstable-warning
new file mode 100644
index 0000000..bb35ccf
--- /dev/null
+++ b/src/privoxytemplates/mod-unstable-warning
@@ -0,0 +1,6 @@
+ <h2>Warning:</h2>
+ <p>
+ <b>Please note that this <em class="warning">@code-status@</em> release
+ of the proxy software is not intended for production systems!
+ <br>Use at your own risk. See the <a href="http://www.gnu.org/copyleft/gpl.html">license</a> for details.</b>
+ </p>
diff --git a/src/privoxytemplates/no-such-domain b/src/privoxytemplates/no-such-domain
new file mode 100644
index 0000000..f220b5c
--- /dev/null
+++ b/src/privoxytemplates/no-such-domain
@@ -0,0 +1,160 @@
+##########################################################
+#
+# No-Such-Domain Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the proxy's administrator, as configured
+# in the 'config' file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# host:
+# The host part of the request that lead to this problem
+# hostport:
+# The host and port part of the request that lead to this problem
+# path:
+# The path part of the request that lead to this problem
+# proxy-info-url:
+# The URL to local online Privoxy documentation, if define in the
+# 'config' file
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>404 - No such Domain (Privoxy@@my-hostname@)</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="status">
+ 404
+ </td>
+ <td class="title" style="width: 100%">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning" colspan="2">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="warning" colspan="2">
+ <h2>No such domain</h2>
+ <p>Your request for <a href="@protocol@@hostport@@path@"><b>@protocol@@hostport@@path@</b></a>
+ could not be fulfilled, because the domain name <b>@host@</b> could not be resolved.
+ </p>
+ <p>This is often a temporary failiure, so you might just
+ <a href="@protocol@@hostport@@path@">try again</a>.
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box" colspan="2">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info" colspan="2">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info" colspan="2">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td colspan="2">
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/show-request b/src/privoxytemplates/show-request
new file mode 100644
index 0000000..0871a11
--- /dev/null
+++ b/src/privoxytemplates/show-request
@@ -0,0 +1,158 @@
+##########################################################
+#
+# Show-Request-CGI Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+# client-request:
+# The request and headers that the client sent.
+# processed-request:
+# What we would have rewritten this request to, if this had not
+# been intercepted.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Privoxy@@my-hostname@</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>Show-Request</h2>
+ <p>
+ Here you see the original headers that your client sent when requesting this page, along with
+ the headers that Privoxy would have sent to the remote server if this request hadn't been
+ intercepted.
+ </p>
+
+ <h3>Original Client Request:</h3>
+ <pre>@client-request@</pre>
+
+ <h3>Processed Request:</h3>
+ <pre>@processed-request@</pre>
+
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/show-status b/src/privoxytemplates/show-status
new file mode 100644
index 0000000..7108722
--- /dev/null
+++ b/src/privoxytemplates/show-status
@@ -0,0 +1,315 @@
+##########################################################
+#
+# Show-Status-CGI Output template for Privoxy.
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# redirect-url:
+# The URL to a script that will redirect to the Privoxy
+# documentation for a given item
+# invocation:
+# The command line with whitch Privoxy was invoked
+# options:
+# The options read from the configfile, linked to their
+# explanations, plus warnings if parsing acl or forward
+# statements produced errors.
+# sourceversions:
+# A HTML-formatted list of the individual source file cvs versions
+# defines:
+# A HTML-formatted list of all conditional #defines used when
+# Privoxy was compiled
+#
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# This is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+# statistics:
+# Privoxy was compiled with statistics support
+# have-stats:
+# There have been previous requests and statistics have
+# been collected. In this case, the following symbols
+# are available:
+# requests-received:
+# The number of requests received so far
+# requests-blocked:
+# The number of request blocked so far
+# percent-blocked:
+# The percentage of blocked requests
+# have-no-stats:
+# There haven't any statistics been collected yet
+# pcrs-support:
+# Privoxy was compiled with pcrs support
+# trust-support:
+# Privoxy was compiled with trust support
+# actions-filename:
+# The path to the actions file.
+# re-filter-filename:
+# The path to the re_filter file. Only available if
+# pcrs-support is set
+# trust-filename:
+# The path to the trust file.Only available if
+# trust-support is set
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Privoxy@@my-hostname@: Proxy Status</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>The program was invoked as follows</h2>
+ <p>@invocation@</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>The following options were given in the config file:</h2>
+ <p>@options@</p>
+ </td>
+ </tr>
+
+<!-- @if-statistics-start -->
+ <tr>
+ <td class="box">
+ <h2>Blocking Statistics:</h2>
+ <p>
+ <!-- @if-have-stats-start -->
+ @requests-blocked@ out of @requests-received@ requests have been blocked,
+ which equals a block rate of @percent-blocked@%.
+<!-- if-have-stats-end@ -->
+<!-- @if-have-no-stats-start -->
+ There haven't been any requests so far.
+<!-- if-have-no-stats-end@ -->
+ </p>
+ </td>
+ </tr>
+<!-- if-statistics-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>The following files are in use:</h2>
+ <p>Click a filename to browse</p>
+ <ul>
+ <li>Actions List: <a href="show-status?file=permit">@actions-filename@</a></li>
+<!-- @if-pcrs-support-start -->
+ <li>Regex Filter List: <a href="show-status?file=re">@re-filter-filename@</a></li>
+<!-- if-pcrs-support-end@ -->
+<!-- @if-trust-support-start -->
+ <li>Trust List: <a href="show-status?file=trust">@trust-filename@</a></li>
+<!-- if-trust-support-end@ -->
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>Conditional #defines:</h2>
+ <p>
+ <table border="1" style="margin-left: 10px">
+ <tr>
+ <th>#define</th> <th>Enabled?</th> <th>Effects when enabled</th>
+ </tr>
+ <tr>
+ <td><code>FEATURE_ACL</code></td>
+ <td>@if-FEATURE_ACL-then@ Yes @else-not-FEATURE_ACL@ No @endif-FEATURE_ACL@</td>
+ <td>Allows the use of an ACL to control access to the proxy by IP address.</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_CGI_EDIT_ACTIONS</code></td>
+ <td>@if-FEATURE_CGI_EDIT_ACTIONS-then@ Yes @else-not-FEATURE_CGI_EDIT_ACTIONS@ No @endif-FEATURE_CGI_EDIT_ACTIONS@</td>
+ <td>Allows the use of the web-based actions file
+ editor@if-FEATURE_CGI_EDIT_ACTIONS-then@, which is <a href="@default-cgi@edit-actions">here</a>@else-not-FEATURE_CGI_EDIT_ACTIONS@@endif-FEATURE_CGI_EDIT_ACTIONS@.</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_COOKIE_JAR</code></td>
+ <td>@if-FEATURE_COOKIE_JAR-then@ Yes @else-not-FEATURE_COOKIE_JAR@ No @endif-FEATURE_COOKIE_JAR@</td>
+ <td>Allows the use of a "cookie jar" file to capture cookies.</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_FAST_REDIRECTS</code></td>
+ <td>@if-FEATURE_FAST_REDIRECTS-then@ Yes @else-not-FEATURE_FAST_REDIRECTS@ No @endif-FEATURE_FAST_REDIRECTS@</td>
+ <td>Allows the +fast-redirects action, to bypass redirect and logging scripts.</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_FORCE_LOAD</code></td>
+ <td>@if-FEATURE_FORCE_LOAD-then@ Yes @else-not-FEATURE_FORCE_LOAD@ No @endif-FEATURE_FORCE_LOAD@</td>
+ <td>Allows bypassing all filtering for a single page using the prefix "<code>@FORCE_PREFIX@</code>".</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_IMAGE_BLOCKING</code></td>
+ <td>@if-FEATURE_IMAGE_BLOCKING-then@ Yes @else-not-FEATURE_IMAGE_BLOCKING@ No @endif-FEATURE_IMAGE_BLOCKING@</td>
+ <td>Allows the +image ation, to send "blocked" images instead of HTML.</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_IMAGE_DETECT_MSIE</code></td>
+ <td>@if-FEATURE_IMAGE_DETECT_MSIE-then@ Yes @else-not-FEATURE_IMAGE_DETECT_MSIE@ No @endif-FEATURE_IMAGE_DETECT_MSIE@</td>
+ <td>Enables automatic detection of image and HTML requests from
+ Microsoft Internet Explorer users, overriding the setting of
+ +image in the actions file.</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_KILL_POPUPS</code></td>
+ <td>@if-FEATURE_KILL_POPUPS-then@ Yes @else-not-FEATURE_KILL_POPUPS@ No @endif-FEATURE_KILL_POPUPS@</td>
+ <td>Allows the +no-popups action, to block JavaScript popups.</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_NO_GIFS</code></td>
+ <td>@if-FEATURE_NO_GIFS-then@ Yes @else-not-FEATURE_NO_GIFS@ No @endif-FEATURE_NO_GIFS@</td>
+ <td>Use PNG instead of GIF for the built-in images.</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_PTHREAD</code></td>
+ <td>@if-FEATURE_PTHREAD-then@ Yes @else-not-FEATURE_PTHREAD@ No @endif-FEATURE_PTHREAD@</td>
+ <td>Use POSIX threads rather than native threads</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_STATISTICS</code></td>
+ <td>@if-FEATURE_STATISTICS-then@ Yes @else-not-FEATURE_STATISTICS@ No @endif-FEATURE_STATISTICS@</td>
+ <td>Enables the statistics function.</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_TOGGLE</code></td>
+ <td>@if-FEATURE_TOGGLE-then@ Yes @else-not-FEATURE_TOGGLE@ No @endif-FEATURE_TOGGLE@</td>
+ <td>Allow Privoxy to be "disabled" so it is just a normal non-blocking non-anonymizing proxy.</td>
+ </tr>
+ <tr>
+ <td><code>FEATURE_TRUST</code></td>
+ <td>@if-FEATURE_TRUST-then@ Yes @else-not-FEATURE_TRUST@ No @endif-FEATURE_TRUST@</td>
+ <td>Allows the use of trust files.</td>
+ </tr>
+ <tr>
+ <td><code>STATIC_PCRE</code></td>
+ <td>@if-STATIC_PCRE-then@ Yes @else-not-STATIC_PCRE@ No @endif-STATIC_PCRE@</td>
+ <td>Use the supplied statically-linked PCRE library. This is set automatically
+ by <code>./configure</code> if you do not have the libpcre installed.</td>
+ </tr>
+ <tr>
+ <td><code>STATIC_PCRS</code></td>
+ <td>@if-STATIC_PCRS-then@ Yes @else-not-STATIC_PCRS@ No @endif-STATIC_PCRS@</td>
+ <td>Use the supplied statically-linked PCRS library. This is set automatically
+ by <code>./configure</code> if you do not have the libpcrs installed.</td>
+ </tr>
+ </table>
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/show-status-file b/src/privoxytemplates/show-status-file
new file mode 100644
index 0000000..04e085f
--- /dev/null
+++ b/src/privoxytemplates/show-status-file
@@ -0,0 +1,150 @@
+##########################################################
+#
+# Show-Status-CGI Output template for Privoxy.
+# (Variant for the show-file mode)
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# file-description:
+# A descriptive name for the file being shown
+# contents:
+# The contents of the file being shown
+# filepath
+# The complete filename of the file being shown
+#
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# This is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Privoxy@@my-hostname@: Contents of @file-description@</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>Contents of @file-description@ (@filepath@)</h2>
+ <pre>@contents@</pre>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/show-url-info b/src/privoxytemplates/show-url-info
new file mode 100644
index 0000000..fa2e124
--- /dev/null
+++ b/src/privoxytemplates/show-url-info
@@ -0,0 +1,188 @@
+##########################################################
+#
+# Show-Url-Info-CGI Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+# url-given:
+# The CGI was called with a url parameter. In that case, the
+# following symbols are available:
+# url:
+# The given URL
+# default:
+# The system default for actions
+# matches:
+# The list of all matches in the actions file that this URL
+# produced, along with the actions that were triggered by
+# these matches
+# final:
+# The actions that are associated with the URL at the end of
+# the matching process
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Privoxy@@my-hostname@ URL Info</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+<!-- @if-url-given-start -->
+ <tr>
+ <td class="box">
+<!-- @if-https-start -->
+ <h2>NOTE:</h2>
+ <p>This is a secure (https:) URL, so the part after the "/" is ignored.
+ This is a feature of the HTTPS protocol - the exact address of the
+ page you're visiting is hidden. Privoxy can only detect the host
+ part of the URL.</p>
+ <p>&nbsp;</p>
+<!-- if-https-end@ -->
+ <h2>Matches for <a href="@url@">@url@</a>:</h2>
+ <p>@matches@</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>Final results:</h2>
+ <p><b>@final@</b></p>
+ </td>
+ </tr>
+<!-- if-url-given-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>Look up the actions for a
+<!-- @if-url-given-start -->new<!-- if-url-given-end@ -->
+ URL:</h2>
+ <form method="GET" action="@default-cgi@show-url-info">
+ <p>
+ <input type="text" name="url" size="80" value="@url@">
+ <input type="submit" value="Go">
+ </p>
+ </form>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/show-version b/src/privoxytemplates/show-version
new file mode 100644
index 0000000..bc7890a
--- /dev/null
+++ b/src/privoxytemplates/show-version
@@ -0,0 +1,163 @@
+##########################################################
+#
+# Show-Status-CGI Output template for Privoxy.
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# redirect-url:
+# The URL to a script that will redirect to the Privoxy
+# documentation for a given item
+# invocation:
+# The command line with whitch Privoxy was invoked
+# options:
+# The options read from the configfile, linked to their
+# explanations, plus warnings if parsing acl or forward
+# statements produced errors.
+# sourceversions:
+# A HTML-formatted list of the individual source file cvs versions
+# defines:
+# A HTML-formatted list of all conditional #defines used when
+# Privoxy was compiled
+#
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# This is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+# sourceversions
+# The versions.
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>Privoxy@@my-hostname@: Detailed proxy version information</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>Source code versions:</h2>
+ <p><i>(Note: This information is only relevant if you checked out Privoxy from CVS
+ and compiled it yourself. If you downloaded a binary, .exe, RPM, or a .tgz file,
+ then when you ask for support just mention the version number <b>@version@</b>
+ and the type of download you got.)</i>
+ </p>
+ <pre>@sourceversions@</pre>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+ </table>
+
+</body>
+</html>
diff --git a/src/privoxytemplates/toggle b/src/privoxytemplates/toggle
new file mode 100644
index 0000000..72fafd2
--- /dev/null
+++ b/src/privoxytemplates/toggle
@@ -0,0 +1,187 @@
+##########################################################
+#
+# Toggle Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+# @if-enabled-display-then@ on @else-not-enabled-display@ off @endif-enabled-display@
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+
+<head>
+ <title>@if-enabled-display-then@Enabled@else-not-enabled-display@Disabled@endif-enabled-display@ - Privoxy@@my-hostname@</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="title">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="box">
+ <h2>Privoxy is @if-enabled-display-then@Enabled@else-not-enabled-display@Disabled@endif-enabled-display@</h2>
+ <p>When enabled, Privoxy performs its magic - blocking
+ adverts, filtering cookies, regex-filtering, etc.</p>
+ <p>When disabled, Privoxy behaves as a normal HTTP proxy,
+ and will not affect your web browsing.</p>
+ <p><a href="@default-cgi@toggle?set=@if-enabled-display-then@disable@else-not-enabled-display@enable@endif-enabled-display@">Click
+ here</a> to @if-enabled-display-then@disable@else-not-enabled-display@enable@endif-enabled-display@ Privoxy.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>Bookmarklets</h2>
+ <p>Here are some bookmarklets to allow you to easily access a
+ "mini" version of this page. They are designed for MS
+ Internet Explorer, but should work equally well in
+ Netscape, Mozilla, and other browsers which support
+ JavaScript. They are designed to run directly from
+ your bookmarks - <b>not</b> by clicking the links
+ below (although that will work for testing).
+ </p>
+
+ <p>To save them, right-click the link and choose
+ "Add to Favorites" (IE) or "Add Bookmark" (Netscape). You
+ will get a warning that the bookmark "may not be safe" - just
+ click OK. Then you can run the Bookmarklet directly from your
+ favourites/bookmarks. For even faster access, you can put
+ them on the "Links" bar (IE) or the "Personal Toolbar"
+ (Netscape), and run them with a single click.
+ </p>
+
+ <ul>
+ <li><a href="javascript:void(window.open('@default-cgi@toggle?mini=y&amp;set=enabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Enable Privoxy</a></li>
+ <li><a href="javascript:void(window.open('@default-cgi@toggle?mini=y&amp;set=disabled','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Disable Privoxy</a></li>
+ <li><a href="javascript:void(window.open('@default-cgi@toggle?mini=y&amp;set=toggle','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">Toggle Privoxy</a>
+ (Toggles between enabled and disabled)</li>
+ <li><a href="javascript:void(window.open('@default-cgi@toggle?mini=y','ijbstatus','width=250,height=100,resizable=yes,scrollbars=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no').focus());">View Privoxy Status</a></li>
+ </ul>
+
+ <p>
+ <b>Credit:</b> The site which gave me the general idea for these
+ bookmarklets is <a href="http://www.bookmarklets.com/">www.bookmarklets.com</a>.
+ They have more information <a href="http://www.bookmarklets.com/about/">about bookmarklets</a>.
+ </p>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+
+ <tr>
+ <td>
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+ </table>
+
+</body>
+</html>
+
diff --git a/src/privoxytemplates/toggle-mini b/src/privoxytemplates/toggle-mini
new file mode 100644
index 0000000..bf06fba
--- /dev/null
+++ b/src/privoxytemplates/toggle-mini
@@ -0,0 +1,90 @@
+##########################################################
+#
+# Toggle Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# this is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+# @if-enabled-display-then@ on @else-not-enabled-display@ off @endif-enabled-display@
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<head>
+ <title>@if-enabled-display-then@Enabled@else-not-enabled-display@Disabled@endif-enabled-display@ - Privoxy@@my-hostname@</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+ <p class="whiteframed">
+ <a href="@default-cgi@" target="_blank">Privoxy</a> is
+ <b>@if-enabled-display-then@enabled@else-not-enabled-display@disabled@endif-enabled-display@</b>.
+ <br><a href="@default-cgi@toggle?mini=y&amp;set=@if-enabled-display-then@disable@else-not-enabled-display@enable@endif-enabled-display@"
+ >@if-enabled-display-then@[Disable]@else-not-enabled-display@[Enable]@endif-enabled-display@</a> |
+ <a href="javascript:window.close();">[Close]</a>
+ </p>
+</body>
+</html>
diff --git a/src/privoxytemplates/untrusted b/src/privoxytemplates/untrusted
new file mode 100644
index 0000000..d9c4529
--- /dev/null
+++ b/src/privoxytemplates/untrusted
@@ -0,0 +1,194 @@
+##########################################################
+#
+# "Untrusted" Error Output template for Privoxy.
+#
+#
+# USING HTML TEMPLATES:
+# ---------------------
+#
+# Template files are written win plain HTML, with a few
+# additions:
+#
+# - Lines that start with a '#' character like this one
+# are ignored
+#
+# - Each item in the below list of exported symbols will
+# be replaced by dynamically generated text, if they
+# are enclosed in '@'-characters. E.g. The string @version@
+# will be replaced by the version number of Privoxy.
+#
+# - One special application of this is to make whole blocks
+# of the HTML template disappear if the condition <name>
+# is not given. Simply enclose the block between the two
+# strings @if-<name>start and if-<name>-end@. The strings
+# should be placed in HTML comments (<!-- -->), so the
+# html structure won't be messed when the magic happens.
+#
+# USABLE SYMBOLS IN THIS TEMPLATE:
+# --------------------------------
+#
+# my-ip-addr:
+# The IP-address that the client used to reach this proxy
+# my-hostname:
+# The hostname associated with my-ip-addr
+# admin-address:
+# The email address of the pxoxy's administrator, as configured
+# in the config file
+# default-cgi:
+# The URL for the "main menu" builtin CGI of this proxy
+# menu:
+# List of <li> elements linking to the other available CGIs
+# version:
+# The version number of the proxy software
+# code-status:
+# The development status of the proxy software: "alpha", "beta",
+# or "stable".
+# homepage:
+# The URL of the SourceForge ijbswa project, who maintains this
+# software.
+#
+# hostport:
+# The host and port part of the request that lead to this problem
+# path:
+# The path part of the request that lead to this problem
+# referrer:
+# The referrer of the request that lead to this problem
+# trusted-referrers:
+# An HTML-formatted list of referrers that are marked as trusted in
+# the trustfile
+#
+#
+# CONDITIONAL SYMBOLS FOR THIS TEMPLATE AND THEIR DEPANDANT SYMBOLS:
+# ------------------------------------------------------------------
+#
+# unstable:
+# This is an alpha or beta release of the proxy software
+# have-adminaddr-info:
+# An e-mail address for the local Privoxy adminstrator has
+# been specified and is available through the "admin-address"
+# symbol
+# have-proxy-info:
+# A URL for online documentation about this proxy has been
+# specified and is available through the "proxy-info-url"
+# symbol
+# have-help-info:
+# If either have-proxy-info is true or have-adminaddr-info is
+# true, have-help-info is true. Used to conditionally include
+# a grey box for any and all help info.
+# force-support:
+# Privoxy has been compiled with support for forced loading
+# of blocked content. In that case, the symbol "force-prefix" is
+# avaiable, which translates to the FORCE_PREFIX
+# have-trust-info:
+# There were URLs with info on the trust policy defined in the config
+# file. In this case the list of URLs is available through the
+# "trust-info" symbol.
+#
+#
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html>
+
+<head>
+ <title>Untrusted request (Privoxy@@my-hostname@)</title>
+ <meta http-equiv="Content-Style-Type" content="text/css">
+ <meta http-equiv="Content-Script-Type" content="text/javascript">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+ <meta name="robots" content="noindex,nofollow">
+ <link rel="stylesheet" type="text/css" href="@default-cgi@send-stylesheet">
+</head>
+
+<body>
+
+ <table cellpadding="20" cellspacing="10" border="0" width="100%">
+ <tr>
+ <td class="status">
+ UNTRUSTED
+ </td>
+ <td class="title" style="width: 100%">
+
+#include mod-title
+
+ </td>
+ </tr>
+
+<!-- @if-unstable-start -->
+# This will only appear if CODE_STATUS is "alpha" or "beta". See configure.in
+ <tr>
+ <td class="warning" colspan="2">
+
+#include mod-unstable-warning
+
+ </td>
+ </tr>
+<!-- if-unstable-end@ -->
+
+ <tr>
+ <td class="warning" colspan="2">
+ <h2>Request for untrusted URL</h2>
+ <p>Your request for <b>@protocol@@hostport@@path@</b> was blocked,
+ because neither the request URL itself, nor its referrer
+ (<a href="@referrer@">@referrer@</a>) were trusted.
+ </p>
+<!-- @if-force-support-start -->
+ <p>(You can <a href="@protocol@@hostport@@force-prefix@@path@">go there anyway</a>.)</p>
+<!-- if-force-support-end@ -->
+ </td>
+ </tr>
+
+ <tr>
+ <td class="box" colspan="2">
+ <h2>The following referrers are trusted:</h2>
+ <ul>
+ @trusted-referrers@
+ </ul>
+ </td>
+ </tr>
+
+<!-- @if-have-trust-info-start -->
+ <tr>
+ <td class="box" colspan="2">
+ <h2>More information on the trust policy:</h2>
+ <p>You can learn more about what this means and what you may be able to do about it by
+ reading the following documents:
+ </p>
+ <ol>
+ @trust-info@
+ </ol>
+ </td>
+ </tr>
+<!-- if-have-trust-info-end@ -->
+
+ <tr>
+ <td class="box" colspan="2">
+ <h2>More Privoxy:</h2>
+ <ul>@menu@</ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td class="info" colspan="2">
+
+#include mod-support-and-service
+
+ </td>
+ </tr>
+
+<!-- @if-have-help-info-start -->
+ <tr>
+ <td class="info" colspan="2">
+
+#include mod-local-help
+
+ </td>
+ </tr>
+<!-- if-have-help-info-end@ -->
+
+ <tr>
+ <td colspan="2">
+ <p class="small">Valid <a href="http://validator.w3.org/">HTML 4.01 Strict</a></p>
+ </td>
+ </tr>
+
+ </table>
+
+</body>
+</html>
diff --git a/src/questions.h b/src/questions.h
new file mode 100644
index 0000000..fb3f882
--- /dev/null
+++ b/src/questions.h
@@ -0,0 +1,382 @@
+/***************************************************************************
+** $Id: questions.h,v 1.35 2008/08/14 21:17:39 hoganrobert Exp $
+ *
+ * Based on config method in Tor
+ *
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "tork.h"
+#include <qstring.h>
+
+
+/** A variable allowed in the configuration file or on the command line. */
+typedef struct question_t {
+ const char *logquestion; /**< The full keyword (case insensitive). */
+ const QString headline; /**< String (or null) describing initial value. */
+ const QString body; /**< String (or null) describing initial value. */
+ char torsaid[250]; /**< String (or null) describing initial value. */
+ const QString question; /**< String (or null) describing initial value. */
+ display_status_t state; /**< The type of the value. */
+ bool persistent;
+ bool showstopper;
+ const QString type; /**< String (or null) describing initial value. */
+ const char *icon; /**< String (or null) describing initial value. */
+ bool (tork::*pt2Member2)();
+ void (tork::*silentAction)();
+ void (tork::*pt2Member)();
+} question_t;
+
+
+/** An entry for config_vars: "The option <b>name</b> has type
+ * CONFIG_TYPE_<b>conftype</b>, and corresponds to
+ * or_options_t.<b>member</b>"
+ */
+#define MSG(logquestion,headline,body,torsaid,question, persistent, \
+ showstopper, state, type, icon, show, silentAction, doIt) \
+ { logquestion, headline,body,torsaid,question, persistent, showstopper, \
+ state, type, icon, show, silentAction, doIt }
+
+/** Array of configuration options. Until we disallow nonstandard
+ * abbreviations, order is significant, since the first matching option will
+ * be chosen first.
+ */
+static question_t _tork_questions[] = {
+ MSG("Your ContactInfo config option is not set",
+ i18n("You Are Running A Server Without Any Contact Information!"),
+ i18n("You can set your contact info in the configuration section 'My Server'. Please do so! "),
+ "",
+ i18n("Would you like to set your contact info now?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::contactInfoSet),
+ (&tork::dummyAction),
+ (&tork::enterContactInfo)),
+
+ MSG("Could not bind to",
+ i18n("Tor Couldn't Bind to One of the Addresses/Ports you configured!"),
+ i18n("Tor is probably already running. If you like, TorK can connect to the already-running instance of Tor and manage that for you instead. (You will have to open the configuration dialog and re-apply any settings you wished to use.) "),
+ "",
+ i18n("Would you like to do this now?"),
+ DISPLAY_NONE,
+ true,
+ true,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::dummyAction),
+ (&tork::fixAddressPort)),
+ MSG("has not managed to confirm that its ORPort is reachable",
+ i18n("Sorry! Your Tor Server is not working!"),
+ i18n("You could be blocking incoming traffic on your Tor port."),
+ "",
+ i18n("Would you like to see information on how to fix this?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::retryUPnP),
+ (&tork::serverHelp)),
+ MSG("has not managed to confirm that its DirPort is reachable",
+ i18n("Sorry! Your Tor Directory Server is not working! You can't share your copy of the network directory with other servers."),
+ i18n("You could be blocking incoming traffic on your Tor port."),
+ "",
+ i18n("Would you like to see information on how to fix this?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::retryUPnP),
+ (&tork::serverHelp)),
+ MSG("must have public IP addresses",
+ i18n("Sorry! You can't run a Tor Server!"),
+ i18n("You appear to be behind a NAT router and TorK/Tor can't determine your public IP address."),
+ "",
+ i18n("Would you like to continue running as a client only?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::dummyAction),
+ (&tork::continueAsClient)),
+ MSG("Our testing circuit (to see if your ORPort is reachable) has failed.",
+ i18n("A Test Connection to Your Server Failed!"),
+ i18n("The address/port you specified in 'My Server' is proving difficult to connect to! Is it your firewall maybe?"),
+ "",
+ i18n("Would you like to see information on how to fix this?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::retryUPnP),
+ (&tork::serverHelp)),
+ MSG("Please upgrade!",
+ i18n("Your Version of Tor is a Bit Out-of-Date!"),
+ i18n("TorK can download and compile the latest stable version for you."),
+ "",
+ i18n("Would you like to try this?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show TorK Feedback"),
+ "tork_torlogo",
+ (&tork::showGuideQuestions),
+ (&tork::dummyAction),
+ (&tork::updateTorStable)),
+ MSG("cannotcontacttor",
+ i18n("TorK cannot connect to Tor!"),
+ i18n("If you are trying to manage a remote or already-running instance of Tor you may not have configured the address and/or port of the Tor server correctly."),
+ "",
+ i18n("Would you like to configure the address and port now?"),
+ DISPLAY_NONE,
+ false,
+ true,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::dummyAction),
+ (&tork::quickConfig)),
+
+ MSG("applysettings",
+ i18n("Would you like to apply your settings to Tor?"),
+ i18n("You are connecting to a remote or local instance of Tor, it may not have the settings you've configured with TorK."),
+ "",
+ i18n("Would you like to apply the settings now? (Note that you can do this automatically in future by selecting the option in the 'Quick Configure' dialog.)"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Alway Ask Before Applying Settings "),
+ "tork_help",
+ (&tork::showApplySettingsQuestions),
+ (&tork::dummyAction),
+ (&tork::applySettingsToRunningTor)),
+
+ MSG("securitynotice",
+ i18n("Your Traffic Can Be Eavesdropped!"),
+ "",
+ "",
+ i18n("Try to use the secure version of services (e.g. https: instead of http:) if you are entering a username and password or the content is sensitive. Would you like to see an explanation of why using Tor can make un-encrypted traffic <b>potentially less secure</b> than normal?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show Security Warnings"),
+ "tork_info",
+ (&tork::showSecurityWarnings),
+ (&tork::dummyAction),
+ (&tork::readEavesdropping)),
+
+ MSG("privoxynotrunning",
+ i18n("Are you sure your Privacy Proxy is running?"),
+ i18n("TorK tested your configured privacy proxy and it does not seem "
+ "to be running."),
+ "",
+ i18n("Would you like TorK to use Privoxy instead?"),
+ DISPLAY_NONE,
+ true,
+ false,
+ i18n("Show Security Warnings"),
+ "tork_alert",
+ (&tork::showSecurityWarnings),
+ (&tork::dummyAction),
+ (&tork::letTorKManagePrivoxy)),
+
+ MSG("privoxycouldntstart",
+ i18n("TorK couldn't start your Privacy Proxy!"),
+ i18n("This may be because you have configured it to launch at system startup. If that is the case, and you have reason to believe it is configured to listen to Tor, then just click 'No' and take a look at the 'Konqueror' settings in the configuration dialog."),
+ "",
+ i18n("Would you like TorK to try restarting it again?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show Security Warnings"),
+ "tork_alert",
+ (&tork::showSecurityWarnings),
+ (&tork::dummyAction),
+ (&tork::startPrivoxy)),
+
+ MSG("privoxydied",
+ i18n("Your Privacy Proxy just stopped working!"),
+ i18n("It may have crashed."),
+ "",
+ i18n("Would you like TorK to restart it again?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show Security Warnings"),
+ "tork_alert",
+ (&tork::showSecurityWarnings),
+ (&tork::dummyAction),
+ (&tork::startPrivoxy)),
+
+ MSG("screamingnotice",
+ i18n("No! No! Won't Someone Please Think Of The Children!?"),
+ "",
+ "",
+ i18n("Would you like to see an explanation of why this is <b>absolutely the wrong thing to do</b> even by normal standards?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show Security Warnings"),
+ "tork_alert",
+ (&tork::showSecurityWarnings),
+ (&tork::dummyAction),
+ (&tork::readEavesdropping)),
+
+ MSG("needalpha",
+ i18n("This version of TorK needs the most recent unstable version of Tor!"),
+ i18n("You can still use TorK with this version of Tor, but the experience may be sub-optimal!"),
+ "",
+ i18n("Would you like to download the most recent alpha version and use that?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show Security Warnings"),
+ "tork_alert",
+ (&tork::showSecurityWarnings),
+ (&tork::dummyAction),
+ (&tork::updateTorUnstable)),
+
+ MSG("DANGEROUS_VERSION",
+ i18n("You have an unrecommended version of Tor!"),
+ i18n("You can still use TorK with this version of Tor, but the experience may be sub-optimal!"),
+ "",
+ i18n("Would you like to download the most recent stable version and use that?"),
+ DISPLAY_NONE,
+ false,
+ false,
+ i18n("Show Security Warnings"),
+ "tork_alert",
+ (&tork::showSecurityWarnings),
+ (&tork::dummyAction),
+ (&tork::updateTorStable)),
+
+ MSG("DANGEROUS_PORT",
+ i18n("You could leak password information to Tor operators!"),
+ i18n("This port is unencrypted and you could give away sensitive information!"),
+ "",
+ i18n("If you are sure you are comfortable with this, click 'Yes' and "
+ "Tor will allow traffic on these ports for the rest of this session."),
+ DISPLAY_NONE,
+ true,
+ false,
+ i18n("Show Security Warnings"),
+ "tork_alert",
+ (&tork::showSecurityWarnings),
+ (&tork::assignPortToRemove),
+ (&tork::allowPlainTextPorts)),
+
+ MSG("filterfailed",
+ i18n("One or More FailSafes Were Not Applied!"),
+ i18n("There was an error when applying your failsafe request."),
+ "",
+ i18n("Would you like to view the failsafe rules?"),
+ DISPLAY_NONE,
+ true,
+ false,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::dummyAction),
+ (&tork::quickConfig)),
+
+ MSG("cookierequired",
+ i18n("You need to use a cookie to connect to Tor!"),
+ i18n("TorK can look up the cookie and attempt to use it."),
+ "",
+ i18n("Would you like TorK to attempt connecting with a cookie?"),
+ DISPLAY_NONE,
+ true,
+ true,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::dummyAction),
+ (&tork::reconnectWithCookie)),
+
+ MSG("cookienotfound",
+ i18n("Tor's Authentication Cookie Not Available!"),
+ i18n("The cookie may be stored in a location that you do not have permission to access. TorK can run a script as 'root' and attempt to copy the cookie to an accessible location. You can then try connecting to Tor again."),
+ "",
+ i18n("Would you like do this? (You will be asked for the 'root' password."),
+ DISPLAY_NONE,
+ true,
+ true,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::dummyAction),
+ (&tork::copyCookie)),
+
+ MSG("jdsklajdkslajdskla",
+ i18n("Tor Controller is Not Responding!"),
+ i18n("TorK hasn't been able to contact Tor yet. "),
+ "",
+ i18n("Would you like to quit the connection attempt?"),
+ DISPLAY_NONE,
+ true,
+ false,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::dummyAction),
+ (&tork::stopTor)),
+
+ MSG("terminatetor",
+ i18n("Tor will close gracefully in 30 seconds!"),
+ i18n("The delay allows other Tor users to re-route their connections to other servers."),
+ "",
+ i18n("Would you like to go ahead and shut down immediately? "),
+ DISPLAY_NONE,
+ true,
+ true,
+ i18n("Show TorK Feedback"),
+ "tork_help",
+ (&tork::showGuideQuestions),
+ (&tork::dummyAction),
+ (&tork::stopTor)),
+
+ MSG("passwordlost",
+ i18n("You used the wrong password to connect to Tor!"),
+ i18n("Maybe TorK crashed and lost the temporary password for connecting to Tor?"),
+ "",
+ i18n("If Tor is running locally TorK can reset Tor and then retry the connection. Would you like TorK to try this (<b>it will need to ask for your root password</b>)? "),
+ DISPLAY_NONE,
+ true,
+ true,
+ i18n("Show TorK Feedback"),
+ "tork_alert",
+ (&tork::showGuideQuestions),
+ (&tork::dummyAction),
+ (&tork::resetTor)),
+
+
+ { NULL, NULL, NULL, "", NULL, DISPLAY_NONE, false, false, NULL, NULL,
+ NULL, NULL, NULL }
+};
+#undef MSG
diff --git a/src/quickconfig.ui b/src/quickconfig.ui
new file mode 100644
index 0000000..c027c26
--- /dev/null
+++ b/src/quickconfig.ui
@@ -0,0 +1,398 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>QuickConfig</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>QuickConfig</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>566</width>
+ <height>529</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Messages</string>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_ShowDNSLeaks</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>51</y>
+ <width>221</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Show DNS Leak Warnings</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_ShowSecurityWarnings</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>111</y>
+ <width>221</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Show Security Warnings</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_ShowUsageWarnings</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>21</x>
+ <y>81</y>
+ <width>221</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Show Usage Warnings</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>22</x>
+ <y>20</y>
+ <width>200</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Warning Messages&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_3_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>262</x>
+ <y>20</y>
+ <width>220</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Question Messages&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_ShowGuideQuestions</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>261</x>
+ <y>51</y>
+ <width>261</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Show Guide Questions</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_ShowApplySettingsQuestions</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>261</x>
+ <y>81</y>
+ <width>261</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string>Never Apply Settings Automatically</string>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>quickGroup</cstring>
+ </property>
+ <property name="title">
+ <string>Quick Configuration</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="4" column="3" rowspan="2" colspan="2">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>:</string>
+ </property>
+ </widget>
+ <spacer row="5" column="5">
+ <property name="name">
+ <cstring>spacer1_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>51</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="5">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>51</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QSpinBox" row="5" column="4">
+ <property name="name">
+ <cstring>kcfg_RemoteTorPort</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <spacer row="5" column="0">
+ <property name="name">
+ <cstring>spacer2_3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>41</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QComboBox" row="2" column="1" rowspan="1" colspan="4">
+ <item>
+ <property name="text">
+ <string>Run a Tor Client and Server With Default Settings</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Run a Tor Client and Relay Server With Default Settings</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Run a Tor Server With Default Settings</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Run a Tor Relay Server With Default Settings</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Run a Tor Client with Default Settings</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Let me configure Tor myself.</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Manage a Remote Instance of Tor</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Manage a Local Instance of Tor that's already running</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>QuickConfigure</cstring>
+ </property>
+ </widget>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>41</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="1">
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="6">
+ <property name="name">
+ <cstring>textLabel9</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; TorK allows you to configure Tor in a very fine-grained manner. However, it's possible to make a mess of things and stop Tor working properly. Tor has very sensible defaults, so you can choose whether you want to configure things yourself or let Tor decide it for you.
+&lt;p&gt; &lt;b&gt;If you choose to manage a remote instance of Tor or a local instance that's already running, only configuration changes made after you have connected to the remote instance will be applied to it.&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="7" column="1" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>kcfg_AlwaysAnonymizeKDE</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Anonymize Konqueror When Tor Starts</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="6" column="1">
+ <property name="name">
+ <cstring>spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit" row="5" column="2">
+ <property name="name">
+ <cstring>kcfg_RemoteTorAddress</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="1">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Address/ Port of Tor Instance:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>QuickConfigure</sender>
+ <signal>activated(int)</signal>
+ <receiver>QuickConfig</receiver>
+ <slot>QuickConfigure_activated(int)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">quickconfig.ui.h</include>
+</includes>
+<signals>
+ <signal>settingsChanged()</signal>
+ <signal>configChanged(const int &amp;)</signal>
+</signals>
+<slots>
+ <slot>QuickConfigure_activated( int item )</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+ <function access="private" specifier="non virtual">destroy()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/quickconfig.ui.h b/src/quickconfig.ui.h
new file mode 100644
index 0000000..eb4f518
--- /dev/null
+++ b/src/quickconfig.ui.h
@@ -0,0 +1,98 @@
+/***************************************************************************
+ * $Id: quickconfig.ui.h,v 1.11 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#include "torkconfig.h"
+#include <klocale.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <kdebug.h>
+#include <dcopref.h>
+#include <kconfig.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+
+
+void QuickConfig::init()
+{
+ QuickConfigure->setCurrentItem(TorkConfig::quickConfigure());
+
+ if (QuickConfigure->currentItem() >= 6){
+ if (QuickConfigure->currentItem() == 6)
+ kcfg_RemoteTorAddress->setEnabled(true);
+ kcfg_RemoteTorPort->setEnabled(true);
+ }else{
+ kcfg_RemoteTorAddress->setEnabled(false);
+ kcfg_RemoteTorPort->setEnabled(false);
+ }
+
+}
+
+
+
+void QuickConfig::QuickConfigure_activated( int item)
+{
+ emit configChanged(item);
+ kcfg_RemoteTorAddress->setEnabled(false);
+
+ if (item >= 6){
+ if (QuickConfigure->currentItem() == 6)
+ kcfg_RemoteTorAddress->setEnabled(true);
+ kcfg_RemoteTorPort->setEnabled(true);
+/* kcfg_ApplySettingsToInstance->setEnabled(true);*/
+ }else{
+ kcfg_RemoteTorPort->setEnabled(false);
+// kcfg_ApplySettingsToInstance->setEnabled(false);
+ }
+}
+
+void
+QuickConfig::destroy()
+{
+
+// configureKonqi();
+
+}
+
+// <connections>
+// <connection>
+// <sender>QuickConfigure</sender>
+// <signal>activated(int)</signal>
+// <receiver>QuickConfig</receiver>
+// <slot>QuickConfigure_activated(int)</slot>
+// </connection>
+// </connections>
+// <includes>
+// <include location="local" impldecl="in implementation">quickconfig.ui.h</include>
+// </includes>
+// <signals>
+// <signal>settingsChanged()</signal>
+// <signal>configChanged(const int &amp;)</signal>
+// </signals>
+// <slots>
+// <slot>QuickConfigure_activated( int item )</slot>
+// </slots>
+// <functions>
+// <function access="private" specifier="non virtual">init()</function>
+// <function access="private" specifier="non virtual">destroy()</function>
+// </functions>
+// <layoutdefaults spacing="6" margin="11"/>
+// </UI>
diff --git a/src/running.ui b/src/running.ui
new file mode 100644
index 0000000..fd87ecb
--- /dev/null
+++ b/src/running.ui
@@ -0,0 +1,593 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Running</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>Running</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>607</width>
+ <height>560</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>MyDialog1</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget8</cstring>
+ </property>
+ <attribute name="title">
+ <string>Startin&amp;g Tor</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="3" column="0">
+ <property name="name">
+ <cstring>I_m_</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>I'm Special</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="1" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>textLabel1_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;Use this special authoritative server for fetching the list of trusted servers. I hereby acknowledge that using such a server makes me more identifiable because I 'm not trusting the same servers as everyone else.</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="2">
+ <property name="name">
+ <cstring>kcfg_DirServer</cstring>
+ </property>
+ </widget>
+ <spacer row="0" column="0">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="0" column="5">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>41</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>120</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="1" column="4" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>130</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="2" column="0">
+ <property name="name">
+ <cstring>NormalOptions</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>I'm Normal</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Run as User</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="0" column="2">
+ <property name="name">
+ <cstring>pushButton10</cstring>
+ </property>
+ <property name="text">
+ <string>..</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="0" column="8">
+ <property name="name">
+ <cstring>pushButton10_2</cstring>
+ </property>
+ <property name="text">
+ <string>..</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="3" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>or as Group</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Use this directory for temporary runtime storage: </string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_User</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="7">
+ <property name="name">
+ <cstring>kcfg_Group</cstring>
+ </property>
+ </widget>
+ <widget class="KURLComboRequester" row="1" column="5" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>kcfg_DataDirectory</cstring>
+ </property>
+ <property name="mode">
+ <number>2</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>kcfg_DefaultRunningNormalOptions</cstring>
+ </property>
+ <property name="text">
+ <string>Let Tor look after m&amp;y normal settings.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+Y</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>Authentication</cstring>
+ </property>
+ <property name="title">
+ <string>Authentication</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_4</cstring>
+ </property>
+ <property name="text">
+ <string>Use this password to control Tor:</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kcfg_CookieAuthentication</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Authenticate using cookie created by Tor</string>
+ </property>
+ <property name="accel">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_HashedControlPassword</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kcfg_GenerateRandomPassword</cstring>
+ </property>
+ <property name="text">
+ <string>If No Authentication Set, Generate Random Password to Protect Session</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget9</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Using Tor</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox5</cstring>
+ </property>
+ <property name="title">
+ <string>Listen For Connecting Applications</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="1" column="2" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>IP:</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="6">
+ <property name="name">
+ <cstring>PushAdd</cstring>
+ </property>
+ <property name="text">
+ <string>O&amp;K</string>
+ </property>
+ <property name="accel">
+ <string>Alt+K</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="0" column="4" rowspan="2" colspan="3">
+ <column>
+ <property name="text">
+ <string>IP Address </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Port</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>SOCKSBindAddressMany</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="4">
+ <property name="name">
+ <cstring>Address</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>kcfg_SOCKSBindAddressHost</cstring>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="3" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>kcfg_SOCKSBindAddressPort</cstring>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="5">
+ <property name="name">
+ <cstring>Port</cstring>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>textLabel7_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; If you're feeling fancy you can add a list of addresses and ports you want Tor to listen to applications on. But you're probably not doing anything fancy, so you'll just want to leave it at:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox6</cstring>
+ </property>
+ <property name="title">
+ <string>Other Computers That Can Use My Tor</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView" row="0" column="1" rowspan="1" colspan="4">
+ <column>
+ <property name="text">
+ <string>Policy</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>IP Address </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Port</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>SOCKSPolicy</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="3">
+ <property name="name">
+ <cstring>SocksPort</cstring>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="4">
+ <property name="name">
+ <cstring>PushAdd2</cstring>
+ </property>
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="2">
+ <property name="name">
+ <cstring>SocksAddress</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <item>
+ <property name="text">
+ <string>accept</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>reject</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>Policy</cstring>
+ </property>
+ </widget>
+ <spacer row="2" column="2">
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; This is a list of rules stating who can and can't use your tor to connect to the internet.</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>SOCKSPolicy</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>Running</receiver>
+ <slot>SOCKSPolicy_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>SOCKSBindAddressMany</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>Running</receiver>
+ <slot>SOCKSBindAddressMany_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>PushAdd</sender>
+ <signal>clicked()</signal>
+ <receiver>Running</receiver>
+ <slot>PushAdd_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>PushAdd2</sender>
+ <signal>clicked()</signal>
+ <receiver>Running</receiver>
+ <slot>PushAdd2_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_DefaultRunningNormalOptions</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>Running</receiver>
+ <slot>kcfg_DefaultRunningNormalOptions_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_HashedControlPassword</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>Running</receiver>
+ <slot>kcfg_HashedControlPassword_textChanged(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_CookieAuthentication</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>Running</receiver>
+ <slot>kcfg_CookieAuthentication_toggled(bool)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">running.ui.h</include>
+</includes>
+<slots>
+ <slot>PushAdd_clicked()</slot>
+ <slot>PushAdd2_clicked()</slot>
+ <slot>SOCKSBindAddressMany_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotDeleteEntry()</slot>
+ <slot>SOCKSPolicy_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotDeletePolicyEntry()</slot>
+ <slot>kcfg_DefaultRunningNormalOptions_toggled( bool state )</slot>
+ <slot>kcfg_CookieAuthentication_toggled( bool )</slot>
+ <slot>kcfg_HashedControlPassword_textChanged( const QString &amp; )</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kurlrequester.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/src/running.ui.h b/src/running.ui.h
new file mode 100644
index 0000000..8111ad9
--- /dev/null
+++ b/src/running.ui.h
@@ -0,0 +1,228 @@
+/***************************************************************************
+ * $Id: running.ui.h,v 1.10 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+//dummy
+#include "torkconfig.h"
+#include <klocale.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <kdebug.h>
+
+void Running::init()
+{
+
+ QStringList existingMaps = TorkConfig::sOCKSBindAddressMany();
+ QListViewItem *tm;
+ for ( QStringList::Iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString entry = (*it).section(":",0,0);
+ QString port = (*it).section(":",1,1);
+
+ tm = new QListViewItem(SOCKSBindAddressMany,entry,port);
+ }
+
+ QStringList existingSocksPolicies = TorkConfig::sOCKSPolicy();
+
+ for ( QStringList::Iterator it = existingSocksPolicies.begin(); it != existingSocksPolicies.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString policy = (*it).section(" ",0,0);
+ QString section2 = (*it).section(" ",1,1);
+ QString entry = section2.section(":",0,0);
+ QString port = section2.section(":",1,1);
+
+
+ tm = new QListViewItem(SOCKSPolicy,policy,entry,port);
+ }
+
+
+}
+void Running::PushAdd_clicked()
+{
+ new QListViewItem(SOCKSBindAddressMany,Address->text(), Port->text());
+}
+
+void Running::PushAdd2_clicked()
+{
+ new QListViewItem(SOCKSPolicy,Policy->currentText(),SocksAddress->text(), SocksPort->text());
+}
+
+
+void Running::SOCKSBindAddressMany_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( SOCKSBindAddressMany );
+
+ menu->clear();
+ menu->insertItem( "Delete Entry", this,SLOT(slotDeleteEntry()) );
+ menu->popup( point );
+
+}
+
+
+void Running::slotDeleteEntry( )
+{
+
+ QListViewItemIterator it(SOCKSBindAddressMany, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (SOCKSBindAddressMany->isSelected( it.current()))
+ delete it.current();
+ ++it;
+ }
+
+}
+
+
+void Running::SOCKSPolicy_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( SOCKSPolicy );
+
+ menu->clear();
+ menu->insertItem( "Delete Entry", this,SLOT(slotDeletePolicyEntry()) );
+ menu->popup( point );
+
+}
+
+
+void Running::slotDeletePolicyEntry( )
+{
+
+ QListViewItemIterator it(SOCKSPolicy, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (SOCKSPolicy->isSelected( it.current()))
+ delete it.current();
+ ++it;
+ }
+
+
+}
+
+
+void Running::kcfg_DefaultRunningNormalOptions_toggled( bool state)
+{
+ NormalOptions->setEnabled(!state);
+}
+
+
+
+void Running::kcfg_CookieAuthentication_toggled( bool )
+{
+ if ( kcfg_CookieAuthentication->isChecked()){
+ kcfg_HashedControlPassword->setEnabled(false);
+ }else{
+ kcfg_HashedControlPassword->setEnabled(true);
+ }
+}
+
+
+void Running::kcfg_HashedControlPassword_textChanged( const QString & )
+{
+ if (! kcfg_HashedControlPassword->text().isEmpty()){
+ kcfg_CookieAuthentication->setEnabled(false);
+ }else{
+ kcfg_CookieAuthentication->setEnabled(true);
+ }
+
+}
+
+
+// <connections>
+// <connection>
+// <sender>SOCKSPolicy</sender>
+// <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+// <receiver>Running</receiver>
+// <slot>SOCKSPolicy_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+// </connection>
+// <connection>
+// <sender>SOCKSBindAddressMany</sender>
+// <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+// <receiver>Running</receiver>
+// <slot>SOCKSBindAddressMany_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+// </connection>
+// <connection>
+// <sender>PushAdd</sender>
+// <signal>clicked()</signal>
+// <receiver>Running</receiver>
+// <slot>PushAdd_clicked()</slot>
+// </connection>
+// <connection>
+// <sender>PushAdd2</sender>
+// <signal>clicked()</signal>
+// <receiver>Running</receiver>
+// <slot>PushAdd2_clicked()</slot>
+// </connection>
+// <connection>
+// <sender>kcfg_DefaultRunningNormalOptions</sender>
+// <signal>toggled(bool)</signal>
+// <receiver>Running</receiver>
+// <slot>kcfg_DefaultRunningNormalOptions_toggled(bool)</slot>
+// </connection>
+// <connection>
+// <sender>kcfg_HashedControlPassword</sender>
+// <signal>textChanged(const QString&amp;)</signal>
+// <receiver>Running</receiver>
+// <slot>kcfg_HashedControlPassword_textChanged(const QString&amp;)</slot>
+// </connection>
+// <connection>
+// <sender>kcfg_CookieAuthentication</sender>
+// <signal>toggled(bool)</signal>
+// <receiver>Running</receiver>
+// <slot>kcfg_CookieAuthentication_toggled(bool)</slot>
+// </connection>
+// <connection>
+// <sender>kcfg_ClientOnly</sender>
+// <signal>toggled(bool)</signal>
+// <receiver>Running</receiver>
+// <slot>kcfg_ClientOnly_toggled(bool)</slot>
+// </connection>
+// </connections>
+// <includes>
+// <include location="local" impldecl="in implementation">running.ui.h</include>
+// </includes>
+// <slots>
+// <slot>PushAdd_clicked()</slot>
+// <slot>PushAdd2_clicked()</slot>
+// <slot>SOCKSBindAddressMany_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+// <slot>slotDeleteEntry()</slot>
+// <slot>SOCKSPolicy_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+// <slot>slotDeletePolicyEntry()</slot>
+// <slot>kcfg_DefaultRunningNormalOptions_toggled( bool state )</slot>
+// <slot>kcfg_HashedControlPassword_textChanged( const QString &amp; )</slot>
+// <slot>kcfg_CookieAuthentication_toggled( bool )</slot>
+// <slot>kcfg_ClientOnly_toggled( bool state )</slot>
+// </slots>
+// <functions>
+// <function access="private" specifier="non virtual">init()</function>
+// </functions>
+// <layoutdefaults spacing="6" margin="11"/>
+// <includehints>
+// <includehint>kurlrequester.h</includehint>
+// <includehint>kcombobox.h</includehint>
+// <includehint>kpushbutton.h</includehint>
+// </includehints>
+
+
+
+
diff --git a/src/server.ui b/src/server.ui
new file mode 100644
index 0000000..c3df472
--- /dev/null
+++ b/src/server.ui
@@ -0,0 +1,758 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>MyServer</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>MyServer</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>532</width>
+ <height>513</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>MyDialog1</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>false</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget8</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;General</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>kcfg_ClientOnly</cstring>
+ </property>
+ <property name="text">
+ <string>Never Run As a Server, &amp;Even If Tor Thinks I've Got The Girth</string>
+ </property>
+ <property name="accel">
+ <string>Alt+E</string>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>ServerInfo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Tor Server Details</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_NickName</cstring>
+ </property>
+ <property name="maxLength">
+ <number>20</number>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="3">
+ <property name="name">
+ <cstring>kcfg_ContactInfo</cstring>
+ </property>
+ <property name="maxLength">
+ <number>40</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Contact Info:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Nick:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView" row="0" column="1">
+ <column>
+ <property name="text">
+ <string>CC</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>geoip</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>fp</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>My Family </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>MyFamily</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>pushButton2</cstring>
+ </property>
+ <property name="text">
+ <string>Delete Selected</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>textLabel7_2_2_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; This is a list of other servers that you administer. This will prevent people from using you more than once.
+&lt;p&gt;&lt;b&gt;You add to this list by right-clicking on your servers in the main 'Tor Network' tab and clicking 'Add to My Family'.&lt;/b&gt;&lt;/p&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="3" column="0">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_DirListenAddress</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Serve Tor Traffic on Local Port</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_ORListenAddress</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>Serve Tor Listings on Local Port</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox" row="3" column="1">
+ <property name="name">
+ <cstring>kcfg_ForwardPorts</cstring>
+ </property>
+ <property name="text">
+ <string>Improve Accessibility</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>This will tell Tor to adverise your Tor server on the common ports 80 and 443, &lt;br&gt; it will also tell your router to forward traffic on these ports to Tor.</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="4" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout4</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_PublishServerDescriptor</cstring>
+ </property>
+ <property name="text">
+ <string>Let the Tor Network know about me as a server</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="Line">
+ <property name="name">
+ <cstring>line1_2_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_MiddleMan</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Act as a Relay Server Only (Disables Your Exit Policies in the Tab Above).</string>
+ </property>
+ <property name="accel">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_BridgeRelay</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Act as an Anti-Censorship Relay</string>
+ </property>
+ <property name="accel">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="Line" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Performance</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>kcfg_DefaultServerPerformance</cstring>
+ </property>
+ <property name="text">
+ <string>Let Tor figure out the &amp;best performance options to use</string>
+ </property>
+ <property name="accel">
+ <string>Alt+B</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="Line" row="1" column="0">
+ <property name="name">
+ <cstring>line3</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <spacer row="3" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>240</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QGroupBox" row="2" column="0">
+ <property name="name">
+ <cstring>PerformanceOptions</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>Performance Options</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSpinBox" row="0" column="4">
+ <property name="name">
+ <cstring>kcfg_NumCPUs</cstring>
+ </property>
+ <property name="maxValue">
+ <number>5000</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="4">
+ <property name="name">
+ <cstring>kcfg_MaxOnionsPending</cstring>
+ </property>
+ <property name="maxValue">
+ <number>5000</number>
+ </property>
+ <property name="value">
+ <number>100</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Maximum number of encryption tasks to keep waiting:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Maximum number of simultaneous encryption tasks:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="2" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>every</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>When shutting down, wait at most: </string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="3" column="3" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kcfg_ShutDownWaitLength</cstring>
+ </property>
+ <property name="suffix">
+ <string> seconds</string>
+ </property>
+ <property name="maxValue">
+ <number>5000</number>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="2" column="4">
+ <item>
+ <property name="text">
+ <string>day</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>week</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>month</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>AccountingStart</cstring>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="1">
+ <property name="name">
+ <cstring>kcfg_AccountingMax</cstring>
+ </property>
+ <property name="suffix">
+ <string> MBs p/s</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Never exceed </string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="4" column="3" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kcfg_ConnLimit</cstring>
+ </property>
+ <property name="suffix">
+ <string> descriptors</string>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>textLabel4_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Do not start unless system can support at least</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>ExitPolicies</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Exit Policies</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>130</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox6</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Sites you do not want to send traffic to</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>textLabel5_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; When you are an exit server for a circuit it is your computer that the destination website or host will see - the traffic will have your name on it. If you are an exit server and do not want your server to route traffic to certain sites/hosts this is the place to specify them.&lt;/p&gt;
+&lt;p&gt;&lt;b&gt;Use '0' as the port to specify 'all ports'. Use '*' as the address to specify 'all addresses'&lt;/b&gt;.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="0" column="1" rowspan="1" colspan="4">
+ <column>
+ <property name="text">
+ <string>Policy</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>IP Address </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Port</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>ExitPolicy</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>false</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="3">
+ <property name="name">
+ <cstring>SocksPort</cstring>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="4">
+ <property name="name">
+ <cstring>PushAdd2</cstring>
+ </property>
+ <property name="text">
+ <string>O&amp;K</string>
+ </property>
+ <property name="accel">
+ <string>Alt+K</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <item>
+ <property name="text">
+ <string>accept</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>reject</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>Policy</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="2">
+ <property name="name">
+ <cstring>SocksAddress</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>kcfg_DefaultServerPerformance</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>MyServer</receiver>
+ <slot>checkBox6_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_MiddleMan</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>MyServer</receiver>
+ <slot>kcfg_MiddleMan_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>PushAdd2</sender>
+ <signal>clicked()</signal>
+ <receiver>MyServer</receiver>
+ <slot>pushAdd2_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>ExitPolicy</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>MyServer</receiver>
+ <slot>ExitPolicy_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>pushButton2</sender>
+ <signal>clicked()</signal>
+ <receiver>MyServer</receiver>
+ <slot>pushButton2_clicked()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">server.ui.h</include>
+</includes>
+<slots>
+ <slot>kcfg_DefaultServerIP_toggled( bool )</slot>
+ <slot>kcfg_MiddleMan_toggled( bool on )</slot>
+ <slot>checkBox6_toggled( bool state )</slot>
+ <slot>pushAdd2_clicked()</slot>
+ <slot>ExitPolicy_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotDeleteEntry()</slot>
+ <slot>pushButton2_clicked()</slot>
+ <slot>kcfg_BridgeRelay_toggled( bool on )</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/server.ui.h b/src/server.ui.h
new file mode 100644
index 0000000..19b083e
--- /dev/null
+++ b/src/server.ui.h
@@ -0,0 +1,217 @@
+/***************************************************************************
+ * $Id: server.ui.h,v 1.30 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "tork.h"
+#include "torkconfig.h"
+#include "upnpmanager.h"
+#include <klocale.h>
+#include <kdebug.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <kiconloader.h>
+
+#ifndef EXTERNAL_GEOIP
+# include "GeoIP-1.4.0/libGeoIP/GeoIP.h"
+#else
+# include <GeoIP.h>
+#endif
+
+using namespace bt;
+using namespace kt;
+
+void MyServer::init()
+{
+
+ kcfg_ForwardPorts->setEnabled(false);
+ if (UPnPManager::Manager()->routersDiscovered())
+ kcfg_ForwardPorts->setEnabled(true);
+
+ MyFamily->setSelectionMode( QListView::Extended );
+ MyFamily->setColumnWidthMode(0, QListView::Manual);
+ MyFamily->hideColumn(0);
+ MyFamily->header()->setResizeEnabled(FALSE, 0);
+ MyFamily->setColumnWidthMode(1, QListView::Manual);
+ MyFamily->hideColumn(1);
+ MyFamily->header()->setResizeEnabled(FALSE, 1);
+ MyFamily->setColumnWidthMode(2, QListView::Manual);
+ MyFamily->hideColumn(2);
+ MyFamily->header()->setResizeEnabled(FALSE, 2);
+ MyFamily->setResizeMode( QListView::LastColumn );
+
+ QStringList existingServers = TorkConfig::myFamily();
+ QListViewItem *tm;
+ QString fp;
+ QString nick;
+ QString geoipcc;
+ QString countryName;
+
+ for ( QStringList::Iterator it = existingServers.begin(); it != existingServers.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+
+ fp.setLength(0);
+ nick.setLength(0);
+ geoipcc = (*it).section("-",0,0);
+ fp = (*it).section("-",1,1);
+ nick = (*it).section("-",2);
+ countryName = GeoIP_country_name[(geoipcc).toInt()];
+
+ tm = new QListViewItem(MyFamily,countryName,geoipcc,fp,nick);
+ tm->setPixmap(3,QPixmap(SmallIcon("tork_" + QString(GeoIP_country_code[geoipcc.toInt()]).lower())));
+
+
+ }
+
+ ExitPolicy->setSorting(-1,false);
+ QStringList exitPolicy = TorkConfig::exitPolicy();
+ for ( QStringList::Iterator it = exitPolicy.end(); ; --it )
+ {
+ if ((it == exitPolicy.begin()) && ((*it).isEmpty()))
+ break;
+
+ if ((*it).isEmpty())
+ continue;
+
+ QString policy = (*it).section(" ",0,0);
+ QString section2 = (*it).section(" ",1,1);
+ QString ip = section2.section(":",0,0);
+ QString port = section2.section(":",1,1);
+ tm = new QListViewItem(ExitPolicy,policy, ip,port);
+
+ if (it == exitPolicy.begin())
+ break;
+
+ }
+ ExitPolicy->setSorting(-1,false);
+
+ if (TorkConfig::currentTorVersion().left(3) == "0.1"){
+ kcfg_BridgeRelay->setEnabled(false);
+ }
+
+ AccountingStart->setCurrentText(TorkConfig::accountingStart());
+
+}
+
+
+
+
+void MyServer::kcfg_DefaultServerIP_toggled( bool )
+{
+/* if ( kcfg_DefaultServerIP->isChecked()){
+ kcfg_ORPort->setEnabled(false);
+ }else{
+ kcfg_ORPort->setEnabled(true);
+ }*/
+}
+
+
+void MyServer::kcfg_MiddleMan_toggled( bool on)
+{
+ if (on )
+ tabWidget->page(2)->setEnabled(false);
+ else{
+ tabWidget->page(2)->setEnabled(true);
+ kcfg_BridgeRelay->setChecked(false);
+ }
+}
+
+
+void MyServer::checkBox6_toggled( bool state)
+{
+
+ PerformanceOptions->setEnabled(!state);
+
+ if (state){
+ kcfg_NumCPUs->setValue(TorkConfig::defaultNumCPUs());
+ kcfg_MaxOnionsPending->setValue(TorkConfig::defaultMaxOnionsPending());
+ kcfg_AccountingMax->setValue(TorkConfig::defaultAccountingMax());
+ AccountingStart->setCurrentText(TorkConfig::defaultAccountingStart());
+ kcfg_ShutDownWaitLength->setValue(TorkConfig::defaultShutDownWaitLength());
+ kcfg_ConnLimit->setValue(TorkConfig::defaultConnLimit());
+ }
+
+}
+
+void MyServer::pushAdd2_clicked()
+{
+ QString port;
+ if (SocksPort->text() == "0")
+ port = "*";
+ else
+ port = SocksPort->text();
+
+ new QListViewItem(ExitPolicy,Policy->text(0), SocksAddress->text(), port);
+}
+
+
+void MyServer::ExitPolicy_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( ExitPolicy );
+
+ menu->clear();
+ menu->insertItem( "Delete Entry", this,SLOT(slotDeleteEntry()) );
+ menu->popup( point );
+
+}
+
+
+void MyServer::slotDeleteEntry( )
+{
+
+ QListViewItemIterator it(ExitPolicy, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (ExitPolicy->isSelected( it.current()))
+ delete it.current();
+ ++it;
+ }
+
+
+}
+
+
+void MyServer::pushButton2_clicked()
+{
+
+ QListViewItemIterator it(MyFamily, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ delete it.current();
+ ++it;
+ }
+
+}
+
+
+void MyServer::kcfg_BridgeRelay_toggled( bool on)
+{
+ if (on ){
+ tabWidget->page(2)->setEnabled(false);
+ kcfg_MiddleMan->setChecked(true);
+ kcfg_PublishServerDescriptor->setChecked(true);
+ }else{
+ tabWidget->page(2)->setEnabled(true);
+ kcfg_MiddleMan->setChecked(false);
+ kcfg_PublishServerDescriptor->setChecked(false);
+ }
+
+}
+
+
diff --git a/src/serverwizard.ui b/src/serverwizard.ui
new file mode 100644
index 0000000..43cab96
--- /dev/null
+++ b/src/serverwizard.ui
@@ -0,0 +1,234 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ServerWizard</class>
+<widget class="QWizard">
+ <property name="name">
+ <cstring>ServerWizard</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>416</width>
+ <height>329</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Tor Server Guide</string>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>ServerName</cstring>
+ </property>
+ <attribute name="title">
+ <string>Naming your Tor Server</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Server Name</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;By running a Tor server you will allow users of the Tor network to route their traffic through your computer. Running a Tor server does not affect your own anonymity while using Tor.&lt;/p&gt;
+&lt;p&gt;Every Tor server has a nickname, for easy identification. It's not that important what you call it.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Server NickName:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="1">
+ <property name="name">
+ <cstring>serverName</cstring>
+ </property>
+ </widget>
+ <spacer row="1" column="1">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>ContactInfo</cstring>
+ </property>
+ <attribute name="title">
+ <string>In Case There's a Problem</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox1_2</cstring>
+ </property>
+ <property name="title">
+ <string>Contact Information</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;In case you inadvertently mis-configure your server, other operators or the Tor team may want to contact you so you can correct any issues..&lt;/p&gt;
+&lt;p&gt;You are not obliged to provide a contact email, but it will certainly help in the event of a problem.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="1">
+ <property name="name">
+ <cstring>contactMail</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Your email:</string>
+ </property>
+ </widget>
+ <spacer row="1" column="1">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>ServerReachability</cstring>
+ </property>
+ <attribute name="title">
+ <string>Making Your Server Reachable</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox1_2_2</cstring>
+ </property>
+ <property name="title">
+ <string>Opening Up Your Router For Tor Users</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;Most Tor users can access the internet over ports 80 (http://) and 443 (https://). It will help if these are the ports Tor advertises to them.&lt;/p&gt;
+&lt;p&gt;If you want, TorK can contact your router and tell it to ensure anything that arrives on ports 80 and 443 is sent to Tor. If you'd like to do this, tick the box below if it is enabled..&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QButtonGroup" row="1" column="0">
+ <property name="name">
+ <cstring>buttonGroup1</cstring>
+ </property>
+ <property name="title">
+ <string>Server Accessibility</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>ForwardPorts</cstring>
+ </property>
+ <property name="text">
+ <string>Make Tor Easily Accessible.</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>RoutersFound</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;No Routers Found. Check your local firewall and ensure your router has UPnP enabled.&lt;/b&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+</widget>
+<includes>
+ <include location="local" impldecl="in declaration">upnp/upnprouter.h</include>
+ <include location="local" impldecl="in implementation">serverwizard.ui.h</include>
+</includes>
+<signals>
+ <signal>setUpServer( int )</signal>
+</signals>
+<slots>
+ <slot>showPage( QWidget * w )</slot>
+ <slot>setServerType( int id )</slot>
+ <slot>accept()</slot>
+ <slot>reject()</slot>
+ <slot>displayDiscoveredRouters()</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/serverwizard.ui.h b/src/serverwizard.ui.h
new file mode 100644
index 0000000..3375298
--- /dev/null
+++ b/src/serverwizard.ui.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ ** $Id: serverwizard.ui.h,v 1.4 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <qstringlist.h>
+#include "tork.h"
+#include "torkconfig.h"
+#include "upnpmanager.h"
+
+using namespace bt;
+using namespace kt;
+int serverType;
+
+void ServerWizard::init()
+{
+ ForwardPorts->setEnabled(false);
+
+ if (UPnPManager::Manager()->routersDiscovered())
+ displayDiscoveredRouters();
+
+ serverName->setText("TorKServer");
+ KConfig emailConf( QString::fromLatin1("emaildefaults") );
+ emailConf.setGroup(QString::fromLatin1("Defaults"));
+ QString profile = QString::fromLatin1("PROFILE_");
+ profile += emailConf.readEntry(QString::fromLatin1("Profile"), QString::fromLatin1("Default"));
+ emailConf.setGroup(profile);
+
+ contactMail->setText(emailConf.readEntry(QString::fromLatin1("EmailAddress")));
+
+}
+
+
+void ServerWizard::displayDiscoveredRouters()
+{
+ ForwardPorts->setEnabled(true);
+ ForwardPorts->setChecked(true);
+
+ QString routers;
+ QStringList routerList;
+ routerList = UPnPManager::Manager()->discoveredRoutersNameList();
+ for ( QStringList::Iterator it = routerList.begin(); it != routerList.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ routers += "- <b>";
+ routers += (*it);
+ routers += "</b><br>";
+ }
+
+ QString routerText = i18n("Make Tor Accessible on the Following Routers:<p> %1").arg(routers);
+ RoutersFound->setText(routerText);
+
+}
+void
+ServerWizard::showPage( QWidget *w ) //virtual
+{
+ QWizard::showPage( w );
+
+
+ if (currentPage() == ServerReachability)
+ setFinishEnabled ( ServerReachability,true );
+}
+
+void
+ServerWizard::setServerType( int id ) //virtual
+{
+ serverType = id;
+}
+
+void
+ServerWizard::accept()
+{
+ TorkConfig::setNickName(serverName->text());
+ TorkConfig::setContactInfo(contactMail->text());
+ TorkConfig::setRunFirstServerWizard(false);
+ TorkConfig::setForwardPorts(ForwardPorts->isChecked());
+ TorkConfig::writeConfig();
+ emit setUpServer(serverType);
+ QDialog::accept();
+
+}
+
+void
+ServerWizard::reject()
+{
+ QDialog::reject();
+}
diff --git a/src/statgraph.cpp b/src/statgraph.cpp
new file mode 100644
index 0000000..4313e5f
--- /dev/null
+++ b/src/statgraph.cpp
@@ -0,0 +1,253 @@
+/***************************************************************************
+ * $Id: statgraph.cpp,v 1.7 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * (c) 2004-2005, Diego Pettenò *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "statgraph.h"
+
+#include <qpainter.h>
+#include <qlabel.h>
+#include <kdebug.h>
+
+#define SOFT_STEP 3
+
+const QColor StatGraph::defaultBgColor = Qt::black;
+const QColor StatGraph::defaultReadingColor = Qt::yellow;
+const QColor StatGraph::defaultLabelColor = Qt::white;
+const QColor StatGraph::defaultGridColor = Qt::lightGray;
+
+/// Color used to pass transparent colors
+//const QColor StatGraph::invalidColor = QColor(-1, -1, -1);
+
+StatGraph::StatGraph(QWidget *parent, ushort pace, ushort gridPace, const QString &label, const QColor &bgColor, const char *name)
+ : QLabel(parent, name), m_style(Shades), m_gridPace(gridPace), m_pace(pace)
+{
+ setLabel(label);
+ setBgColor(bgColor);
+
+ m_numReadings = width() / pace;
+ m_currReading = 0;
+ m_readings = new uint[m_numReadings]; memset(m_readings, 0, m_numReadings*sizeof(uint));
+
+}
+
+StatGraph::~StatGraph()
+{
+ delete[] m_readings;
+}
+
+void StatGraph::setBgColor(const QColor &color)
+{
+ m_bgColor = color;
+
+ if ( m_bgColor.isValid() )
+ setBackgroundColor(m_bgColor);
+}
+
+inline void StatGraph::paintGrid(QPainter &p)
+{
+ p.setPen(m_gridColor);
+
+ const uint gridLines = height() / m_gridPace;
+ static uint graphWidth = width();
+ for(uint i = 0; i < gridLines; i++)
+ {
+ const int lineHeight = i*m_gridPace;
+ p.drawLine(0, lineHeight, graphWidth-1, lineHeight);
+ }
+}
+
+inline void StatGraph::paintShades(QPainter &p)
+{
+ //kdDebug() << "StatGraph::paintShades()" << endl;
+ const uint graphHeight = height();
+ for(uint i = 0; i < m_numReadings; i++)
+ {
+ ushort tmpPos = (m_currReading + i + 1) % m_numReadings;
+ if ( m_readings[tmpPos] > graphHeight )
+ m_readings[tmpPos] = graphHeight;
+
+ for(uint j = 0; j < m_readings[tmpPos]; j++)
+ {
+ if (m_readings[tmpPos] == 0 || j == 0)
+ p.setPen(m_bgColor);
+ else
+ p.setPen(m_readingColor.dark((100 * m_readings[tmpPos]) / j));
+
+ p.drawPoint(i, graphHeight - 1 - j);
+ }
+ }
+}
+
+inline void StatGraph::paintBars(QPainter &p)
+{
+ //kdDebug() << "StatGraph::paintBars()" << endl;
+ const uint graphHeight = height();
+ // Draw the readings bars, then the lower to save on pen adjustments.
+ p.setPen(m_readingColor);
+ for(uint i = 0; i < m_numReadings; i++)
+ {
+ ushort tmpPos = (m_currReading + i + 1) % m_numReadings;
+ p.drawLine(i, graphHeight - 1 - m_readings[tmpPos], i, graphHeight - 1);
+ }
+}
+
+inline void StatGraph::paintLines(QPainter &p)
+{
+ //kdDebug() << "StatGraph::paintLines()" << endl;
+ const uint graphHeight = height();
+ // Draw the reading line, then the lower to save on pen adjustments.
+ p.setPen(m_readingColor);
+ for(uint i = 0; i < m_numReadings; i++)
+ {
+ ushort tmpPos = (m_currReading + i + 1) % m_numReadings;
+ p.drawPoint(i, graphHeight - 1 - m_readings[tmpPos]);
+ }
+}
+
+inline void StatGraph::paintLabel(QPainter &p)
+{
+ //kdDebug() << "StatGraph::paintLabel()" << endl;
+ p.setFont(QFont("Helvetica", 8));
+ p.setPen(m_labelColor);
+ p.drawText(rect(), AlignLeft | AlignTop, m_label);
+}
+
+void StatGraph::clear()
+{
+ memset(m_readings, 0, m_numReadings*sizeof(uchar));
+ update();
+}
+
+void StatGraph::addPercentReading(uchar reading, bool soft)
+{
+ //kdDebug() << "StatGraph::addPercentReading(" << (uint)reading << ", " << soft << ")" << endl;
+ // Rescale the readings to a measure in pixels.
+ uint pix = ( reading * height() )/100;
+
+ if ( soft )
+ softenReadings(pix);
+
+ m_currReading = (m_currReading+1) % m_numReadings;
+ m_readings[m_currReading] = pix;
+ update();
+ update();
+}
+
+void StatGraph::softenReadings(uint &reading)
+{
+ //kdDebug() << "StatGraph::softenReadings(" << reading << ")" << endl;
+ uint old = m_readings[m_currReading];
+
+ // Modify the reading.
+ if (reading > old + SOFT_STEP)
+ reading = old + SOFT_STEP;
+ else if (reading > SOFT_STEP && reading < old - SOFT_STEP)
+ reading = old - SOFT_STEP;
+}
+
+void StatGraph::resizeEvent(QResizeEvent *e)
+{
+ QLabel::resizeEvent(e);
+
+ uint oldNumReadings = m_numReadings;
+ m_numReadings = width() / m_pace;
+
+ if ( m_numReadings != oldNumReadings )
+ {
+ uint *oldReadings = m_readings;
+
+ m_readings = new uint[m_numReadings];
+ memset(m_readings, 0, m_numReadings*sizeof(uint));
+
+ if ( m_numReadings < oldNumReadings )
+ memcpy(m_readings, oldReadings, m_numReadings*sizeof(uint));
+ else
+ memcpy(m_readings, oldReadings, oldNumReadings*sizeof(uint));
+ delete oldReadings;
+ m_currReading %= m_numReadings;
+ }
+}
+
+void StatGraph::paintEvent(QPaintEvent *e)
+{
+ QLabel::paintEvent(e);
+ if ( ! m_readingColor.isValid() ) m_readingColor = defaultReadingColor;
+ if ( ! m_labelColor.isValid() ) m_labelColor = defaultLabelColor;
+ if ( ! m_gridColor.isValid() ) m_gridColor = defaultGridColor;
+
+ QPainter p(this);
+ if ( m_gridPace )
+ paintGrid(p);
+
+ switch(m_style)
+ {
+ case Shades:
+ paintShades(p); break;
+ case Bars:
+ paintBars(p); break;
+ case Lines:
+ paintLines(p); break;
+ default:
+ kdDebug() << "Unknown style " << m_style << endl;
+ }
+
+ if ( ! m_label.isNull() )
+ paintLabel(p);
+}
+
+void StatGraph::mousePressEvent(QMouseEvent *e)
+{
+ QLabel::mousePressEvent(e);
+ m_button = e->button();
+}
+
+void StatGraph::mouseReleaseEvent(QMouseEvent *e)
+{
+ QLabel::mouseReleaseEvent(e);
+ if ( m_button == e->button() )
+ {
+ switch(m_button)
+ {
+ case LeftButton:
+ emit clickedLeft();
+ break;
+ case RightButton:
+ emit clickedRight();
+ break;
+ default:
+ kdDebug() << "Unknown button combination" << endl;
+ }
+ }
+ m_button = Qt::NoButton;
+}
+
+#include "statgraph.moc"
diff --git a/src/statgraph.h b/src/statgraph.h
new file mode 100644
index 0000000..40a9c26
--- /dev/null
+++ b/src/statgraph.h
@@ -0,0 +1,229 @@
+/***************************************************************************
+ * $Id: statgraph.h,v 1.4 2008/07/31 19:56:26 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * KCPULoad and KNetLoad are copyright (c) 1999-2000, Markus Gustavsson *
+ * (c) 2002, Ben Burton *
+ * (c) 2004-2005, Diego Pettenò *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef STATGRAPH_H
+#define STATGRAPH_H
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qcolor.h>
+#include <qlabel.h>
+
+/**
+ * @author Diego 'Flameeyes' Pettenò
+ *
+ * @brief Abstraction of the dock's graph class for KNetLoad and KCPULoad.
+ *
+ * This classes abstracts the access to the graphs for KNetLoad and KCPULoad
+ * (and eventually other apps, too), making possible to use them without
+ * system trays and so on.
+ *
+ */
+class StatGraph : public QLabel {
+Q_OBJECT
+public:
+//@{
+/**
+ * @name defaultcolors Default graphs' colors
+ * @brief These colors will be used as defaults color for graphs.
+ */
+ static const QColor defaultBgColor;
+ static const QColor defaultReadingColor;
+ static const QColor defaultLabelColor;
+ static const QColor defaultGridColor;
+ static const QColor invalidColor; ///< Color used to pass transparent colors
+//@}
+
+ enum Style { Lines, Bars, Shades };
+protected:
+ Style m_style; ///< Style of the graph
+ QString m_label; ///< Label to show on the graph (QString::null to not show label)
+
+ QColor m_bgColor; ///< Background color for the graph @see defaultBgColor
+ QColor m_readingColor; ///< Color for the readings graph
+ QColor m_labelColor; ///< Color for the graph's label (if any)
+ QColor m_gridColor; ///< Color for the graph's grid (if any)
+
+ ushort m_gridPace; ///< Pace at which a the grid is drawn. If 0, the grid is not drawn.
+ ushort m_pace; ///< Horizontal pace for readings
+ uint m_numReadings; ///< Maximum number of readings (label's width / graph's pace)
+ uint m_currReading; ///< Current index in the readings arrays.
+ uint *m_readings; ///< Array for readings.
+
+ Qt::ButtonState m_button; ///< Button clicked in pressed/released events
+public:
+ /**
+ * @brief Constructor for a StatGraph instance
+ * @param parent Label where to draw the graph
+ * @param pace X-distance between two reads. This will also influence the number
+ * of readings which can be added (label's width / pace)
+ * @param gridPace Y-distance between two grid lines. If 0, the grid is not drawn.
+ * @param label Label to show on the graph (QString::null to not show label)
+ * @param bgColor Background color to apply to the graph
+ * @param name Name of the statgraph instance (passed to QObject)
+ *
+ * This constructor initialize the QObject parent class and the
+ * label which will be used to draw the graph on.
+ * Note: it will @b not change the background of the label, nor it will draw
+ * the label.
+ */
+ StatGraph(QWidget *parent, ushort pace = 1, ushort gridPace = 0, const QString &label = QString::null, const QColor &bgColor = defaultBgColor, const char *name = "");
+
+ virtual ~StatGraph();
+
+ /**
+ * @brief Sets the graph's style
+ */
+ void setStyle(Style style)
+ { m_style = style; }
+
+protected:
+ virtual void resizeEvent(QResizeEvent*);
+ virtual void paintEvent(QPaintEvent*);
+ virtual void mousePressEvent(QMouseEvent *);
+ virtual void mouseReleaseEvent(QMouseEvent *);
+
+ /**
+ * @brief Paints the grid on the graph
+ */
+ void paintGrid(QPainter &p);
+
+ /**
+ * @brief Paints the graph using Shades style
+ */
+ void paintShades(QPainter &p);
+
+ /**
+ * @brief Paints the graph using Bars style
+ */
+ void paintBars(QPainter &p);
+
+ /**
+ * @brief Paints the graph using Lines style
+ */
+ void paintLines(QPainter &p);
+
+ /**
+ * @brief Paints the label on the graph
+ */
+ void paintLabel(QPainter &p);
+
+ /**
+ * @brief Apply softening algorithm to readings
+ *
+ * This function is called to 'soften' the readings when addPercentReadings() is
+ * called with @c soft parameter true.
+ */
+ void softenReadings(uint &reading);
+
+public slots:
+ /**
+ * @brief REquest a clear of the graph
+ *
+ * This functions resets the readings arrays and redraw completely the graph.
+ */
+ void clear();
+
+ /**
+ * @brief Sets the label to show on the graph
+ *
+ * This function sets the string to show on the graph.
+ * To disable showLabel, simply pass QString::null as label to show.
+ */
+ inline void setLabel(const QString &label)
+ {
+ m_label = label;
+ }
+
+ /**
+ * @brief Sets the background color for the graph.
+ *
+ * This function sets the background color for the graph instance
+ * To set the background to transparent, simply pass invalidColor value.
+ */
+ void setBgColor(const QColor &color);
+
+ /**
+ * @brief Sets the reading color for the graph.
+ *
+ * This function sets the reading color for the graph instance.
+ * @note Passing invalidColor to this, made it move to the default color
+ * as soon as a redraw is requested.
+ */
+ inline void setReadingColor(const QColor &color)
+ { m_readingColor = color; }
+
+ /**
+ * @brief Sets the label color for the graph.
+ *
+ * This function sets the label color for the graph instance.
+ * @note Passing invalidColor to this, made it move to the default color
+ * as soon as a redraw is requested.
+ */
+ inline void setLabelColor(const QColor &color)
+ { m_labelColor = color; }
+
+ /**
+ * @brief Sets the grid color for the graph.
+ *
+ * This function sets the grid color for the graph instance.
+ * @note Passing invalidColor to this, made it move to the default color
+ * as soon as a redraw is requested.
+ */
+ inline void setGridColor(const QColor &color)
+ { m_gridColor = color; }
+
+ /**
+ * @brief Sets the grid pace for the graph.
+ *
+ * This function sets the grid pace for the graph instance.
+ * @note Pass 0 to disable grid painting.
+ */
+ inline void setGridPace(const ushort gridpace)
+ { m_gridPace = gridpace; }
+
+ /**
+ * @brief Add the given reading as the most recent in our list.
+ * @param reading The reading
+ * @param soft If true, the reading will be aproximated to have a soft curve.
+ *
+ * The diagram will be updated accordingly.
+ */
+ void addPercentReading(uchar reading, bool soft);
+
+signals:
+ void clickedLeft();
+ void clickedRight();
+};
+
+#endif
diff --git a/src/testprivacyproxy.cpp b/src/testprivacyproxy.cpp
new file mode 100644
index 0000000..7b03f44
--- /dev/null
+++ b/src/testprivacyproxy.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+ ** $Id: testprivacyproxy.cpp,v 1.2 2008/08/20 16:49:31 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#include <qsocket.h>
+#include <qtextstream.h>
+#include "testprivacyproxy.h"
+#include "tork.h"
+#include "torkconfig.h"
+
+#include <qtimer.h>
+#include <klocale.h>
+#include <assert.h>
+#include <qfile.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <kstandarddirs.h>
+#include <qdir.h>
+
+
+TestPrivoxy::TestPrivoxy( )
+{
+ // create the socket and connect various of its signals
+ socket = new QSocket( this );
+ connect( socket, SIGNAL(connected()),
+ SLOT(socketConnected()) );
+ connect( socket, SIGNAL(connectionClosed()),
+ SLOT(socketConnectionClosed()) );
+/* connect( socket, SIGNAL(readyRead()),
+ SLOT(socketReadyRead()) );*/
+ connect( socket, SIGNAL(error(int)),
+ SLOT(socketError(int)) );
+
+
+}
+
+void TestPrivoxy::connectTo(const QString &host, Q_UINT16 port )
+{
+ // connect to the server
+ socket->connectToHost( host, port );
+}
+
+TestPrivoxy::~TestPrivoxy( )
+{
+}
+
+#include "testprivacyproxy.moc"
+
diff --git a/src/testprivacyproxy.h b/src/testprivacyproxy.h
new file mode 100644
index 0000000..c139edb
--- /dev/null
+++ b/src/testprivacyproxy.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+ ** $Id: testprivacyproxy.h,v 1.2 2008/08/20 16:49:31 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#ifndef _TESTPRIVACYPROXY_H_
+#define _TESTPRIVACYPROXY_H_
+
+#include <qsocket.h>
+#include <qtextstream.h>
+#include <kdebug.h>
+#include <kconfigskeleton.h>
+#include <qlistview.h>
+#include "torkconfig.h"
+
+
+class TestPrivoxy : public QObject
+{
+ Q_OBJECT
+public:
+ TestPrivoxy( );
+
+ virtual ~TestPrivoxy();
+
+
+ void sendToServer(const QString &string)
+ {
+ if (!socket)
+ return;
+ QTextStream os(socket);
+ os << string << "\r\n";
+ }
+
+public slots:
+// void socketReadyRead();
+
+ void closeConnection()
+ {
+ socket->close();
+ if ( socket->state() == QSocket::Closing ) {
+ // We have a delayed close.
+ connect( socket, SIGNAL(delayedCloseFinished()),
+ SLOT(socketClosed()) );
+ } else {
+ // The socket is closed.
+ socketClosed();
+ }
+ }
+
+ void connectTo(const QString &host, Q_UINT16 port);
+
+signals:
+
+ void connectedToPrivacyProxy();
+ void privacyProxyConnectionClosed();
+ void fatalError();
+
+private slots:
+
+
+ void socketConnected()
+ {
+ emit connectedToPrivacyProxy();
+ }
+
+ void socketConnectionClosed()
+ {
+ emit privacyProxyConnectionClosed();
+ }
+
+ void socketClosed()
+ {
+ }
+
+ void socketError( int e )
+ {
+ if ( e == QSocket::ErrHostNotFound ||
+ e == QSocket::ErrConnectionRefused )
+ emit fatalError();
+ }
+
+
+private:
+ QSocket *socket;
+};
+
+#endif //
+
+
diff --git a/src/tor_ioslave/Makefile.am b/src/tor_ioslave/Makefile.am
new file mode 100644
index 0000000..c64d2ff
--- /dev/null
+++ b/src/tor_ioslave/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = $(all_includes)
+LIBS =
+
+kde_module_LTLIBRARIES = kio_torioslave.la
+
+kio_torioslave_la_SOURCES = torioslave.cpp
+kio_torioslave_la_LIBADD = -lkio
+kio_torioslave_la_LDFLAGS = -module -avoid-version $(all_libraries) $(KDE_PLUGIN)
+
+protocol_DATA = torioslave.protocol
+protocoldir = $(kde_servicesdir)
+
+messages: rc.cpp
+ $(EXTRACTRC) `find . -name \*.ui -o -name \*.rc` > rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kio_torioslave.pot
diff --git a/src/tor_ioslave/torioslave.cpp b/src/tor_ioslave/torioslave.cpp
new file mode 100644
index 0000000..961b1d0
--- /dev/null
+++ b/src/tor_ioslave/torioslave.cpp
@@ -0,0 +1,167 @@
+/***************************************************************************
+** $Id: torioslave.cpp,v 1.7 2008/07/31 19:56:29 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <qcstring.h>
+#include <qsocket.h>
+#include <qdatetime.h>
+#include <qbitarray.h>
+
+#include <stdlib.h>
+#include <math.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kinstance.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <klocale.h>
+#include <kurl.h>
+#include <ksock.h>
+#include <dcopref.h>
+#include <dcopclient.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <krun.h>
+#include <kprocio.h>
+
+#include "torioslave.h"
+
+using namespace KIO;
+
+
+kio_torProtocol::kio_torProtocol(const QCString &pool_socket, const QCString &app_socket)
+ : SlaveBase("kio_tor", pool_socket, app_socket)
+{
+}
+
+
+kio_torProtocol::~kio_torProtocol()
+{
+}
+
+
+void kio_torProtocol::get(const KURL& url )
+{
+
+ QString wait;
+ QByteArray output;
+
+ QTextStream os( output, IO_WriteOnly );
+ os.setEncoding( QTextStream::Latin1 ); // In fast ASCII
+
+ QString cleanedurl = url.prettyURL().replace("tor://","");
+ cleanedurl = cleanedurl.replace("tor:/","");
+ cleanedurl = cleanedurl.replace("tor:","");
+ cleanedurl = cleanedurl.replace(" ","");
+ bool cantdo = false;
+
+ if (cleanedurl.contains(".txt"))
+ cantdo = true;
+
+ if (cleanedurl.contains("://") && (cleanedurl.left(4) != "http"))
+ cantdo = true;
+
+ if (cantdo){
+
+ os << QString("<html><head><title>Tor</title></head><body>%1 is not a valid URL for this feature. Websites only I'm afraid. And no file extensions either!</body></html>").arg(cleanedurl);
+
+ data( output );
+ finished();
+ return;
+ }
+
+ if ((cleanedurl.left(7) != "http://") && (cleanedurl.left(8) != "https://"))
+ cleanedurl.prepend("http://");
+
+ bool m_torkrunning = false;
+ bool anonymized = false;
+
+ DCOPClient* p_dcopServer= new DCOPClient();
+ p_dcopServer->attach ();
+
+ if (p_dcopServer->isApplicationRegistered ("tork")){
+ m_torkrunning = true;
+ DCOPRef tork( "tork", "DCOPTork" );
+ anonymized = tork.call( "getKDESetting" );
+ }
+
+
+
+ if (m_torkrunning){
+ DCOPRef("tork*", "DCOPTork").send("startEverything");
+ if (!anonymized)
+ DCOPRef("tork*", "DCOPTork").send("toggleKDESetting");
+ wait = "3";
+ }else{
+ KProcIO *whichproc = new KProcIO();
+ whichproc->setUseShell(TRUE);
+ QString whichCommand="tork --toggleKDE";
+
+ *whichproc<<whichCommand;
+
+ whichproc->start(KProcIO::NotifyOnExit,TRUE);
+
+ //KRun::runCommand( "tork --toggleKDE");
+ wait = "10";
+ }
+
+
+ os << QString("<html><head><title>Tor</title><META HTTP-EQUIV='Refresh' CONTENT='%1; URL=%2'></head><body>Will load %3 anonymously in a moment.</body></html>").arg(wait).arg(cleanedurl).arg(cleanedurl);
+
+ data( output );
+ finished();
+
+}
+
+
+void kio_torProtocol::mimetype(const KURL & /*url*/)
+{
+ mimeType("text/html");
+ finished();
+}
+
+
+extern "C"
+{
+ int kdemain(int argc, char **argv)
+ {
+ KInstance instance( "kio_tor" );
+
+ kdDebug(7101) << "*** Starting kio_tor " << endl;
+
+ if (argc != 4) {
+ kdDebug(7101) << "Usage: kio_tor protocol domain-socket1 domain-socket2" << endl;
+ exit(-1);
+ }
+
+ kio_torProtocol slave(argv[2], argv[3]);
+ slave.dispatchLoop();
+
+ kdDebug(7101) << "*** kio_tor Done" << endl;
+ return 0;
+ }
+}
diff --git a/src/tor_ioslave/torioslave.h b/src/tor_ioslave/torioslave.h
new file mode 100644
index 0000000..05e90ca
--- /dev/null
+++ b/src/tor_ioslave/torioslave.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+** $Id: torioslave.h,v 1.3 2008/07/31 19:56:29 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef _tor_H_
+#define _tor_H_
+
+#include <qstring.h>
+#include <qcstring.h>
+
+#include <kurl.h>
+#include <kio/global.h>
+#include <kio/slavebase.h>
+
+class QCString;
+
+class kio_torProtocol : public KIO::SlaveBase
+{
+public:
+ kio_torProtocol(const QCString &pool_socket, const QCString &app_socket);
+ virtual ~kio_torProtocol();
+ virtual void mimetype(const KURL& url);
+ virtual void get(const KURL& url);
+};
+
+#endif
diff --git a/src/tor_ioslave/torioslave.lsm b/src/tor_ioslave/torioslave.lsm
new file mode 100644
index 0000000..8734d50
--- /dev/null
+++ b/src/tor_ioslave/torioslave.lsm
@@ -0,0 +1,16 @@
+Begin3
+Title: torioslave -- Some description
+Version: 0.1
+Entered-date:
+Description:
+Keywords: KDE Qt
+Author: Robert Hogan <robert@roberthogan.net>
+Maintained-by: Robert Hogan <robert@roberthogan.net>
+Home-page:
+Alternate-site:
+Primary-site: ftp://ftp.kde.org/pub/kde/unstable/apps/utils
+ xxxxxx torioslave-0.1.tar.gz
+ xxx torioslave-0.1.lsm
+Platform: Linux. Needs KDE
+Copying-policy: GPL
+End
diff --git a/src/tor_ioslave/torioslave.protocol b/src/tor_ioslave/torioslave.protocol
new file mode 100644
index 0000000..efb6111
--- /dev/null
+++ b/src/tor_ioslave/torioslave.protocol
@@ -0,0 +1,29 @@
+[Protocol]
+exec=kio_torioslave
+protocol=tor
+input=none
+output=stream
+reading=true
+defaultMimetype=text/html
+Icon=tork_tor
+Description=A kioslave for tor
+Description[da]=En kioslave til tor
+Description[de]=Ein Ein-/Ausgabemodul für tor
+Description[es]=Un kioslave para tor
+Description[et]=tor IO-moodul
+Description[fr]=Un module d'entrée / sortie pour tor
+Description[hu]=tor-támogató KIOslave
+Description[it]=Un kioslave per tor
+Description[nl]=Kioslave voor tor
+Description[pl]=kioslave dla tor
+Description[pt]=Um 'kioslave' para tor
+Description[pt_BR]=Um kioslave para tor
+Description[ru]=Обработчик ввода-вывода для tor
+Description[sl]=kioslave za tor
+Description[sr]=KIOSlave за tor
+Description[sr@Latn]=KIOSlave za tor
+Description[sv]=En I/O-slav för tor
+Description[tr]=tor için bir kioslave
+Description[uk]=Підлеглий В/В (kioslave) для tor
+Description[xx]=xxA kioslave for torxx
+Description[zh_CN]=tor 的 kioslave
diff --git a/src/torclient.cpp b/src/torclient.cpp
new file mode 100644
index 0000000..a29051a
--- /dev/null
+++ b/src/torclient.cpp
@@ -0,0 +1,1536 @@
+/****************************************************************************
+ ** $Id: torclient.cpp,v 1.138 2009/10/13 20:19:51 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#include <qsocket.h>
+#include <qtextstream.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+#include "torclient.h"
+#include "tork.h"
+#include "torkconfig.h"
+#include "dndlistview.h"
+#include "functions.h"
+
+#include <qtimer.h>
+#include <klocale.h>
+#include <assert.h>
+#include <qfile.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <kstandarddirs.h>
+#include <qdir.h>
+#include "crypto.h"
+
+#ifndef EXTERNAL_GEOIP
+# include "GeoIP-1.4.0/libGeoIP/GeoIP.h"
+#else
+# include <GeoIP.h>
+#endif
+
+/* Linux-specific includes */
+#include <dirent.h>
+#include <unistd.h>
+
+using namespace tk;
+
+
+TorClient::TorClient( const QString &host, Q_UINT16 port )
+{
+ // create the socket and connect various of its signals
+ socket = new QSocket( this );
+ connect( socket, SIGNAL(connected()),
+ SLOT(socketConnected()) );
+ connect( socket, SIGNAL(connectionClosed()),
+ SLOT(socketConnectionClosed()) );
+ connect( socket, SIGNAL(readyRead()),
+ SLOT(socketReadyRead()) );
+ connect( socket, SIGNAL(error(int)),
+ SLOT(socketError(int)) );
+
+ // connect to the server
+ //infoText->append( tr("Trying to connect to the server\n") );
+ socket->connectToHost( host, port );
+ m_expectingCircuitInfo= false;
+ m_expectingStreamInfo= false;
+ m_expectingOrconnInfo= false;
+ m_expectingGuardsInfo= false;
+ m_expectingDirStatus= false;
+ m_expectingServerInfo= false;
+ m_controllerWorking= false;
+ m_firstloadcomplete = false;
+ m_resolvingServerAddress = false;
+
+ clearServers();
+
+ serverReport.append("<font color='#990000'>Status Not Known</font>");
+ clientReport.append("<font color='#990000'>Status Not Known</font>");
+ serverStatus["DANGEROUS_VERSION"] = "<font color='#990000'>Server Requires Upgrade</font>";
+ serverStatus["TOO_MANY_CONNECTIONS"] = "<font color='#990000'>Recently Exceeded Local Connection Limit. Check Local System</font>";
+ serverStatus["CLOCK_SKEW"] = "<font color='#990000'>Your Local Clock Is Skewed. Check Local System.</font>";
+ serverStatus["BAD_LIBEVENT"] = "<font color='#990000'>Libevent Installation Requires Upgrade</font>";
+ serverStatus["DIR_ALL_UNREACHABLE"] = "<font color='#990000'>Tor Network Unreachable.</font>";
+// serverStatus["NAMESERVER_ALL_DOWN"] = "Your DNS Servers are down.";
+ serverStatus["DNS_HIJACKED"] = "<font color='#990000'>Your Provider is Hijacking DNS Requests.</font>";
+ serverStatus["DNS_USELESS"] = "<font color='#990000'>Your Provider is Hijacking DNS Requests.</font>";
+ serverStatus["EXTERNAL_ADDRESS"] = "Using Address ADDRESS";
+
+ serverStatus["REACHABILITY_SUCCEEDED"] = "Reachable By Tor Network";
+ serverStatus["REACHABILITY_FAILED"] = "<font color='#990000'>Reachability Tests Failed. Trying again..</font>";
+ serverStatus["BAD_SERVER_DESCRIPTOR"] = "<font color='#990000'>Server Not Accepted By Tor Network Yet.</font>";
+ serverStatus["GOOD_SERVER_DESCRIPTOR"] = "Accepted By Tor Network";
+
+ serverStatusIcon["REACHABILITY_SUCCEEDED"] = "tork_green";
+ serverStatusIcon["REACHABILITY_FAILED"] = "tork_orange";
+ serverStatusIcon["BAD_SERVER_DESCRIPTOR"] = "tork_little";
+ serverStatusIcon["GOOD_SERVER_DESCRIPTOR"] = "tork_green";
+ serverStatusIcon["DIR_ALL_UNREACHABLE"] = "tork_red";
+
+ clientStatus["NOT_ENOUGH_DIR_INFO"] = "<font color='#990000'>Not Enough Info To Try Network Yet</font>";
+ clientStatus["ENOUGH_DIR_INFO"] = "Enough Info To Try Network";
+ clientStatus["CIRCUIT_ESTABLISHED"] = "Connected to Network.";
+ clientStatus["CIRCUIT_NOT_ESTABLISHED"] = "<font color='#990000'>Still Trying Network</font>";
+
+ clientStatusIcon[clientStatus["NOT_ENOUGH_DIR_INFO"]] = "tork_red";
+ clientStatusIcon[clientStatus["ENOUGH_DIR_INFO"]] = "tork_little";
+ clientStatusIcon[clientStatus["CIRCUIT_ESTABLISHED"]] = "tork_green";
+ clientStatusIcon[clientStatus["CIRCUIT_NOT_ESTABLISHED"]] = "tork_orange";
+
+ portMessage["23"] = " Port 23 is used by telnet, which transmits usernames "
+ "and passwords unencrypted.";
+ portMessage["110"] = " Port 110 is used to download email, so your login "
+ "details can be transmitted unencrypted.";
+ portMessage["109"] = " Port 109 is used to download email, so your login "
+ "details can be transmitted unencrypted.";
+ portMessage["143"] = " Port 143 is used to download email, so your login "
+ "details can be transmitted unencrypted.";
+
+
+ statusMessage["DANGEROUS_PORT"] = "QUESTIONMESSAGETraffic on Port PORT "
+ "has been rejected by Tor.";
+ statusMessage["DANGEROUS_VERSION"] = "QUESTIONMESSAGEYou are using Tor CURRENT."
+ " This version is REASON. "
+ "You should use Tor RECOMMENDED instead";
+ statusMessage["TOO_MANY_CONNECTIONS"] = "MESSAGETor has reached its native"
+ " limit on file descriptors: CURRENT. ";
+ statusMessage["BUG"] = "WARNINGMESSAGETor encountered an unexpected error: REASON. ";
+ statusMessage["CLOCK_SKEW"] = "WARNINGMESSAGEYour local clock is skewed by SKEW seconds. ";
+ statusMessage["BAD_LIBEVENT"] = "WARNINGMESSAGEYour version of libevent, VERSION, is BADNESS. ";
+ statusMessage["DIR_ALL_UNREACHABLE"] = "WARNINGMESSAGEAll known directory servers are unreachable. ";
+ statusMessage["ENOUGH_DIR_INFO"] = "WARNINGMESSAGETor has gathered enough info to start working. ";
+ statusMessage["NOT_ENOUGH_DIR_INFO"] = "WARNINGMESSAGETor does not have enough info to work. ";
+ statusMessage["CIRCUIT_ESTABLISHED"] = "WARNINGMESSAGETor has gathered enough info to start working. ";
+ statusMessage["CIRCUIT_NOT_ESTABLISHED"] = "WARNINGMESSAGETor does not have enough info to work. ";
+ statusMessage["SOCKS_BAD_HOSTNAME"] = "WARNINGMESSAGESome application gave us"
+ " a funny-looking hostname."
+ "Perhaps it is broken?";
+ statusMessage["NAMESERVER_ALL_DOWN"] = "WARNINGMESSAGEAll your configured nameservers appear to be down.";
+ statusMessage["DNS_HIJACKED"] = "WARNINGMESSAGEYour DNS requests are being hijacked by your provider.";
+ statusMessage["DNS_USELESS"] = "WARNINGMESSAGEYour DNS requests are being hijacked by your provider.";
+ statusMessage["BAD_SERVER_DESCRIPTOR"] = "WARNINGMESSAGEYour descriptor was rejected by DIRAUTH "
+ "because of REASON.";
+
+ m_statustip = i18n("<b>Name:</b> $SERVERNAME<br>"
+ "<b>IP:</b> $IP ($HOSTNAME) <b>Port:</b> $PORT<br>"
+ "<b>Country:</b> $COUNTRY <br>"
+ "<b>Version:</b> $VERSION <b>OS:</b> $OS<br>"
+ "<b>Published:</b> $PUBLISHED <b>Up Time:</b> $UPTIME minutes<br>"
+ "<center><b>Avg BW up to $INTERVALTIME</b></center>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"
+ "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>24 hrs</b>"
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;<b>12 hrs</b>"
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;<b>6 hrs</b>"
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;<b>1 hr</b><br>"
+ "<b>Up</b>"
+ "&nbsp;&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;&nbsp;" // 1 space
+ "<font color='#990000'>$BWUP</font><br>"
+ "<b>Down</b>"
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "&nbsp;&nbsp;&nbsp;" // 1 space
+ "<font color='#1c9a1c'>$BWDN</font><br>"
+ );
+
+}
+
+void TorClient::configureServer( int orPort, int dirPort)
+{
+
+ sendToServer(QString("SETCONF ContactInfo=%1").arg(TorkConfig::contactInfo())) ;
+
+ sendToServer(QString("SETCONF ClientOnly=%1").arg(TorkConfig::clientOnly())) ;
+
+
+ if (TorkConfig::middleMan())
+ ( sendToServer(QString("SETCONF ExitPolicy=%1").arg(("\"reject *:*\"")))) ;
+ else
+ ( sendToServer(QString("SETCONF ExitPolicy=\"%2\"").arg( TorkConfig::exitPolicy().join(","))));
+
+ sendToServer(QString("SETCONF NickName=%1").arg(TorkConfig::nickName())) ;
+ if (!TorkConfig::clientOnly()){
+ //We send the orport configs together to avoid error messages from Tor
+ //telling us that one cannot be set without the other.
+ sendToServer(QString("SETCONF ORPort=%1 "
+ "ORListenAddress=0.0.0.0:%2")
+ .arg(orPort)
+ .arg(TorkConfig::oRListenAddress())) ;
+ //We send the dirport configs together to avoid error messages from Tor
+ //telling us that one cannot be set without the other.
+ sendToServer(QString("SETCONF DIRPort=%1 "
+ "DIRListenAddress=0.0.0.0:%2")
+ .arg(dirPort)
+ .arg(TorkConfig::dirListenAddress())) ;
+ sendToServer(QString("SETCONF BridgeRelay=%1").arg(TorkConfig::bridgeRelay())) ;
+ setBandwidth(QString("%1").arg(TorkConfig::bandwidthRate()),
+ QString("%1").arg(TorkConfig::bandwidthBurst()),
+ QString("%1").arg(TorkConfig::maxAdvertisedBandwidth()));
+ }else{
+ sendToServer(QString("SETCONF ORPort= ORListenAddress=")) ;
+ sendToServer(QString("SETCONF DirPort= DirListenAddress=")) ;
+ sendToServer(QString("SETCONF BridgeRelay=")) ;
+ }
+
+ if (TorkConfig::clientOnly())
+ resetClientReport();
+ TorkConfig::writeConfig();
+}
+void TorClient::clearNodes( )
+{
+
+ sendToServer("SETCONF ExcludeNodes=");
+ sendToServer("SETCONF ExitNodes=");
+ sendToServer("SETCONF EntryNodes=");
+ TorkConfig::setCurrentExcludeNodes("");
+ TorkConfig::setCurrentEntryNodes("");
+ TorkConfig::setCurrentExitNodes("");
+ emit copyOldConfig();
+}
+
+void TorClient::updateExcludeNodes( )
+{
+ ////kdDebug() << "SETCONF ExcludeNodes=" + TorkConfig::currentExcludeNodes().join(",") << endl;
+ sendToServer("SETCONF ExcludeNodes=" + TorkConfig::currentExcludeNodes().join(","));
+ sendToServer("GETCONF ExcludeNodes");
+ sendToServer("signal newnym");
+
+}
+
+void TorClient::updateExitNodes( )
+{
+ ////kdDebug() << "SETCONF ExitNodes=" + TorkConfig::currentExitNodes().join(",") << endl;
+ sendToServer("SETCONF ExitNodes=" + TorkConfig::currentExitNodes().join(","));
+ sendToServer("GETCONF ExitNodes");
+ sendToServer("signal newnym");
+
+}
+
+void TorClient::strictExitNodes( bool strict )
+{
+ if (strict)
+ sendToServer("SETCONF StrictExitNodes=1");
+ else
+ sendToServer("SETCONF StrictExitNodes=0");
+
+}
+
+void TorClient::safeLogging( bool safe )
+{
+ if (safe)
+ sendToServer("SETCONF SafeLogging=1");
+ else
+ sendToServer("SETCONF SafeLogging=0");
+
+}
+
+void TorClient::updateEntryNodes( )
+{
+ ////kdDebug() << "SETCONF EntryNodes=" + TorkConfig::currentEntryNodes().join(",") << endl;
+ sendToServer("SETCONF EntryNodes=" + TorkConfig::currentEntryNodes().join(","));
+ sendToServer("GETCONF EntryNodes");
+ sendToServer("signal newnym");
+
+}
+
+void TorClient::enableDNS( bool set )
+{
+ if (set)
+ sendToServer("SETCONF DNSPort=9999");
+ else
+ sendToServer("SETCONF DNSPort=");
+
+}
+
+void TorClient::enableTransPort( bool set )
+{
+ if (set)
+ sendToServer("SETCONF TransPort=9040");
+ else
+ sendToServer("SETCONF TransPort=");
+
+}
+
+void TorClient::fetchServerInfo( const QString & server)
+{
+
+ QString fp = getFPFromFPDigest(server);
+ fp.replace("$","");
+
+ kdDebug() << fp << endl;
+// emit showServerBW(fp);
+
+ sendToServer("GETINFO dir/server/fp/" + fp);
+}
+
+void TorClient::fetchServerInfoByNick( const QString & server)
+{
+
+
+ QString fp = getFPFromNickName(server);
+ fp.replace("$","");
+
+ sendToServer("GETINFO dir/server/fp/" + fp);
+}
+
+void TorClient::slotCheckTorNet()
+{
+ sendToServer("GETINFO ns/all");
+}
+
+void TorClient::slotCheckGuards()
+{
+
+ sendToServer("GETINFO entry-guards");
+
+}
+
+void TorClient::terminateTor()
+{
+
+ sendToServer("SIGNAL SHUTDOWN");
+
+}
+
+void TorClient::createService(const QString &dir, const QString &port)
+{
+ sendToServer(QString("setconf hiddenservicedir=\"%1\" hiddenserviceport=\"%2\"").arg(dir).arg(port));
+}
+
+void TorClient::authenticate()
+{
+
+// if (TorkConfig::defaultRunningNormalOptions()){
+// sendToServer("AUTHENTICATE");
+// return;
+// }
+
+ if (TorkConfig::cookieAuthentication()){
+ if (!readCookie()){
+ emit processQuestion("cookienotfound",
+ QString("Couldn't find authentication"
+ " cookie in %1/.tor!").arg(getenv("HOME")));
+ emit fatalError();
+ }
+ }else if (!TorkConfig::hashedControlPassword().isEmpty())
+ sendToServer(QString("AUTHENTICATE \"%1\"").arg(TorkConfig::hashedControlPassword()));
+ else{
+ sendToServer("AUTHENTICATE");
+ /* Lock the control port */
+ if (TorkConfig::generateRandomPassword()){
+ crypto_seed_rng();
+ sendToServer(QString("setconf HashedControlPassword=16:%2")
+ .arg(hashPassword(crypto_rand_string(16))));
+ }
+ }
+
+}
+
+
+bool TorClient::readCookie()
+{
+
+ QString hex;
+ char hx[2];
+
+ QStringList cookieCandidates;
+ cookieCandidates << QString("%1/.tor/control_auth_cookie").arg(getenv("HOME"));
+ cookieCandidates << QString("/var/lib/tor/control_auth_cookie");
+
+ for ( QStringList::Iterator it = cookieCandidates.begin(); it != cookieCandidates.end(); ++it ) {
+ QFile inf((*it));
+ if ( inf.open(IO_ReadOnly) ) {
+ QByteArray array = inf.readAll();
+ inf.close();
+ if (array.size() != 32)
+ continue;
+ for ( unsigned int i = 0; i < array.size(); i++ ) {
+ sprintf(hx,"%02x",array[i]);
+ hex += QString(hx).right(2);
+ }
+ sendToServer(QString("AUTHENTICATE %1").arg(hex));
+ return true;
+
+ }
+ }
+
+ return false;
+
+}
+
+void TorClient::readRouters()
+{
+
+ QFile inf(QString("%1/.tor/cached-status/7EA6EAD6FD83083C538F44038BBFA077587DD755").arg(getenv("HOME")));
+ if ( inf.open(IO_ReadOnly) ) {
+ QTextStream stream( &inf );
+ QString line;
+ while ( !stream.atEnd() ) {
+ line = stream.readLine(); // line of text excluding '\n'
+ parseDirStatus(line);
+ }
+ inf.close();
+ }
+
+
+}
+
+void TorClient::newIdentity()
+{
+ kdDebug() << "changing id" << endl;
+ sendToServer("signal newnym");
+
+}
+
+void TorClient::bandwidth()
+{
+
+ sendToServer("usefeature verbose_names");
+ sendToServer("usefeature extended_events");
+ sendToServer("GETINFO ns/all");
+ sendToServer("GETINFO circuit-status");
+ sendToServer("GETINFO stream-status");
+ sendToServer("GETINFO orconn-status");
+ sendToServer("GETINFO version");
+ sendToServer("GETINFO status/enough-dir-info");
+ sendToServer("GETINFO status/good-server-descriptor");
+ sendToServer("GETINFO status/reachability-succeeded/or");
+
+ //Always enable for each session, user can disable through yes/no
+ //interface when warned - but only for that session.
+ m_portsToReject.clear();
+ m_portsToReject << "23" << "109" << "110" << "143";
+ sendToServer(QString("SETCONF WarnPlainTextPorts=%1")
+ .arg(m_portsToReject.join(",")));
+ sendToServer(QString("SETCONF RejectPlainTextPorts=%1")
+ .arg(m_portsToReject.join(",")));
+ sendToServer("SETEVENTS EXTENDED CIRC STREAM ORCONN NOTICE "
+ "WARN ERR ADDRMAP BW STREAM_BW NS STATUS_GENERAL "
+ "STATUS_CLIENT STATUS_SERVER GUARD");
+ sendToServer(QString("SETCONF __ReloadTorrcOnSIGHUP=0"));
+
+
+}
+
+void TorClient::handle250(const QString &lin)
+{
+
+
+ QString line = lin;
+
+ if ((line.contains("250-circuit-status="))){
+ if (line != ".")
+ parseEvent("CIRC",line.replace("250-circuit-status=",""));
+ else
+ m_expectingCircuitInfo = false;
+ }else if ((line.contains("250-orconn-status="))){
+ if (line != ".")
+ parseEvent("ORCONN",line.replace("250-orconn-status=",""));
+ else
+ m_expectingOrconnInfo = false;
+ }else if ((line.contains("250-stream-status="))){
+ if (line != ".")
+ parseEvent("STREAM",line.replace("250-stream-status=",""));
+ else
+ m_expectingStreamInfo = false;
+ }else if (line.contains("250+circuit-status="))
+ m_expectingCircuitInfo= true;
+ else if (line.contains("250+orconn-status="))
+ m_expectingOrconnInfo= true;
+ else if (line.contains("250+stream-status="))
+ m_expectingStreamInfo= true;
+ else if (line.contains("250+entry-guards="))
+ m_expectingGuardsInfo= true;
+ else if (line.contains("250+dir/server/fp/"))
+ m_expectingServerInfo= true;
+ else if (line.contains("250+extra-info/digest/"))
+ m_expectingServerInfo= true;
+ else if (line.contains("250+ns/all=")){
+ m_expectingDirStatus= true;
+ emit whatImDoing("Inspecting the Tor network..");
+ }else if (line.contains("250-ns/all=")){
+ emit warnNoServerInfo();
+ emit shouldIApplySettings();
+ }else if (line.contains("250-version="))
+ handleTorVersion(line.section("=",1,1));
+ else if (line.contains("250 BandwidthRate="))
+ m_CurBandwidthRate = line.section("=",1,1).toInt();
+ else if (line.contains("250 BandwidthBurst="))
+ m_CurBandwidthBurst = line.section("=",1,1).toInt();
+ else if (line.contains("250 MaxAdvertisedBandwidth="))
+ m_CurMaxAdvertisedBandwidth = line.section("=",1,1).toInt();
+ else if (line.contains("250 ExcludeNodes="))
+ TorkConfig::setCurrentExcludeNodes(QStringList::split(",",line.replace("250 ExcludeNodes=","")));
+ else if (line.contains("250 EntryNodes="))
+ TorkConfig::setCurrentEntryNodes(QStringList::split(",",line.replace("250 EntryNodes=","")));
+ else if (line.contains("250 ExitNodes="))
+ TorkConfig::setCurrentExitNodes(QStringList::split(",",line.replace("250 ExitNodes=","")));
+ else if (line.contains("250-status/circuit-established=1"))
+ updateClientReport("CIRCUIT_ESTABLISHED");
+ else if (line.contains("250-status/circuit-established=0"))
+ updateClientReport("CIRCUIT_NOT_ESTABLISHED");
+ else if (line.contains("250-status/enough-dir-info=1")){
+ updateClientReport("ENOUGH_DIR_INFO");
+ sendToServer("GETINFO status/circuit-established");
+ }else if (line.contains("250-status/enough-dir-info=0"))
+ updateClientReport("NOT_ENOUGH_DIR_INFO");
+ else if (line.contains("250-status/good-server-descriptor=1"))
+ updateServerReport("GOOD_SERVER_DESCRIPTOR", QString());
+ else if (line.contains("250-status/good-server-descriptor=0"))
+ updateServerReport("BAD_SERVER_DESCRIPTOR", QString());
+ else if (line.contains("250-status/reachability-succeeded/or=1"))
+ updateServerReport("REACHABILITY_SUCCEEDED", QString());
+ else if (line.contains("250-status/reachability-succeeded/or=0"))
+ updateServerReport("REACHABILITY_FAILED", QString());
+
+}
+
+void TorClient::socketReadyRead()
+{
+ QString line;
+ // read from the server
+ while ( socket->canReadLine() ) {
+
+ line = (socket->readLine()).stripWhiteSpace();
+
+ if (line.contains("250 OK")){
+ if (!m_controllerWorking){
+ bandwidth();
+ emit authenticated();
+ m_controllerWorking = true;
+ }
+ continue;
+ }
+
+ if (m_expectingDirStatus){
+ if (!(line == ".")){
+ parseDirStatus(line);
+ }else{
+ m_expectingDirStatus = false;
+ sendToServer("GETINFO entry-guards");
+ if (!m_firstloadcomplete)
+ emit shouldIApplySettings();
+ m_firstloadcomplete = true;
+ }
+ continue;
+ }else if ((m_expectingCircuitInfo)){
+ if (line != "."){
+ parseEvent("CIRC",line);
+ }else
+ m_expectingCircuitInfo = false;
+ continue;
+ }else if ((m_expectingOrconnInfo)){
+ if (line != "."){
+ parseEvent("ORCONN",line);
+ }else
+ m_expectingOrconnInfo = false;
+ continue;
+ }else if ((m_expectingStreamInfo)){
+ if (line != "."){
+ parseEvent("STREAM",line);
+ }else
+ m_expectingStreamInfo = false;
+ continue;
+ }else if (m_expectingServerInfo){
+ if (line != "."){
+ parseEvent("SERVER",line);
+ }else
+ m_expectingServerInfo = false;
+ continue;
+ }else if (m_expectingGuardsInfo){
+ if (line != "."){
+ parseEvent("GUARDS",line);
+ emit whatImDoing(i18n("Ready for use."));
+ }else{
+ m_expectingGuardsInfo = false;
+ }
+ continue;
+ }
+
+ if (line.contains("552 Unrecognized key \"ns/all\"")){
+ emit needAlphaVersion();
+ emit shouldIApplySettings();
+ continue;
+ }
+
+ QString code = line.left(3);
+
+ if (code == "250")
+ handle250(line);
+ else if (code == "650"){
+ if (line.contains("650+NS")){
+ m_expectingDirStatus= true;
+ continue;
+ }
+ QString eventType = line.section(" ",1,1);
+ QString eventInfo = line.section(" ",2);
+ if (eventInfo.contains("circuit_testing_failed"))
+ emit serverError();
+ parseEvent(eventType,eventInfo);
+ }else if (code == "552"){
+ QString eventInfo = line.section(" ",1);
+ emit displayError("Sorry!", eventInfo);
+ }else if (code == "514"){
+ QString eventInfo = line.section(" ",1);
+ emit processWarning("authenticationrequired", eventInfo);
+ emit fatalError();
+ }else if (code == "515"){
+ QString eventInfo = line.section(" ",1);
+ if (eventInfo.contains("Wrong length"))
+ emit processQuestion("cookierequired", eventInfo);
+ else{
+ if (TorkConfig::generateRandomPassword())
+ emit processQuestion("passwordlost", eventInfo);
+ else
+ emit processWarning("authenticationfailed", eventInfo);
+ }
+ //Only used by the first-run wizard
+ emit authenticationFailed();
+ }
+
+
+ }
+}
+
+void TorClient::parseEvent(const QString &type, const QString &info)
+{
+
+ if (info.isEmpty())
+ return;
+
+ if (type == "STREAM")
+ parseStream(info);
+ else if (type == "ORCONN")
+ parseORConn(info);
+ else if (type == "CIRC")
+ parseCircuit(info);
+ else if (type == "GUARDS")
+ parseGuards(info);
+ else if (type == "GUARD")
+ parseGuards(info.section(" ",1));
+ else if (type == "SERVER")
+ parseServer(info);
+ else if (type == "DIRSTATUS")
+ parseDirStatus(info);
+ else if (type == "BW")
+ parseBW(info);
+ else if (type == "STREAM_BW")
+ parseStreamBW(info);
+ else if (type.contains( "STATUS_"))
+ parseStatusGeneral(info);
+ else if (type == "ADDRMAP")
+ parseAddrmap(info);
+/* else if (type == "STREAM_PORT")
+ parseStreamPort(info);*/
+ else if ((type == "WARN") || (type == "NOTICE") || (type == "ERR"))
+ parseInfo(type,info);
+}
+
+void TorClient::parseStatusGeneral(const QString &info)
+{
+ QString severity = info.section(" ",0,0);
+ QString action = info.section(" ",1,1);
+ QString message = statusMessage[action];
+
+ if (!serverStatus[action].isEmpty())
+ updateServerReport(action, info);
+
+ if (!clientStatus[action].isEmpty())
+ updateClientReport(action);
+
+/* kdDebug() << info << endl;
+ kdDebug() << info.section(" ",2) << endl;*/
+ populateMessageFromStatusDetail(info.section(" ",2), message);
+
+ if (message.left(14) == "WARNINGMESSAGE"){
+ message.replace("WARNINGMESSAGE","");
+ emit processWarning(action, message);
+ }else{
+ message.replace("QUESTIONMESSAGE","");
+ emit processQuestion(action, message);
+ }
+
+}
+
+void TorClient::populateMessageFromStatusDetail(const QString &line, QString &message)
+{
+ QRegExp rx("[\\sA-Z0-9]+[=]([\\-\\:\\.\\(\\)a-zA-Z0-9]+|\\\"[\\-\\.\\,a-zA-Z0-9\\s]+\\\")");
+ int pos = 0;
+ while ( (pos = rx.search(line, pos)) != -1 ) {
+/* kdDebug() << rx.cap(0) << endl;*/
+ QString keyword = rx.cap(0).section("=",0,0).stripWhiteSpace();
+ QString value = rx.cap(0).section("=",1,1).stripWhiteSpace();
+ message.replace(keyword,value);
+ pos += rx.matchedLength();
+ if (keyword=="PORT"){
+ m_WarnedPorts << value;
+ message.append(portMessage[value]);
+ }
+ }
+}
+
+void TorClient::updateServerReport(const QString &message, const QString &info)
+{
+// kdDebug() << serverStatusIcon[message] << endl;
+// kdDebug() << message << endl;
+
+ //If we're back to being a client, ensure the server symbol is removed from the tray icon
+ if (TorkConfig::clientOnly()){
+ emit updateTrayIcon(serverStatusIcon[message].replace("server",""));
+ return;
+ }
+ if (!serverStatusIcon[message].isEmpty())
+ emit updateTrayIcon(serverStatusIcon[message]);
+
+ serverReport.remove("<font color='#990000'>Status Not Known</font>");
+ QString msg = serverStatus[message];
+
+ if (message.contains("EXTERNAL_ADDRESS")){
+ for ( QStringList::Iterator it = serverReport.begin(); it != serverReport.end(); ++it )
+ {
+ // XXX Fixme
+ if ((*it).contains("Using Address")){
+ serverReport.remove((*it));
+ break;
+ }
+ }
+ populateMessageFromStatusDetail(info.section(" ",2),msg);
+ }else if (message.contains("REACHABILITY")){
+ serverReport.remove(serverStatus["REACHABILITY_FAILED"]);
+ serverReport.remove(serverStatus["REACHABILITY_SUCCEEDED"]);
+ }else if (message.contains("SERVER_DESCRIPTOR")){
+ serverReport.remove(serverStatus["DIR_ALL_UNREACHABLE"]);
+ serverReport.remove(serverStatus["BAD_SERVER_DESCRIPTOR"]);
+ serverReport.remove(serverStatus["GOOD_SERVER_DESCRIPTOR"]);
+ }else // Prevent multiple reports
+ serverReport.remove(msg);
+
+ serverReport.append(msg);
+}
+
+void TorClient::updateClientReport(const QString &message)
+{
+ if (!clientStatusIcon[message].isEmpty() && (TorkConfig::clientOnly()))
+ emit updateTrayIcon(clientStatusIcon[clientStatus[message]]);
+ clientReport.clear();
+ clientReport.append(clientStatus[message]);
+}
+
+void TorClient::resetClientReport()
+{
+ emit updateTrayIcon(clientStatusIcon[clientReport.first()]);
+}
+
+void TorClient::parseBW(const QString &info)
+{
+
+ QString in = info.section(" ",0,0);
+ QString out = info.section(" ",1,1);
+
+ emit bwUpdate(in, out);
+
+}
+
+
+void TorClient::parseStreamBW(const QString &info)
+{
+
+ QString stream = info.section(" ",0,0);
+ /* Tor spec had it wrong way round! */
+ QString out = info.section(" ",1,1);
+ QString in = info.section(" ",2,2);
+
+ emit streamBwUpdate(stream, in, out);
+
+}
+
+
+void TorClient::parseStream(const QString &info)
+{
+
+
+ QString streamID = info.section(" ",0,0);
+ QString status = info.section(" ",1,1);
+ QString circID = info.section(" ",2,2);
+ QString Target = info.section(" ",3,3);
+
+ //We ignore REMAPs because we don't do anything with them
+ if (status == "REMAP")
+ return;
+
+ emit streamStatusUpdate(streamID, status, circID, Target, info);
+
+}
+
+void TorClient::parseServer(const QString &info)
+{
+
+ kdDebug() << "server info " << info << endl;
+ if (info.left(7) == "router "){
+ QString ip = info.section(" ",2,2);
+ QString cc;
+
+ GeoIP * gi = 0;
+
+ if (geoip_db)
+#ifndef EXTERNAL_GEOIP
+ gi = GeoIP_open(locate("data", "tork/geoip/GeoIP.dat").ascii(),0);
+#else
+ gi = GeoIP_new(GEOIP_STANDARD);
+#endif
+
+ if (gi){
+ int country_id = 0;
+ country_id = GeoIP_id_by_name(gi, ip);
+ cc = GeoIP_country_name[country_id];
+ GeoIP_delete(gi);
+ }else
+ cc = "a1";
+
+ m_statustiptmp = m_statustip;
+ m_statustipIP = ip;
+
+ m_statustiptmp.replace("$SERVERNAME",info.section(" ",1,1));
+ m_statustiptmp.replace("$IP",ip);
+ m_statustiptmp.replace("$PORT",info.section(" ",3,3));
+ m_statustiptmp.replace("$COUNTRY",cc);
+
+ }else if (info.left(8) == "platform"){
+ m_statustiptmp.replace("$VERSION",info.section(" ",1,2));
+ m_statustiptmp.replace("$OS",info.section(" ",4).section("{",0,0));
+
+ }else if (info.left(9) == "published"){
+ m_statustiptmp.replace("$PUBLISHED",info.section(" ",1));
+
+ }else if (info.left(6) == "uptime"){
+ //from the clever ktorrent
+ KLocale* loc = KGlobal::locale();
+ QTime t;
+ int nsecs = info.section(" ",1).toInt();
+ int ndays = (nsecs) / 86400;
+ t = t.addSecs(nsecs % 86400);
+ QString s = loc->formatTime(t,true,true);
+ if (ndays > 0)
+ s = i18n("1 day ","%n days ",ndays) + s;
+
+ m_statustiptmp.replace("$UPTIME",s);
+
+
+ }else if (info.left(20).contains("write-history")){
+ QStringList bwlist = QStringList::split(",",info.section(" ",-1));
+
+ QValueList<int> bws;
+ bws << 4 << 24 << 48 << bwlist.count();
+
+ QString bwup;
+ QString avgbw;
+ for ( QValueList<int>::Iterator it = bws.begin(); it != bws.end(); ++it ){
+ avgbw = calcBW(bwlist, (*it));
+ for (int i = avgbw.length(); i < 14; i++)
+ avgbw.append("&nbsp;&nbsp;");
+ bwup.append(avgbw);
+ }
+
+ m_statustiptmp.replace("$BWUP",bwup);
+
+ m_statustiptmp.replace("$INTERVALTIME", info.section(" ",2,3));
+
+ }else if (info.left(20).contains("read-history")){
+ QStringList bwlist = QStringList::split(",",info.section(" ",-1));
+ QValueList<int> bws;
+ bws << 4 << 24 << 48 << bwlist.count();
+
+ QString bwup;
+ QString avgbw;
+ for ( QValueList<int>::Iterator it = bws.begin(); it != bws.end(); ++it ){
+ avgbw = calcBW(bwlist, (*it));
+ for (int i = avgbw.length(); i < 14; i++)
+ avgbw.append("&nbsp;&nbsp;");
+ bwup.append(avgbw);
+ }
+ m_statustiptmp.replace("$BWDN",bwup);
+
+
+ if (m_currentTorVersion.left(3) == "0.2"){
+ m_resolvingServerAddress=true;
+ sendToServer("RESOLVE mode=reverse " + m_statustipIP);
+ }else{
+ m_statustiptmp.replace("($HOSTNAME)","");
+ emit displayServer("Server Info", m_statustiptmp);
+ }
+ }else if (info.left(25).contains("opt extra-info-digest")){
+ if (m_currentTorVersion.left(3) == "0.2"){
+ sendToServer("GETINFO extra-info/digest/" + info.section(" ",2));
+ }else{
+ m_statustiptmp.replace("($HOSTNAME)","");
+ m_statustiptmp.replace("$BWDN","Unavailable");
+ m_statustiptmp.replace("$BWUP","Unavailable");
+ m_statustiptmp.replace("$INTERVALTIME", "Unavailable");
+ emit displayServer("Server Info", m_statustiptmp);
+ }
+
+ }
+}
+
+void TorClient::parseAddrmap(const QString &info)
+{
+
+
+ QString type = info.section(" ",0,0);
+ QString address = info.section(" ",1,1);
+
+ // If this is a request to resolve a hostname/address from the traffic
+ // logs
+ if (logResolveList.contains(type)){
+ emit resolvedAddress(info);
+ logResolveList.remove(logResolveList.find(type));
+ return;
+ }
+
+ if (!m_resolvingServerAddress)
+ return;
+
+ // If this is a request to resolve a node name from the server list
+ if (type.startsWith("REVERSE")){
+ m_statustiptmp.replace("$HOSTNAME",address);
+ }else
+ m_statustiptmp.replace("$HOSTNAME","Cannot Resolve Hostname.");
+
+ emit displayServer("Server Info", m_statustiptmp);
+ m_resolvingServerAddress = false;
+
+}
+
+void TorClient::parseGuards(const QString &info)
+{
+
+ QString fp_identity = info.section(" ",0,0);
+ QString status = info.section(" ",1,1);
+ QRegExp rx("(\\$[A-Z0-9]{40})");
+ rx.search(fp_identity);
+ QString server = getNickNameFromFP(rx.cap(0));
+
+ if (!server.isEmpty()){
+ emit guardStatusUpdate(server, status);
+ }
+}
+
+void TorClient::parseCircuit(const QString &info)
+{
+
+ if (info.contains("FAILED"))
+ emit displayError("Circuit Failed - "+info.section(" ",3,3).replace("REASON=",""), "Circuit: " + info.section(" ",2,2));
+
+ QString circuitID = info.section(" ",0,0).stripWhiteSpace();
+ QString status = info.section(" ",1,1).stripWhiteSpace();
+ QString path = info.section(" ",2,2).stripWhiteSpace();
+
+ //Get the FP Digest (if any) of the last server in the circuit
+ QString exit;
+ QRegExp rx("(\\$[A-Z0-9]{40})");
+ int count = 0;
+ int pos = 0;
+ while ( (pos = rx.search(path, pos)) != -1 ) {
+ count++;
+ pos += rx.matchedLength();
+ exit = rx.cap(0);
+ }
+ if (!exit.isEmpty())
+ exit = getFPDigestFromFP(exit);
+ //Strip out the FPs from the circuit, if any
+ path.replace(QRegExp("(\\$[A-Z0-9]{40})(~|=)"),"");
+
+ emit circuitStatusUpdate(circuitID, status, path, exit);
+
+}
+
+void TorClient::parseORConn(const QString &info)
+{
+ QString serverID = info.section(" ",0,0);
+ QString status = info.section(" ",1,1);
+
+ if (serverID.startsWith("$")){
+ QString server = getNickNameFromFP(serverID);
+ if (!server.isEmpty())
+ serverID = server;
+ }
+
+ if (!status.contains("NEW")){
+ serverID.replace(QRegExp("^[A-Z0-9$=~]{42}"),"");
+ emit ORStatusUpdate(serverID, status);
+ }
+}
+
+void TorClient::parseInfo(const QString &type,const QString &info)
+{
+
+ QString message = info;
+ message.replace(QRegExp("^[a-zA-Z0-9_]+\\(\\):"),"");
+// QString summary = info.section(":",0,0);
+// QString data = info.section(":",1);
+
+ if (info.contains("Servers unavailable"))
+ emit displayServer("Server Info", "<b>Server appears to be down!</b>");
+ emit infoUpdate(type, message, QString());
+
+}
+
+void TorClient::updateCandidateServers(const QString &path)
+{
+
+ QStringList servers = QStringList::split(",", path);
+ QStringList existingServers = TorkConfig::serversHistory();
+ for ( QStringList::Iterator it = servers.begin(); it != servers.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ if (existingServers.find(*it) == existingServers.end())
+ existingServers.append(*it);
+ }
+ TorkConfig::setServersHistory(existingServers);
+
+ TorkConfig::writeConfig();
+}
+
+void TorClient::attemptAttach(const QString &circid, const QString &streamid)
+{
+
+ QStringList streams = QStringList::split( " ", streamid);
+ for ( QStringList::Iterator it = streams.begin(); it != streams.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ sendToServer(QString("ATTACHSTREAM %1 %2").arg(*it).arg(circid));
+ }
+
+}
+
+void TorClient::attemptExtendCircuit(const QString &circid, const QString &serverlist, bool usefp)
+{
+
+
+ QStringList servers = QStringList::split( " ", serverlist);
+ QStringList circuitlist;
+ for ( QStringList::Iterator it = servers.begin(); it != servers.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ if (usefp)
+ circuitlist.append(getFPFromFPDigest((*it)));
+ else
+ circuitlist.append((*it));
+ }
+
+ QString circuit = circuitlist.join(",");
+ sendToServer(QString("EXTENDCIRCUIT %1 %2").arg(circid).arg(circuit));
+}
+
+void TorClient::attemptCreateCircuit(const QString &serverlist, bool usefp)
+{
+
+ QStringList servers = QStringList::split( " ", serverlist);
+ QStringList circuitlist;
+ for ( QStringList::Iterator it = servers.begin(); it != servers.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ if (usefp)
+ circuitlist.append(getFPFromFPDigest((*it)));
+ else
+ circuitlist.append((*it));
+ }
+
+ QString circuit = circuitlist.join(",");
+ sendToServer(QString("EXTENDCIRCUIT 0 %1").arg(circuit));
+}
+
+void TorClient::attemptCloseStream(const QString &streamid)
+{
+ sendToServer(QString("CLOSESTREAM %1 1").arg(streamid));
+}
+
+void TorClient::attemptAttachStreams( bool attachStreams)
+{
+ sendToServer(QString("SETCONF __LeaveStreamsUnattached=%1").arg(attachStreams));
+}
+
+void TorClient::attemptCloseCircuit(const QString &circuitid)
+{
+ sendToServer(QString("CLOSECIRCUIT %1").arg(circuitid));
+}
+
+
+void TorClient::updatePrevConfig(PrevConfig::PrevConfigList prevlist)
+{
+
+ m_previtems = prevlist;
+}
+
+
+void TorClient::applySettingsToRunningTor()
+{
+
+ //FIXME: use function pointers and a list to do this
+
+
+ switch (TorkConfig::quickConfigure()) {
+ case 0 : //Tor client and server with default settings
+ return;
+ case 1 : //Tor client with default settings
+ return;
+ case 2 : //Tor server with default settings
+ return;
+ case 3 : //Tor server with default settings
+ return;
+ case 4 : //Tor server with default settings
+ return;
+ default:
+ break;
+ }
+
+// kdDebug() << "1" << endl;
+ KConfigSkeletonItem::List items = TorkConfig::self()->items();
+ KConfigSkeletonItem::List::ConstIterator it;
+
+ for( it = items.begin(); it != items.end(); ++it ) {
+ if (elementShouldBeUsed((*it))){
+ if (noSpecialProcessing((*it))){
+ PrevConfig::PrevConfigList::iterator mit;
+ QVariant oldvalue;
+ for( mit = m_previtems.begin(); mit != m_previtems.end(); ++mit ) {
+ if ((*mit).name() == (*it)->name()){
+ oldvalue = (*mit).property();
+ continue;
+ }
+ }
+
+
+ if ( (*it)->property().type() == QVariant::String ) {
+ if ((oldvalue !=(*it)->property())){
+ ( sendToServer(QString("SETCONF %1=%2").arg((*it)->name()).arg((*it)->property().toString())));
+ }
+ }else if ( (*it)->property().type() == QVariant::StringList ) {
+ if ((oldvalue !=(*it)->property())){
+ ( sendToServer(QString("SETCONF %1=\"%2\"").arg((*it)->name()).arg( (*it)->property().toStringList().join(","))));
+ }
+ }else if ( (*it)->property().type() == QVariant::Int ) {
+ if ((oldvalue !=(*it)->property())){
+ ( sendToServer(QString("SETCONF %1=%2").arg((*it)->name()).arg( (*it)->property().toString())));
+ }
+ }else if ( (*it)->property().type() == QVariant::Bool ) {
+ if ((oldvalue !=(*it)->property())){
+ ( sendToServer(QString("SETCONF %1=%2").arg((*it)->name()).arg( (*it)->property().toInt())));
+ }
+ }
+
+ }
+ }
+ }
+
+ if (TorkConfig::useProxy()){
+ if ((TorkConfig::httpProxyPort() > 0) && (!TorkConfig::httpProxyHost().isEmpty()))
+ ( sendToServer(QString("SETCONF HttpProxy=%1:%2").arg(TorkConfig::httpProxyHost()).arg(TorkConfig::httpProxyPort()))) ;
+ if ((TorkConfig::httpsProxyPort() > 0) && (!TorkConfig::httpsProxyHost().isEmpty()))
+ ( sendToServer(QString("SETCONF HttpsProxy=%1:%2").arg(TorkConfig::httpsProxyHost()).arg(TorkConfig::httpsProxyPort()))) ;
+
+ if ((!TorkConfig::httpProxyAuthenticatorUserName().isEmpty()) && (!TorkConfig::httpProxyAuthenticatorPassword().isEmpty()))
+ ( sendToServer(QString("SETCONF HttpProxyAuthenticator=%1:%2").arg(TorkConfig::httpProxyAuthenticatorUserName()).arg(TorkConfig::httpProxyAuthenticatorPassword())));
+
+ if ((!TorkConfig::httpsProxyAuthenticatorUserName().isEmpty()) && (!TorkConfig::httpsProxyAuthenticatorPassword().isEmpty()))
+ ( sendToServer(QString("SETCONF HttpsProxyAuthenticator=%1:%2").arg(TorkConfig::httpsProxyAuthenticatorUserName() ).arg(TorkConfig::httpsProxyAuthenticatorPassword())));
+ }else{
+ ( sendToServer(QString("SETCONF HttpProxy=")));
+ ( sendToServer(QString("SETCONF HttpsProxy=")));
+ ( sendToServer(QString("SETCONF HttpProxyAuthenticator=")));
+ ( sendToServer(QString("SETCONF HttpsProxyAuthenticator=")));
+ }
+
+ if ((!TorkConfig::sOCKSBindAddressHost().isEmpty()) && (TorkConfig::sOCKSBindAddressPort() > -1))
+ ( sendToServer(QString("SETCONF SOCKSListenAddress=%1:%2").arg(TorkConfig::sOCKSBindAddressHost()).arg( TorkConfig::sOCKSBindAddressPort()))) ;
+
+ if ((TorkConfig::sOCKSBindAddressHost().isEmpty()) && (TorkConfig::sOCKSBindAddressPort() > -1))
+ ( sendToServer(QString("SETCONF SOCKSPort=%2").arg(TorkConfig::sOCKSBindAddressPort()))) ;
+
+ emit copyOldConfig();
+ emit makeTorkStoppable();
+ sendToServer(QString("GETCONF ExcludeNodes")) ;
+ sendToServer(QString("GETCONF ExitNodes")) ;
+ sendToServer(QString("GETCONF EntryNodes")) ;
+
+}
+
+bool TorClient::elementShouldBeUsed(const KConfigSkeletonItem* it)
+{
+
+ //Maxmin Settings are always applied, defaults if 'let Tor decide' selected.
+ if (((*it).group() == "MaxMin") ||
+ ((!(TorkConfig::clientOnly())) && ((*it).group() == "DefaultServerAddress")) ||
+ ((*it).group() == "FirewallEvasion") ||
+ ((*it).group() == "Censorship") ||
+ (((*it).group() == "RunningSpecial")) ||
+ (((*it).group() == "Servers")) ||
+ // Server settings are applied by calling configureServer() later
+ //(((*it).group() == "MyServer")) ||
+ (((*it).group() == "Usability")) ||
+ (((*it).group() == "UsingTor")) ||
+ (((*it).group() == "MyHiddenServices")) ||
+ //Serverperformance Settings are always applied, defaults if 'let Tor decide' selected.
+ (((*it).group() == "ServerPerformance")))
+ return true;
+
+
+ //Excluded:
+ //((*it).group() == "RunningNormal")) - Because they aren't appropriate for a running Tor
+
+ return false;
+}
+
+bool TorClient::noSpecialProcessing(const KConfigSkeletonItem* it)
+{
+
+ if (((*it).name() == "PublishServerDescriptor") && (TorkConfig::bridgeRelay())){
+ sendToServer(QString("setconf PublishServerDescriptor=bridge"));
+ return false;
+ }
+
+ if ((*it).name() == "HashedControlPassword"){
+ if ((*it).property().toString().isEmpty() &&
+ (!TorkConfig::cookieAuthentication()) &&
+ TorkConfig::generateRandomPassword()){
+ crypto_seed_rng();
+ sendToServer(QString("setconf %1=16:%2")
+ .arg((*it).name())
+ .arg(hashPassword(crypto_rand_string(16))));
+ return false;
+ }
+ return true;
+ }
+
+ if ((*it).group() == "DefaultServerAddress"){
+ if ((*it).name() == "ORPort")
+ ( sendToServer(QString("SETCONF %1=%2").arg((*it).name())
+ .arg( (*it).property().toString())));
+ return false;
+ }
+
+ if (((*it).name() == "BandwidthBurst") || ((*it).name() == "BandwidthRate")){
+ ( sendToServer(QString("SETCONF BandwidthBurst=%1KB BandwidthRate=%2KB")
+ .arg(TorkConfig::bandwidthBurst()).arg(TorkConfig::bandwidthRate())));
+ getBandwidth();
+ return false;
+ }
+
+ if ((*it).name() == "MaxAdvertisedBandwidth"){
+ ( sendToServer(QString("SETCONF %1=%2KB").arg((*it).name()).arg( (*it).property().toString())));
+ getBandwidth();
+ return false;
+ }
+
+ if ((*it).name() == "AccountingMax"){
+ ( sendToServer(QString("SETCONF %1=\"%2 bytes\"").arg((*it).name()).arg( ((*it).property().toInt() * 1024 * 1024))));
+ return false;
+ }
+
+ if ((*it).name() == "AccountingStart"){
+ if ((*it).property().toString() == "day")
+ ( sendToServer(QString("SETCONF %1=\"%2 00:00\"").arg((*it).name()).arg( (*it).property().toString())));
+ else
+ ( sendToServer(QString("SETCONF %1=\"%2 1 00:00\"").arg((*it).name()).arg( (*it).property().toString())));
+ return false;
+ }
+
+
+ if ((*it).name() == "KeepalivePeriod"){
+ if (!TorkConfig::reachableAddresses().isEmpty()){
+ ( sendToServer(QString("SETCONF %1=%2").arg((*it).name()).arg( ((*it).property().toInt() * 60)))) ;
+ }
+ return false;
+ }
+
+ if ((*it).name() == "TrackHostExits"){
+ if (!TorkConfig::trackHostExits().isEmpty()){
+ ( sendToServer(QString("SETCONF %1=%2").arg((*it).name()).arg( ((*it).property().toStringList().join(","))))) ;
+ if (TorkConfig::trackHostExitsExpire() > 0)
+ ( sendToServer(QString("SETCONF TrackHostExitsExpire=%2").arg((TorkConfig::trackHostExitsExpire() * 60)))) ;
+ }
+ return false;
+ }
+
+
+ if ((*it).name() == "SOCKSBindAddressMany"){
+
+ if (!TorkConfig::sOCKSBindAddressMany().isEmpty()){
+ QStringList socksbind = TorkConfig::sOCKSBindAddressMany();
+ for ( QStringList::Iterator it = (socksbind).begin(); it != (socksbind).end(); it++ )
+ {
+ if ((*it).isEmpty())
+ continue;
+ ( sendToServer(QString("SETCONF SOCKSListenAddress=%2").arg((*it)))) ;
+ }
+ }
+ return false;
+ }
+
+ if ((*it).name() == "ExitPolicy"){
+ if (TorkConfig::middleMan())
+ ( sendToServer(QString("SETCONF ExitPolicy=%1").arg(("\"reject *:*\"")))) ;
+ else
+ ( sendToServer(QString("SETCONF %1=\"%2\"").arg((*it).name()).arg( (*it).property().toStringList().join(","))));
+ return false;
+ }
+
+
+ if ((*it).name() == "HiddenServices"){
+ QStringList hiddenServices = TorkConfig::hiddenServices();
+ QString allservices;
+ for ( QStringList::Iterator it = (hiddenServices).begin(); it != (hiddenServices).end(); it++ )
+ {
+ if ((*it).isEmpty())
+ continue;
+ allservices += (QString("HiddenServiceDir=\"%1\" HiddenServicePort=\"%2 %3\" ").arg((*it).section("\n",-1)).arg((*it).section("\n",-4,-4)).arg((*it).section("\n",-3,-3))) ;
+ }
+ if (!allservices.isEmpty())
+ ( sendToServer(QString("SETCONF %1").arg(allservices))) ;
+ else
+ ( sendToServer(QString("SETCONF HiddenServiceDir= HiddenServicePort="))) ;
+
+ return false;
+ }
+
+ if ((TorkConfig::useBridges()) && ((*it).name() == "Bridge")){
+
+ QStringList bridges = TorkConfig::bridge();
+ QString allbridges;
+ for ( QStringList::Iterator it = (bridges).begin(); it != (bridges).end(); it++ )
+ {
+ if ((*it).isEmpty())
+ continue;
+ allbridges += (QString("Bridge=\"%1\" ")
+ .arg((*it))) ;
+ }
+ if (!allbridges.isEmpty())
+ ( sendToServer(QString("SETCONF %1").arg(allbridges))) ;
+ else
+ ( sendToServer(QString("SETCONF Bridge="))) ;
+
+ return false;
+ }
+
+ if ((*it).name() == "MyFamily"){
+
+ QStringList family = TorkConfig::myFamily();
+ QStringList allfamily;
+ for ( QStringList::Iterator it = (family).begin(); it != (family).end(); it++ )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString node = "$"+getFPFromFPDigest((*it).section("-",1,1));
+ allfamily.append(node) ;
+ }
+ if (!allfamily.isEmpty())
+ ( sendToServer(QString("SETCONF MyFamily=%1").arg(allfamily.join(",")))) ;
+ else
+ ( sendToServer(QString("SETCONF MyFamily="))) ;
+
+ return false;
+ }
+
+ if ((*it).name() == "MapAddress"){
+
+ QStringList maps = TorkConfig::mapAddress();
+ for ( QStringList::Iterator it = (maps).begin();
+ it != (maps).end(); it++ )
+ {
+ if ((*it).isEmpty())
+ continue;
+ ( sendToServer(QString("SETCONF MapAddress=%2").arg((*it)))) ;
+ }
+ return false;
+ }
+
+ if ((!TorkConfig::fascistFirewall()) && ((*it).name() == "ReachableAddresses")){
+ ( sendToServer(QString("SETCONF ReachableAddresses="))) ;
+ return false;
+ }
+ return true;
+}
+
+
+void TorClient::cleanUp()
+{
+
+ if (TorkConfig::hashedControlPassword().isEmpty() &&
+ (!TorkConfig::cookieAuthentication()) &&
+ TorkConfig::generateRandomPassword()){
+ sendToServer(QString("setconf HashedControlPassword="));
+ socket->flush();
+ }
+}
+
+TorClient::~TorClient()
+{
+
+}
+
+void TorClient::parseDirStatus(const QString &info)
+{
+
+
+ if (info.left(2) == "r "){
+ ds_identity = info.section(" ",2,2);
+ ds_ip = info.section(" ",6,6);
+ ds_server = info.section(" ",1,1);
+ ds_date = info.section(" ",4,4);
+ return;
+ }
+
+ if (info.left(2) == "s "){
+
+ if (QDate::currentDate().daysTo(QDate(ds_date.left(4).toInt(),
+ ds_date.mid(5,2).toInt(),ds_date.right(2).toInt())) > -30) {
+ if (server(ds_identity).isEmpty())
+ storeServer(ds_server,ds_identity);
+
+ ds_statuses = info;
+ emit updateServerStatus(ds_ip, ds_identity, ds_server, ds_statuses);
+ }
+ }
+
+}
+
+bool TorClient::isControllerWorking()
+{
+ return m_controllerWorking;
+
+}
+
+void TorClient::setBandwidth(const QString &rate, const QString &burst, const QString &max)
+{
+ ( sendToServer(QString("SETCONF BandwidthRate=%2KB BandwidthBurst=%2KB")
+ .arg(rate).arg(burst)));
+ if (!max.isEmpty())
+ ( sendToServer(QString("SETCONF MaxAdvertisedBandwidth=%2KB").arg(max)));
+ getBandwidth();
+}
+
+void TorClient::getBandwidth()
+{
+ ( sendToServer(QString("GETCONF BandwidthRate")));
+ ( sendToServer(QString("GETCONF BandwidthBurst")));
+ ( sendToServer(QString("GETCONF MaxAdvertisedBandwidth")));
+}
+
+void TorClient::handleTorVersion( const QString &caption)
+{
+ m_currentTorVersion = caption;
+ if (m_currentTorVersion.left(3) == "0.2")
+ sendToServer("SETCONF DownloadExtraInfo=1");
+ emit setTorCaption(caption);
+}
+
+void TorClient::closeAllCircuits( QListView* &circuitList)
+{
+ QListViewItemIterator cit(circuitList);
+ while ( cit.current() ) {
+ attemptCloseCircuit(cit.current()->text(0));
+ ++cit;
+ }
+}
+
+void TorClient::assignPortToRemove()
+{
+ //called by the warning message to get the port to remove in case
+ // user requests it.
+ if (m_WarnedPorts[0].isNull())
+ return;
+ kdDebug() << "warnedports " << m_WarnedPorts[0] << endl;
+ m_portToRemove = m_WarnedPorts[0];
+ kdDebug() << "porttoremove" << m_portToRemove << endl;
+ m_WarnedPorts.pop_front();
+ kdDebug() << "porttoremove" << m_portToRemove << endl;
+
+}
+
+void TorClient::allowPlainTextPorts()
+{
+
+ kdDebug() << "m_portsToReject " << m_portsToReject << endl;
+
+ m_portsToReject.remove(m_portsToReject.find(m_portToRemove));
+ sendToServer(QString("SETCONF WarnPlainTextPorts=%1")
+ .arg(m_portsToReject.join(",")));
+ sendToServer(QString("SETCONF RejectPlainTextPorts=%1")
+ .arg(m_portsToReject.join(",")));
+}
+
+void TorClient::resolveAddress(const QString &address)
+{
+ QRegExp rx("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}");
+ rx.search(address);
+ QString tmp = rx.cap(0);
+ if (tmp.isEmpty()) {
+ sendToServer("RESOLVE " + address);
+ logResolveList << address;
+ }else{
+ sendToServer("RESOLVE mode=reverse " + tmp);
+ logResolveList << QString("REVERSE[%1]").arg(tmp);
+ }
+
+}
+
+#include "torclient.moc"
+
diff --git a/src/torclient.h b/src/torclient.h
new file mode 100644
index 0000000..caaed20
--- /dev/null
+++ b/src/torclient.h
@@ -0,0 +1,274 @@
+/****************************************************************************
+ ** $Id: torclient.h,v 1.76 2009/01/17 15:49:08 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************
+**
+** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
+**
+** This file is part of an example program for Qt. This example
+** program may be used, distributed and modified without limitation.
+**
+*****************************************************************************/
+
+#ifndef _TORCLIENT_H_
+#define _TORCLIENT_H_
+
+#include <qsocket.h>
+#include <qtextstream.h>
+#include <kdebug.h>
+#include <kconfigskeleton.h>
+#include <qlistview.h>
+#include "torkconfig.h"
+
+
+class KConfigSkeleton;
+class KConfigSkeletonItem;
+
+class PrevConfig
+ {
+ public:
+ PrevConfig(): pr(0) {}
+ PrevConfig( const QString& name, const QVariant& property )
+ : nm(name), pr(property)
+ {}
+ typedef QValueList<PrevConfig> PrevConfigList;
+ QString name() const { return nm; }
+ QVariant property() const { return pr; }
+ void setName( QString n ) { nm = n; }
+ void setProperty( QVariant p ) { pr = p; }
+ private:
+ QString nm;
+ QVariant pr;
+ };
+
+
+
+class TorClient : public QObject
+{
+ Q_OBJECT
+public:
+ TorClient( const QString &host, Q_UINT16 port );
+
+ virtual ~TorClient();
+
+
+ void sendToServer(const QString &string)
+ {
+ if (!socket)
+ return;
+ QTextStream os(socket);
+ os << string << "\r\n";
+ }
+
+ QStringList currentServerReport()
+ {
+ return serverReport;
+ }
+
+ QStringList currentClientReport()
+ {
+ return clientReport;
+ }
+
+ void bandwidth();
+ bool isControllerWorking( );
+ void updatePrevConfig(PrevConfig::PrevConfigList previtems);
+ void newIdentity();
+ void createService(const QString &dir, const QString &port);
+ void setBandwidth(const QString &rate, const QString &burst, const QString &max);
+ void setGeoIPAvailable(bool set){geoip_db = set;};
+ unsigned long int getCurBandwidthRate(){return m_CurBandwidthRate;};
+ unsigned long int getCurBandwidthBurst(){return m_CurBandwidthBurst;};
+ unsigned long int getCurMaxAdvertisedBandwidth()
+ {return m_CurMaxAdvertisedBandwidth;};
+ void getBandwidth();
+ void enableDNS( bool set );
+ void enableTransPort( bool set );
+ void cleanUp();
+
+signals:
+
+ void streamStatusUpdate(const QString &, const QString &,
+ const QString &, const QString &, const QString &);
+ void ORStatusUpdate(const QString &, const QString &);
+ void guardStatusUpdate(const QString &, const QString &);
+ void circuitStatusUpdate(const QString &, const QString &,
+ const QString &, const QString &);
+ void infoUpdate(const QString &,const QString &, const QString &);
+ void bwUpdate(const QString &,const QString &);
+ void updateActiveServers(const QStringList &);
+ void updateServerStatus(const QString &, const QString &,
+ const QString &,const QString &);
+ void fatalError();
+ void serverError();
+ void displayError(const QString &,const QString &);
+ void displayServer(const QString &,const QString &);
+ void whatImDoing(const QString &);
+ void copyOldConfig();
+ void shouldIApplySettings();
+ void torConnectionClosed();
+ void makeTorkStoppable();
+ void warnNoServerInfo();
+ void needAlphaVersion( );
+ void connectedToTor( );
+ void authenticated();
+ void streamBwUpdate(const QString &,const QString &,const QString & );
+ void setTorCaption(const QString &);
+ void processWarning(const QString &,const QString &);
+ void processQuestion(const QString &,const QString &);
+ void showServerBW(const QString&);
+ void updateTrayIcon(const QString&);
+ void resolvedAddress(const QString&);
+ void authenticationFailed();
+
+public slots:
+ void socketReadyRead();
+ void applySettingsToRunningTor();
+ void attemptAttach(const QString &, const QString &);
+ void attemptExtendCircuit(const QString &, const QString &, bool);
+ void attemptCreateCircuit(const QString &, bool);
+ void attemptCloseStream(const QString &);
+ void attemptAttachStreams( bool );
+ void attemptCloseCircuit(const QString &);
+ void fetchServerInfo(const QString &);
+ void fetchServerInfoByNick(const QString &);
+ void slotCheckTorNet();
+ void authenticate();
+ void slotCheckGuards();
+ void updateExcludeNodes();
+ void updateEntryNodes();
+ void updateExitNodes();
+ void safeLogging( bool safe);
+ void clearNodes();
+ void strictExitNodes( bool strict );
+ void configureServer( int orPort, int dirPort);
+ void closeAllCircuits( QListView* &circuitList);
+ void allowPlainTextPorts( );
+ void assignPortToRemove();
+ void resolveAddress(const QString &);
+ void terminateTor();
+
+private slots:
+ void closeConnection()
+ {
+ socket->close();
+ if ( socket->state() == QSocket::Closing ) {
+ // We have a delayed close.
+ connect( socket, SIGNAL(delayedCloseFinished()),
+ SLOT(socketClosed()) );
+ } else {
+ // The socket is closed.
+ socketClosed();
+ }
+ }
+
+
+ void socketConnected()
+ {
+ emit connectedToTor();
+ }
+
+ void socketConnectionClosed()
+ {
+ emit torConnectionClosed();
+ }
+
+ void socketClosed()
+ {
+ }
+
+ void socketError( int e )
+ {
+ if ( e == QSocket::ErrHostNotFound ||
+ e == QSocket::ErrConnectionRefused )
+ emit fatalError();
+ }
+
+ void parseEvent(const QString &type, const QString &info);
+ void parseStream(const QString &info);
+ void parseGuards(const QString &info);
+ void parseORConn(const QString &info);
+ void parseServer(const QString &info);
+ void parseCircuit(const QString &info);
+ void parseInfo(const QString &type, const QString &info);
+ void parseBW(const QString &info);
+ void parseAddrmap(const QString &info);
+ void parseStreamBW(const QString &info);
+ void parseDirStatus(const QString &info);
+ void parseStatusGeneral(const QString &info);
+ void resetClientReport();
+ void updateCandidateServers(const QString &path);
+ void handle250(const QString &line);
+ void updateServerReport(const QString &message,
+ const QString &info);
+ void updateClientReport(const QString &message);
+ void populateMessageFromStatusDetail(const QString &line,
+ QString &message);
+ void handleTorVersion( const QString &caption);
+ void readRouters();
+
+private:
+ QSocket *socket;
+ bool m_expectingCircuitInfo;
+ bool m_expectingStreamInfo;
+ bool m_expectingOrconnInfo;
+ bool m_expectingGuardsInfo;
+ bool m_expectingDirStatus;
+ bool m_expectingServerInfo;
+ bool m_resolvingServerAddress;
+ bool geoip_db;
+ QString m_currentTorVersion;
+ bool elementShouldBeUsed(const KConfigSkeletonItem* it);
+ bool noSpecialProcessing(const KConfigSkeletonItem* it);
+ bool readCookie();
+ QString ds_identity;
+ QString ds_fp_identity;
+ QString ds_ip;
+ QString ds_server;
+ QString ds_date;
+ QString ds_statuses;
+ QString m_statustip;
+ QString m_statustiptmp;
+ bool m_controllerWorking;
+ bool authorityread;
+ bool m_firstloadcomplete;
+ bool m_firstdircomplete;
+ PrevConfig::PrevConfigList m_previtems;
+ int m_CurBandwidthRate;
+ int m_CurBandwidthBurst;
+ int m_CurMaxAdvertisedBandwidth;
+ QString m_statustipIP;
+ typedef QMap<QString, QString> statusmap;
+ statusmap statusMessage;
+ statusmap serverStatus;
+ statusmap serverStatusIcon;
+ statusmap clientStatus;
+ statusmap portMessage;
+ statusmap clientStatusIcon;
+ QStringList serverReport;
+ QStringList clientReport;
+ QStringList m_WarnedPorts;
+ QStringList m_portsToReject;
+ QString m_portToRemove;
+ QStringList logResolveList;
+};
+
+#endif //
+
+
diff --git a/src/torconfig.h b/src/torconfig.h
new file mode 100644
index 0000000..88a0bae
--- /dev/null
+++ b/src/torconfig.h
@@ -0,0 +1,318 @@
+/***************************************************************************
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "torkconfig.h"
+
+TorkConfig* torkcon = TorkConfig::self();
+
+/** Enumeration of types which option values can take */
+typedef enum config_type_t {
+ CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
+ CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
+ CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */
+ CONFIG_TYPE_DUO, /**< two values from torkconfig required */
+ CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */
+} config_type_t;
+
+
+/** A variable allowed in the configuration file or on the command line. */
+typedef struct config_t {
+ bool (*groupcondition)(); /**<Group condition for config value */
+ int (*configvalue)(); /**<Value in torkconfig */
+ int (*configvaluetwo)(); /**<Second Value in torkconfig (in case of DUOs) */
+ config_type_t type; /**< The type of the value. */
+ const char *text; /**< Text for value. */
+ const char *suffix; /**< Text for value. */
+} config_t;
+
+
+/** An entry for config_vars: "The option <b>name</b> has type
+ * CONFIG_TYPE_<b>conftype</b>, and corresponds to
+ * or_options_t.<b>member</b>"
+ */
+#define MSG(groupcond, configval, configvaltwo, type, text, suffix) \
+ { groupcond, configval, configvaltwo, type, text, suffix }
+
+/** Array of configuration options. Until we disallow nonstandard
+ * abbreviations, order is significant, since the first matching option will
+ * be chosen first.
+ */
+static config_t _tor_config[] = {
+ MSG((&TorkConfig::defaultMaxMinOptions),
+ (&TorkConfig::bandwidthBurst),
+ (&TorkConfig::bandwidthBurst),
+ CONFIG_TYPE_UINT,
+ "BandwidthBurst",
+ "KB"),
+ MSG((&TorkConfig::defaultMaxMinOptions),
+ (&TorkConfig::bandwidthRate),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "BandwidthRate",
+ "KB"),
+ MSG((&TorkConfig::defaultMaxMinOptions),
+ (&TorkConfig::maxAdvertisedBandwidth),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "MaxAdvertisedBandwidth",
+ "GB"),
+ MSG((&TorkConfig::defaultMaxMinOptions),
+ (&TorkConfig::maxCircuitDirtiness),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "MaxCircuitDirtiness",
+ ""),
+ MSG((&TorkConfig::defaultMaxMinOptions),
+ (&TorkConfig::maxConn),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "ConnLimit",
+ ""),
+
+ MSG((&TorkConfig::defaultRunningNormalOptions),
+ (&TorkConfig::user),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "User",
+ ""),
+ MSG((&TorkConfig::defaultRunningNormalOptions),
+ (&TorkConfig::group),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "Group",
+ ""),
+ MSG((&TorkConfig::defaultRunningNormalOptions),
+ (&TorkConfig::outboundBindAddress),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "OutboundBindAddress",
+ ""),
+ MSG((&TorkConfig::defaultRunningNormalOptions),
+ (&TorkConfig::dataDirectory),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "dataDirectory",
+ ""),
+ MSG((&TorkConfig::defaultRunningNormalOptions),
+ (&TorkConfig::hashedControlPassword),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "hashedControlPassword",
+ ""),
+ MSG((&TorkConfig::defaultRunningNormalOptions),
+ (&TorkConfig::cookieAuthentication),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "cookieAuthentication",
+ ""),
+
+ MSG((&TorkConfig::defaultServerIP),
+ (&TorkConfig::oRBindAddress),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "oRBindAddress",
+ ""),
+
+/* MSG(NULL,
+ (&TorkConfig::oRPort),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "ORPort",
+ ""),
+
+ MSG((&TorkConfig::defaultServerPerformance),
+ (&TorkConfig::numCPUs),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "numCPUs",
+ ""),
+ MSG((&TorkConfig::defaultServerPerformance),
+ (&TorkConfig::maxOnionsPending),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "maxOnionsPending",
+ ""),
+ MSG((&TorkConfig::defaultServerPerformance),
+ (&TorkConfig::accountingMax),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "accountingMax",
+ "bytes"),*/
+/* MSG((&TorkConfig::defaultServerPerformance),
+ (&TorkConfig::accountingStart),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "accountingStart",
+ ""),*/
+/* MSG((&TorkConfig::defaultServerPerformance),
+ (&TorkConfig::shutDownWaitLength),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "ShutDownWaitLength",
+ ""),
+
+ MSG((NULL),
+ (&TorkConfig::newCircuitPeriod),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "NewCircuitPeriod",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::dirFetchPeriod),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "DirFetchPeriod",
+ ""),*/
+ MSG((NULL),
+ (&TorkConfig::dirServer),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "DirServer",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::entryNodes),
+ NULL,
+ CONFIG_TYPE_LINELIST,
+ "EntryNodes",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::excludeNodes),
+ NULL,
+ CONFIG_TYPE_LINELIST,
+ "ExcludeNodes",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::exitNodes),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "ExitNodes",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::entryNodes),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "EntryNodes",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::httpProxyPort),
+ (&TorkConfig::httpProxyHost),
+ CONFIG_TYPE_DUO,
+ "HttpProxy",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::httpsProxyPort),
+ (&TorkConfig::httpsProxyHost),
+ CONFIG_TYPE_DUO,
+ "HttpsProxy",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::httpProxyAuthenticatorUserName),
+ (&TorkConfig::httpProxyAuthenticatorPassword),
+ CONFIG_TYPE_DUO,
+ "HttpProxyAuthenticator",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::httpsProxyAuthenticatorUserName),
+ (&TorkConfig::httpsProxyAuthenticatorPassword),
+ CONFIG_TYPE_DUO,
+ "HttpsProxyAuthenticator",
+ ""),
+
+/* MSG((NULL),
+ (&TorkConfig::keepalivePeriod),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "KeepalivePeriod",
+ ""),*/
+/* MSG((NULL),
+ (&TorkConfig::longLivedPorts),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "LongLivedPorts",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::mapAddress),
+ NULL,
+ CONFIG_TYPE_STRING,
+ "MapAddress",
+ ""),*/
+/* MSG((NULL),
+ (&TorkConfig::numHelperNodes),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "NumHelperNodes",
+ ""),*/
+/* MSG((NULL),
+ (&TorkConfig::reachableAddresses),
+ NULL,
+ CONFIG_TYPE_LINELIST,
+ "ReachableAddresses",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::rendNodes),
+ NULL,
+ CONFIG_TYPE_LINELIST,
+ "RendNodes",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::sOCKSBindAddressHost),
+ (&TorkConfig::sOCKSBindAddressPort),
+ CONFIG_TYPE_DUO,
+ "SOCKSBindAddress",
+ ":"),
+ MSG((NULL),
+ (&TorkConfig::sOCKSBindAddressMany),
+ NULL,
+ CONFIG_TYPE_LINELIST,
+ "SOCKSBindAddress",
+ "\nSOCKSBindAddress"),
+ MSG((NULL),
+ (&TorkConfig::sOCKSPolicy),
+ NULL,
+ CONFIG_TYPE_LINELIST,
+ "SOCKSPolicy",
+ ""),*/
+/* MSG((NULL),
+ (&TorkConfig::statusFetchPeriod),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "StatusFetchPeriod",
+ ""),*/
+/* MSG((NULL),
+ (&TorkConfig::statusFetchPeriod),
+ NULL,
+ CONFIG_TYPE_BOOL,
+ "StrictExitNodes",
+ ""),
+ MSG((NULL),
+ (&TorkConfig::trackHostExits),
+ NULL,
+ CONFIG_TYPE_LINELIST,
+ "TrackHostExits",
+ ""),*/
+ MSG((NULL),
+ (&TorkConfig::trackHostExitsExpire),
+ NULL,
+ CONFIG_TYPE_UINT,
+ "TrackHostExitsExpire",
+ ""),
+
+/* { NULL, NULL, NULL, NULL, NULL, NULL }*/
+};
+#undef MSG
diff --git a/src/tork.1 b/src/tork.1
new file mode 100644
index 0000000..cd7a195
--- /dev/null
+++ b/src/tork.1
@@ -0,0 +1,52 @@
+.TH "TORK" "1"
+.SH "NAME"
+tork \- an anonymity manager for KDE.
+.SH "SYNOPSIS"
+\fBtork\fR
+.SH "DESCRIPTION"
+This manual page documents briefly the
+\fBtork\fR commandline
+parameters.
+\fBtork\fR is an anonymity manager for KDE.
+It allows you to monitor all your tor and
+non-tor traffic, to search and setup tor servers
+and to launch programs like Konqueror, Opera or
+Firefox with the tor network.
+.SH "BINARY PARAMETERS"
+This program follows the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+.TP
+.B \-\-toggleKDE
+Toggle Anonymous KDE
+.TP
+.B \-\-anonymousFirefox
+Launch Anonymous Firefox
+.TP
+.B \-\-anonymousOpera
+Launch Anonymous Opera
+.TP
+.B \-\-anonymousKonsole
+Launch Anonymous Konsole
+.TP
+.B \-\-anonymousKopete
+Launch Anonymous Kopete
+.TP
+.B \-\-anonymousPidgin
+Launch Anonymous Pidgin
+.TP
+.B \-\-anonymousGaim
+Launch Anonymous Gaim
+.TP
+.B \-\-anonymousKonversation
+Launch Anonymous Konversation
+.TP
+.B \-\-anonymousEmail
+Launch Mixminion Interface
+.TP
+.SH "AUTHOR"
+This manual page was written by Patrick Matth\[:a]i <patrick.matthaei@web.de>
+for webissues.
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU General Public License, Version 2 any
+later version published by the Free Software Foundation.
diff --git a/src/tork.cpp b/src/tork.cpp
new file mode 100644
index 0000000..22e5b61
--- /dev/null
+++ b/src/tork.cpp
@@ -0,0 +1,4493 @@
+/***************************************************************************
+ * $Id: tork.cpp,v 1.202 2010/07/24 12:18:36 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#include <qdragobject.h>
+#include <kprinter.h>
+#include <qpainter.h>
+#include <qpaintdevicemetrics.h>
+#include <qtimer.h>
+#include <qgroupbox.h>
+
+#include <kconfigdialog.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kdeversion.h>
+#include <kmenubar.h>
+#include <kstatusbar.h>
+#include <kkeydialog.h>
+#include <ksqueezedtextlabel.h>
+#include <kedittoolbar.h>
+#include <ktoolbarbutton.h>
+#include <krun.h>
+#include <kstdaccel.h>
+#include <kaction.h>
+#include <kstdaction.h>
+#include <kpopupmenu.h>
+#include <kprocio.h>
+#include <kmessagebox.h>
+#include <dcopref.h>
+#include <kconfig.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kpassivepopup.h>
+#include <kio/netaccess.h>
+#include <khtml_part.h>
+#include <dom/html_misc.h>
+#include <kurl.h>
+#include <khtmlview.h>
+#include <kstandarddirs.h>
+#include <ktip.h>
+#include <kwin.h>
+#include <knotifyclient.h>
+#include <klistviewsearchline.h>
+
+#include <qtooltip.h>
+#include <qlabel.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qtabwidget.h>
+#include <qhostaddress.h>
+#include <dcopref.h>
+#include <dcopclient.h>
+#include <kcmdlineargs.h>
+
+#ifndef EXTERNAL_GEOIP
+# include "GeoIP-1.4.0/libGeoIP/GeoIP.h"
+#else
+# include <GeoIP.h>
+#endif
+
+#include "tork.h"
+#include "crypto.h"
+#include "configdialog.h"
+#include "quickconfig.h"
+#include "torkconfig.h"
+#include "functions.h"
+#include "dndlistview.h"
+#include "newfirstrunwizard.h"
+#include "introwizard.h"
+#include "serverwizard.h"
+#include "warnings.h"
+#include "questions.h"
+#include "portsandicons.h"
+#include "likeback.h"
+#include "version.h"
+#include "hiddensrvs.h"
+
+#include "../config.h"
+
+tork *kmain = 0L;
+
+using namespace tk;
+
+const char *dayweekmonth[] = {
+ "day",
+ "week",
+ "month"
+};
+
+QValueVector<QString> serverCondition(9);
+QValueVector<QString> logType(5);
+QValueVector<QString> torkifyApp(5);
+QValueVector<QString> torTrafficType(9);
+QValueVector<QString> nonTorTrafficType(9);
+QValueVector<QString> subnetType(256);
+QValueVector<QString> countryType(256);
+
+
+tork::tork()
+ : DCOPObject( "DCOPTork" ),
+ KMainWindow( 0, "TorK" ),
+ m_view(new torkView(this)),
+ m_printer(0),
+ m_servererrornag(true),
+ m_contactinfonag(true),
+ m_serverworking(true),
+ m_toolTipShowing(false),
+ waitingForServers(false),
+ stillStarting(false),
+ m_DNSTorified(false),
+ m_showstopperAlreadyDisplayed(false),
+ m_routerDiscovered(false),
+ m_ShutdownRequested(false),
+ m_CanApplyServerSettingsIfSet(false),
+ myHiddenDialog(0L),
+ privoxytest(0L)
+{
+
+
+ // Register with DCOP
+// if ( !kapp->dcopClient()->isRegistered() ) {
+ kapp->dcopClient()->registerAs( "tork", false );
+ kapp->dcopClient()->setDefaultObject( objId() );
+// }
+
+ kmain = this;
+ client = 0L;
+ childproc = 0L;
+ privoxyproc = 0L;
+ netstatproc = 0L;
+ tfPrivoxy = 0L;
+ tfTor = 0L;
+ bwtimer = 0L;
+ bwLimitTimer = 0L;
+ updater=0L;
+
+ serverCondition[0] = "All";
+ serverCondition[1] = "Valid";
+ serverCondition[2] = "Fast";
+ serverCondition[3] = "Authority";
+ serverCondition[4] = "Named";
+ serverCondition[5] = "Exit";
+ serverCondition[6] = "Running";
+ serverCondition[7] = "Guard";
+ serverCondition[8] = "Stable";
+
+ logType[0] = "All";
+ logType[1] = "NOTICE";
+ logType[2] = "WARN";
+ logType[3] = "ERR";
+ logType[4] = "DEBUG";
+
+ torkifyApp[0] = "konversation";
+ torkifyApp[1] = "kopete";
+ torkifyApp[2] = "gaim";
+ torkifyApp[3] = "pidgin";
+ torkifyApp[4] = "konsole";
+
+ torTrafficType[0] = "All";
+ torTrafficType[1] = ":80";
+ torTrafficType[2] = ":443";
+ torTrafficType[3] = ":110";
+ torTrafficType[4] = ":25";
+ torTrafficType[5] = ":22";
+ torTrafficType[6] = ":23";
+ torTrafficType[7] = ":21";
+ torTrafficType[8] = ":53";
+
+ nonTorTrafficType[0] = "All";
+ nonTorTrafficType[1] = ":80";
+ nonTorTrafficType[2] = ":443";
+ nonTorTrafficType[3] = ":110";
+ nonTorTrafficType[4] = ":25";
+ nonTorTrafficType[5] = ":22";
+ nonTorTrafficType[6] = ":23";
+ nonTorTrafficType[7] = ":21";
+ nonTorTrafficType[8] = ":53";
+
+ for ( int country_id = 0; country_id != 250; ++country_id)
+ countryType[country_id] = GeoIP_country_code[country_id];
+ countryType[251] = "All";
+
+
+ // accept dnd
+ //setAcceptDrops(true);
+
+
+ // then, setup our actions
+ setupActions();
+
+ // Instanciate the LikeBack system, and show the first-use information dialog if the button-bar is shown:
+ LikeBack *likeBack = new LikeBack(LikeBack::AllButtons, LikeBack::isDevelopmentVersion(TORK_VERSION)); // Show button-bar only in beta-versions
+ likeBack->setServer("tork.sourceforge.net", "/likeback/send.php");
+ likeBack->setAcceptedLanguages(QStringList::split(";", "en;fr"), i18n("Please write in English or French."));
+
+ // Comment the following line once you are sure all your windows have a name:
+ likeBack->setWindowNamesListing(LikeBack::WarnUnnamedWindows);
+
+ // This line should be called early in your KMainWindow constructor because it references actionCollection().
+ // It should be called before createGUI() for the action to be plugged in the Help menu:
+ likeBack->sendACommentAction(actionCollection());
+
+ // and a status bar
+ statusBar()->show();
+
+ m_statusInfo = new QLabel(this);
+ m_statusTransfer = new QLabel(this);
+
+ statusBar()->addWidget(m_statusInfo,2);
+ statusBar()->addWidget(m_statusTransfer,2);
+
+ // apply the saved mainwindow settings, if any, and ask the mainwindow
+ // to automatically save settings if changed: window size, toolbar
+ // position, icon size, etc.
+ setAutoSaveSettings();
+
+ //currentChanged(0);
+ //applySettings(false);
+
+ // tell the KMainWindow that this is indeed the main widget
+ setCentralWidget(m_view);
+
+ setStandardToolBarMenuEnabled(true);
+
+
+ setUpnpDirPort(TorkConfig::dirListenAddress());
+ setUpnpORPort(TorkConfig::oRListenAddress());
+
+ // allow the view to change the statusbar and caption
+ connect(m_view, SIGNAL(updateTrayStats(const QString&, const QString&,
+ const QString&, const QString&)),
+ this, SLOT(updateTrayStats(const QString&,const QString&,
+ const QString&, const QString&)));
+ connect(m_view->m_osd, SIGNAL(requestHideMonitor()),
+ this, SLOT(toggleTorMon2()));
+ connect(m_view->m_osd, SIGNAL(requestToggleKDE()),
+ this, SLOT(toggleKDESetting()));
+ connect(m_view->m_osd, SIGNAL(requestChangeID()),
+ this, SLOT(useNewIdentity()));
+
+ connect(m_view, SIGNAL(showSecurityNotice(const QString&)),
+ this, SLOT(showSecurityNotice(const QString&)));
+ connect(m_view, SIGNAL(showScreamingNotice(const QString&)),
+ this, SLOT(showScreamingNotice(const QString&)));
+
+ connect(m_view, SIGNAL(newIdentity()),
+ this, SLOT(useNewIdentity()));
+ connect(m_view, SIGNAL(konqWithTor()),
+ this, SLOT(toggleKDESettingAndLaunchKonq()));
+ connect(m_view, SIGNAL(networkList()),
+ this, SLOT(networkList()));
+ connect(m_view, SIGNAL(hiddenServices()),
+ this, SLOT(hiddenServices()));
+ connect(m_view, SIGNAL(mixminionHome()),
+ this, SLOT(mixminionHome()));
+ connect(m_view, SIGNAL(showMyKonqueror()),
+ this, SLOT(showMyKonqueror()));
+ connect(m_view, SIGNAL(showMyHiddenServices()),
+ this, SLOT(showMyHiddenServices()));
+ connect(m_view, SIGNAL(riskySession()),
+ this, SLOT(readEavesdropping()));
+ connect(m_view, SIGNAL(aboutTorify()),
+ this, SLOT(aboutTorify()));
+ connect(m_view, SIGNAL(aboutTor()),
+ this, SLOT(aboutTor()));
+ connect(m_view, SIGNAL(configurePrivoxy()),
+ this, SLOT(configurePrivoxy()));
+ connect(m_view, SIGNAL(aboutParanoidMode()),
+ this, SLOT(aboutParanoidMode()));
+ connect(m_view, SIGNAL(startEverything()),
+ this, SLOT(startEverything()));
+ connect(m_view, SIGNAL(stopEverything()),
+ this, SLOT(stopTorGracefully()));
+
+ connect(m_view, SIGNAL(toggleTorTraffic(bool)),
+ this, SLOT(toggleTorTraffic(bool)));
+
+ connect(m_view, SIGNAL(toggleNonTorTraffic(bool)),
+ this, SLOT(toggleNonTorTraffic(bool)));
+
+ connect(m_view, SIGNAL(processWarning(const QString& , const QString& )),
+ this, SLOT(processWarning(const QString& , const QString& )));
+
+ connect(m_view, SIGNAL(copyOldConfig()),
+ this, SLOT(copyOldConfig()));
+
+ connect(UPnPManager::Manager(),SIGNAL(routerDiscovered( kt::UPnPRouter* )),
+ this,SLOT(routerDiscovered( kt::UPnPRouter* )));
+ connect(UPnPManager::Manager(),SIGNAL(forwardingOK(kt::UPnPRouter*, const QString &, bool )),
+ this,SLOT(upnpForwardingOK(kt::UPnPRouter*, const QString & , bool)));
+ connect(UPnPManager::Manager(),SIGNAL(forwardingError(kt::UPnPRouter*, const QString &, bool )),
+ this,SLOT(upnpForwardingError(kt::UPnPRouter*, const QString &, bool )));
+
+/* if (!TorkConfig::clientOnly() && TorkConfig::forwardPorts()){
+ upnpmanager->discover();*/
+ QTimer::singleShot( 20000, this, SLOT(checkRouterDiscovered()) );
+/* }*/
+
+
+// setupGUI();
+
+ changeStatusbar("zero","zero");
+ sayWhatImDoing(i18n("To connect to Tor, press play."));
+ showTipOnStart();
+ turnOffKDE();
+
+ if ((KApplication::kApplication()->isRestored()))
+ startEverything();
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ if( args->isSet( "toggleKDE" ) ){
+ startEverything();
+ enableKDE(true);
+ }
+
+ if( args->isSet( "anonymousFirefox" ) ){
+ startEverything();
+ if (args->count() > 0)
+ m_view->anonymizedFirefox(args->arg(0));
+ else
+ m_view->anonymousFirefox();
+ }
+
+ if( args->isSet( "anonymousOpera" ) ){
+ startEverything();
+ if (args->count() > 0)
+ m_view->anonymizedOpera(args->arg(0));
+ else
+ m_view->anonymousOpera();
+ }
+
+ if( args->isSet( "anonymousKopete" ) ){
+ startEverything();
+ m_view->torify("kopete --caption 'Anonymous IM Session - Launched From TorK'");
+ }
+
+ if( args->isSet( "anonymousKonversation" ) ){
+ startEverything();
+ m_view->torify("konversation --caption 'Anonymous IM Session - Launched From TorK'");
+ }
+
+ if( args->isSet( "anonymousPidgin" ) ){
+ startEverything();
+ m_view->torify("pidgin --caption 'Anonymous IM Session - Launched From TorK'");
+ }
+
+ if( args->isSet( "anonymousGaim" ) ){
+ startEverything();
+ m_view->torify("gaim --caption 'Anonymous IM Session - Launched From TorK'");
+ }
+
+ if( args->isSet( "anonymousKonsole" ) ){
+ startEverything();
+ m_view->torify("konsole --caption 'Anonymous Shell Session - Launched From TorK'");
+ }
+
+ if( args->isSet( "anonymousEmail" ) ){
+ startEverything();
+ hide();
+ m_view->sendAnonymousEmail();
+ }
+
+ //Toggle 'advanced' toolbar if necessary
+ if (TorkConfig::advancedMode()){
+ m_ModeButton->plug( toolBar("TorToolBar") );
+ toolBar("TorToolBar")->setToggle(toolBar("TorToolBar")->idAt(2),true);
+ toolBar("TorToolBar")->toggleButton(toolBar("TorToolBar")->idAt(2));
+ toolBar("MoreToolBar")->show();
+ }else{
+ toolBar("TorToolBar")->setIconText( KToolBar::IconTextRight, false );
+ m_ModeButton->plug( toolBar("TorToolBar") );
+ toolBar("TorToolBar")->setToggle(toolBar("TorToolBar")->idAt(2),true);
+ toolBar("MoreToolBar")->hide();
+ toolBar("TorToolBar")->setIconText( KToolBar::IconOnly, false );
+ }
+
+}
+
+tork::~tork()
+{
+ prepareToShut();
+
+}
+
+void tork::prepareToShut()
+{
+
+ if (client != 0L){
+ client->cleanUp();
+ client->socketReadyRead();
+ client->deleteLater();
+ client = 0L;
+ }
+
+ KConfig* config = new KConfig("kioslaverc", false, false);
+ config->setGroup( "Proxy Settings" );
+ config->writeEntry( "httpProxy", TorkConfig::originalHttpProxy() );
+ config->writeEntry( "httpsProxy", TorkConfig::originalHttpsProxy() );
+ config->writeEntry( "ProxyType", TorkConfig::originalProxyType() );
+ config->sync();
+
+ //delete config;
+ // Inform all running io-slaves about the changes...
+ // if we cannot update, ioslaves inform the end user...
+ if (!DCOPRef("*", "KIO::Scheduler").send("reparseSlaveConfiguration", QString::null))
+ {
+ QString caption = i18n("Update Failed");
+ QString message = i18n("You have to restart the running applications "
+ "for these changes to take effect.");
+ KMessageBox::information (this, message, caption);
+ return;
+ }
+ if (childproc !=0L){
+ childproc->kill();
+ delete childproc;
+ childproc = 0L;
+ }
+
+ if (privoxyproc !=0L){
+ privoxyproc->kill();
+ delete privoxyproc;
+ privoxyproc = 0L;
+ }
+
+
+ if (tfPrivoxy !=0L){
+ delete tfPrivoxy;
+ tfPrivoxy = 0L;
+ }
+
+ if (tfTor !=0L){
+ delete tfTor;
+ tfTor = 0L;
+ }
+
+ if (privoxytest !=0L){
+ delete privoxytest;
+ privoxytest = 0L;
+ }
+
+ m_view->m_osd->saveSettings(KGlobal::config());
+
+ TorkConfig::writeConfig();
+
+
+}
+
+bool tork::queryClose()
+{
+
+ if (client && !kapp->sessionSaving()) {
+ hide();
+ return false;
+ }
+
+ return true;
+}
+
+void tork::shuttingDown()
+{
+
+
+ if (m_DNSTorified){
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled", i18n("<b>You are now in "
+ "FailSafe Mode</b>. <br> You need to be in Normal Mode before "
+ "you can close TorK."));
+ return;
+ }
+
+
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled", "TorK Has Closed And Returned "
+ "KDE To Its Non-Anonymous State! Goodbye!");
+
+ prepareToShut();
+
+ kapp->quit();
+}
+
+void tork::setupActions()
+{
+
+ //Set up system tray
+ _tray = new TrayIcon(this);
+ _tray->setPixmap(KSystemTray::loadIcon("tork_pressplay"));
+ connect(_tray,SIGNAL(quitSelected()),SLOT(shuttingDown()));
+ KPopupMenu *conf_menu = _tray->contextMenu();
+ torkConfigure = new KAction(i18n("&Configure TorK"), "configure", 0,
+ this, SLOT(optionsPreferences()),actionCollection(),"configure_tor");
+
+ torkStart = new KAction(i18n("Connect To Tor"), "tork_play", 0,this,
+ SLOT(startEverything()),actionCollection(),"start_tor");
+ torkStop = new KAction(i18n("Disconnect From Tor"),"tork_stop", 0,this,
+ SLOT(stopTorGracefully()),actionCollection(),"stop_tor");
+ enableKonqi = new KAction(i18n("Enable/Disable Konqueror's use of Tor"),"konqueror", 0,this,
+ SLOT(toggleKDESetting()),actionCollection(),"enable_konqi");
+ enableTormon = new KAction(i18n("Toggle Tor Traffic OSD"),"tork_konsole", 0,this,
+ SLOT(toggleTorMon()),actionCollection(),"enable_tormon");
+ browseHiddenServices = new KAction(i18n("Browse Hidden Services"),"tork_tor", 0,this,
+ SLOT(hiddenServices()),actionCollection(),"hidden_services");
+ browseNetworkList = new KAction(i18n("Browse Tor Network Status"),"info", 0,this,
+ SLOT(networkList()),actionCollection(),"network_list");
+#ifndef LIVECD
+ torkUpdateTork = new KAction(i18n("Download Tork"), "tork_green", 0,this,
+ SLOT(updateTork()),actionCollection(),"update_tork");
+ torkUpdateStable = new KAction(i18n("Download Tor (Stable Version)"), "tork_tor", 0,this,
+ SLOT(updateTorStable()),actionCollection(),"update_torstable");
+ torkUpdateUnstable = new KAction(i18n("Download Tor (Experimental Version)"), "tork_tor", 0,this,
+ SLOT(updateTorUnstable()),actionCollection(),"update_torunstable");
+ torkUpdatePrivoxy = new KAction(i18n("Download Privoxy (Proxy)"), "proxy", 0,this,
+ SLOT(updatePrivoxy()),actionCollection(),"update_privoxy");
+#endif
+ torkFirstRunWizard = new KAction(i18n("First Run Wizard"), "wizard", 0,this,
+ SLOT(runWizard()),actionCollection(),"firstrun_wizard");
+ toggleTorbar = new KAction(i18n("Toggle Tor Bar"), "tork_tor", 0,this,
+ SLOT(toggleTorBar()),actionCollection(),"toggle_torbar");
+
+ connect(m_view->TorkTabs,SIGNAL(currentChanged( QWidget* )),SLOT(currentTabChanged( QWidget* )));
+
+ //Servers Filter
+
+ m_ServerFilterButton = new KActionMenu( i18n( "Servers" ), "filter", actionCollection() );
+ m_ServerFilterButton->setDelayed( false );
+ m_ServerFilterMenu = m_ServerFilterButton->popupMenu();
+ m_ServerFilterMenu->insertItem( i18n( "All" ), this, SLOT( filterServers( int ) ), 0, 0 );
+ m_ServerFilterMenu->insertItem( i18n( "Valid" ), this, SLOT( filterServers( int ) ), 0, 1 );
+ m_ServerFilterMenu->insertItem( i18n( "Fast" ), this, SLOT( filterServers( int ) ), 0, 2 );
+ m_ServerFilterMenu->insertItem( i18n( "Authority" ), this, SLOT( filterServers( int ) ), 0, 3 );
+ m_ServerFilterMenu->insertItem( i18n( "Named" ), this, SLOT( filterServers( int ) ), 0, 4 );
+ m_ServerFilterMenu->insertItem( i18n( "Exit" ), this, SLOT( filterServers( int ) ), 0, 5 );
+ m_ServerFilterMenu->insertItem( i18n( "Running" ), this, SLOT( filterServers( int ) ), 0, 6 );
+ m_ServerFilterMenu->insertItem( i18n( "Guard" ), this, SLOT( filterServers( int ) ), 0, 7 );
+ m_ServerFilterMenu->insertItem( i18n( "Stable" ), this, SLOT( filterServers( int ) ), 0, 8 );
+ m_ServerFilterMenu->insertSeparator();
+ m_ServerFilterMenu->insertItem( i18n( "Show IP" ), this,
+ SLOT( toggleIP( int ) ), 0, 10 );
+ m_ServerFilterMenu->insertSeparator();
+ m_ServerFilterMenu->insertItem( i18n( "Sort By Country" ), this, SLOT( sortByCountry( ) ), 0, 9 );
+
+ m_ServerFilterMenu->setItemChecked( 0, true );
+
+
+ m_CountryMenu = new KPopupMenu( this );
+ m_ServerFilterMenu->insertItem( i18n( "Show Countries" ), m_CountryMenu );
+
+ m_CountryMenuEU = new KPopupMenu( this );
+ m_CountryMenuAF = new KPopupMenu( this );
+ m_CountryMenuAS = new KPopupMenu( this );
+ m_CountryMenuNA = new KPopupMenu( this );
+ m_CountryMenuAN = new KPopupMenu( this );
+ m_CountryMenuSA = new KPopupMenu( this );
+ m_CountryMenuNN = new KPopupMenu( this );
+ m_CountryMenuOC = new KPopupMenu( this );
+
+ continentMapList["EU"] = m_CountryMenuEU;
+ continentMapList["AF"] = m_CountryMenuAF;
+ continentMapList["AS"] = m_CountryMenuAS;
+ continentMapList["NA"] = m_CountryMenuNA;
+ continentMapList["AN"] = m_CountryMenuAN;
+ continentMapList["SA"] = m_CountryMenuSA;
+ continentMapList["OC"] = m_CountryMenuOC;
+ continentMapList["--"] = m_CountryMenuNN;
+
+ m_CountryMenu->insertItem( i18n( "All" ), this, SLOT( filterCountries( int ) ), 0, 251 );
+ m_CountryMenu->insertItem( i18n( "Europe" ), m_CountryMenuEU );
+ m_CountryMenu->insertItem( i18n( "N America" ), m_CountryMenuNA );
+ m_CountryMenu->insertItem( i18n( "S America" ), m_CountryMenuSA );
+ m_CountryMenu->insertItem( i18n( "Africa" ), m_CountryMenuAF );
+ m_CountryMenu->insertItem( i18n( "Asia" ), m_CountryMenuAS );
+ m_CountryMenu->insertItem( i18n( "Oceania" ), m_CountryMenuOC );
+ m_CountryMenu->insertItem( i18n( "Satellite" ), m_CountryMenuNN );
+ m_CountryMenu->insertItem( i18n( "Antarctica" ), m_CountryMenuAN );
+
+ connect(m_CountryMenu,SIGNAL(aboutToShow()),SLOT(populateCountryMenu( )));
+ m_CountryMenu->setItemChecked( 251, true );
+
+ m_ServerFilterMenu->insertSeparator();
+ m_ServerFilterMenu->insertItem( i18n( "Text Filter" ), this,
+ SLOT( toggleTextFilter( int ) ), 0, 11 );
+ m_view->clearButton->setHidden(true);
+ m_view->serverFilter->setHidden(true);
+
+ // Launch Filter
+ m_LaunchMenuButton = new KActionMenu( i18n( "Launch" ), "tork_tor", actionCollection() );
+ m_LaunchMenuButton->setDelayed( false );
+ m_LaunchMenu = m_LaunchMenuButton->popupMenu();
+ m_LaunchMenu->insertItem( SmallIcon("tork_mail"), i18n( "Anonymous Email" ), m_view,
+ SLOT( sendAnonymousEmail( ) ) );
+ if (m_view->firefoxitem)
+ m_LaunchMenu->insertItem( SmallIcon("tork_firefox"), i18n( "Anonymous Firefox" ),
+ m_view, SLOT( anonymousFirefox( ) ) );
+ if (m_view->operaitem)
+ m_LaunchMenu->insertItem( SmallIcon("tork_opera"), i18n( "Anonymous Opera" ),
+ m_view, SLOT( anonymousOpera( ) ));
+ if (m_view->konversationitem)
+ m_LaunchMenu->insertItem( SmallIcon("konversation"), i18n( "Anonymous Konversation" ),
+ this,SLOT( torkify( int )), 0, 0 );
+ if (m_view->kopeteitem)
+ m_LaunchMenu->insertItem( SmallIcon("kopete"), i18n( "Anonymous Kopete" ),
+ this,SLOT( torkify( int )), 0, 1 );
+ if (m_view->gaimitem)
+ m_LaunchMenu->insertItem( SmallIcon("gaim"), i18n( "Anonymous Gaim" ),
+ this,SLOT( torkify( int )), 0, 2 );
+ if (m_view->pidginitem)
+ m_LaunchMenu->insertItem( SmallIcon("pidgin"), i18n( "Anonymous Pidgin" ),
+ this,SLOT( torkify( int )), 0, 3 );
+ if (m_view->sshitem)
+ m_LaunchMenu->insertItem( SmallIcon("tork_konsolessh"), i18n( "Anonymous SSH/Telnet" ),
+ this,SLOT( torkify( int )), 0, 4 );
+
+ // Log Filter
+ m_LogFilterButton = new KActionMenu( i18n( "Tor Log" ), "filter", actionCollection() );
+ m_LogFilterButton->setDelayed( false );
+ m_LogFilterMenu = m_LogFilterButton->popupMenu();
+ m_LogFilterMenu->insertItem( i18n( "All" ), this, SLOT( filterLog( int ) ), 0, 0 );
+ m_LogFilterMenu->insertItem( i18n( "NOTICE" ), this, SLOT( filterLog( int ) ), 0, 1 );
+ m_LogFilterMenu->insertItem( i18n( "WARNING" ), this, SLOT( filterLog( int ) ), 0, 2 );
+ m_LogFilterMenu->insertItem( i18n( "ERROR" ), this, SLOT( filterLog( int ) ), 0, 3 );
+ m_LogFilterMenu->insertItem( i18n( "DEBUG" ), this, SLOT( filterLog( int ) ), 0, 4 );
+ m_LogFilterMenu->setItemChecked( 0, true );
+
+ // Traffic Filter
+ m_TrafficFilterButton = new KActionMenu( i18n( "Traffic" ), "filter", actionCollection() );
+ m_TrafficFilterButton->setDelayed( false );
+ m_TrafficFilterMenu = m_TrafficFilterButton->popupMenu();
+ m_TorTrafficFilterMenu = new KPopupMenu( this );
+ m_NonTorTrafficFilterMenu = new KPopupMenu( this );
+
+ m_TrafficFilterMenu->insertItem( i18n( "Tor Traffic" ), m_TorTrafficFilterMenu );
+ m_TrafficFilterMenu->insertItem( i18n( "Non-Tor Traffic" ), m_NonTorTrafficFilterMenu );
+
+ m_TorTrafficFilterMenu->insertItem( i18n( "All" ), this, SLOT( filterTorTraffic( int ) ), 0, 0 );
+ m_TorTrafficFilterMenu->insertItem( SmallIcon("konqueror"), i18n( "Http" ), this,
+ SLOT( filterTorTraffic( int ) ), 0, 1 );
+ m_TorTrafficFilterMenu->insertItem( SmallIcon("tork_konqueror_https"),i18n( "Https" ), this,
+ SLOT( filterTorTraffic( int ) ), 0, 2 );
+ m_TorTrafficFilterMenu->insertItem( SmallIcon("tork_mail"),i18n( "Mail Receive" ), this,
+ SLOT( filterTorTraffic( int ) ), 0, 3 );
+ m_TorTrafficFilterMenu->insertItem( SmallIcon("tork_mail"),i18n( "Mail Send" ), this,
+ SLOT( filterTorTraffic( int ) ), 0, 4 );
+ m_TorTrafficFilterMenu->insertItem( SmallIcon("tork_konsolessh"),i18n( "SSH" ), this,
+ SLOT( filterTorTraffic( int ) ), 0, 5 );
+ m_TorTrafficFilterMenu->insertItem( SmallIcon("tork_konsole"),i18n( "Telnet" ), this,
+ SLOT( filterTorTraffic( int ) ), 0, 6 );
+ m_TorTrafficFilterMenu->insertItem( SmallIcon("konqueror"),i18n( "FTP" ), this,
+ SLOT( filterTorTraffic( int ) ), 0, 7 );
+ m_TorTrafficFilterMenu->insertItem( SmallIcon("network"),i18n( "DNS" ), this,
+ SLOT( filterTorTraffic( int ) ), 0, 8 );
+ m_TorTrafficFilterMenu->setItemChecked( 0, true );
+
+ m_NonTorTrafficFilterMenu->insertItem( i18n( "All" ), this,
+ SLOT( filterNonTorTraffic( int ) ), 0, 0 );
+ m_NonTorTrafficFilterMenu->insertItem( SmallIcon("konqueror"), i18n( "Http" ), this,
+ SLOT( filterNonTorTraffic( int ) ), 0, 1 );
+ m_NonTorTrafficFilterMenu->insertItem( SmallIcon("tork_konqueror_https"),i18n( "Https" ), this,
+ SLOT( filterNonTorTraffic( int ) ), 0, 2 );
+ m_NonTorTrafficFilterMenu->insertItem( SmallIcon("tork_mail"),i18n( "Mail Receive" ), this,
+ SLOT( filterNonTorTraffic( int ) ), 0, 3 );
+ m_NonTorTrafficFilterMenu->insertItem( SmallIcon("tork_mail"),i18n( "Mail Send" ), this,
+ SLOT( filterNonTorTraffic( int ) ), 0, 4 );
+ m_NonTorTrafficFilterMenu->insertItem( SmallIcon("tork_konsolessh"),i18n( "SSH" ), this,
+ SLOT( filterNonTorTraffic( int ) ), 0, 5 );
+ m_NonTorTrafficFilterMenu->insertItem( SmallIcon("tork_konsole"),i18n( "Telnet" ), this,
+ SLOT( filterNonTorTraffic( int ) ), 0, 6 );
+ m_NonTorTrafficFilterMenu->insertItem( SmallIcon("konqueror"),i18n( "FTP" ), this,
+ SLOT( filterNonTorTraffic( int ) ), 0, 7 );
+ m_NonTorTrafficFilterMenu->insertItem( SmallIcon("network"),i18n( "DNS" ), this,
+ SLOT( filterNonTorTraffic( int ) ), 0, 8 );
+ m_NonTorTrafficFilterMenu->setItemChecked( 0, true );
+
+
+ m_IdentityButton = new KAction(i18n("Change Identity"),"tork_identity", 0,this,
+ SLOT(useNewIdentity()),actionCollection());
+
+ //Pseudonymity Buttons
+
+ m_PseudoButton = new KActionMenu( i18n( "Be From.." ), "tork_internet",
+ actionCollection() );
+ m_PseudoButton->setDelayed( false );
+ m_PseudoMenu = m_PseudoButton->popupMenu();
+ m_PseudoMenuEU = new KPopupMenu( this );
+ m_PseudoMenuAF = new KPopupMenu( this );
+ m_PseudoMenuAS = new KPopupMenu( this );
+ m_PseudoMenuNA = new KPopupMenu( this );
+ m_PseudoMenuAN = new KPopupMenu( this );
+ m_PseudoMenuSA = new KPopupMenu( this );
+ m_PseudoMenuNN = new KPopupMenu( this );
+ m_PseudoMenuOC = new KPopupMenu( this );
+
+ continentMap["EU"] = m_PseudoMenuEU;
+ continentMap["AF"] = m_PseudoMenuAF;
+ continentMap["AS"] = m_PseudoMenuAS;
+ continentMap["NA"] = m_PseudoMenuNA;
+ continentMap["AN"] = m_PseudoMenuAN;
+ continentMap["SA"] = m_PseudoMenuSA;
+ continentMap["OC"] = m_PseudoMenuOC;
+ continentMap["--"] = m_PseudoMenuNN;
+
+ m_PseudoMenu->insertItem( i18n( "Anonymous" ), this, SLOT( applyPseudonymity( int ) ), 0, 999 );
+ m_PseudoMenu->insertItem( i18n( "Europe" ), m_PseudoMenuEU );
+ m_PseudoMenu->insertItem( i18n( "N America" ), m_PseudoMenuNA );
+ m_PseudoMenu->insertItem( i18n( "S America" ), m_PseudoMenuSA );
+ m_PseudoMenu->insertItem( i18n( "Africa" ), m_PseudoMenuAF );
+ m_PseudoMenu->insertItem( i18n( "Asia" ), m_PseudoMenuAS );
+ m_PseudoMenu->insertItem( i18n( "Oceania" ), m_PseudoMenuOC );
+ m_PseudoMenu->insertItem( i18n( "Satellite" ), m_PseudoMenuNN );
+ m_PseudoMenu->insertItem( i18n( "Antarctica" ), m_PseudoMenuAN );
+
+ connect(m_PseudoMenu,SIGNAL(aboutToShow()),SLOT(populatePseudoMenu( )));
+ m_PseudoMenu->setItemChecked(999,true);
+
+ // Server Button
+ m_ServerButton = new KActionMenu( i18n( "Run Server" ), "server", actionCollection() );
+ m_ServerButton->setDelayed( false );
+ m_ServerButtonMenu = m_ServerButton->popupMenu();
+ m_ServerButtonMenu->insertItem( i18n( "None" ), this, SLOT( configureServer( int ) ), 0, 0 );
+ m_ServerButtonMenu->insertItem( i18n( "To Exit Tor Traffic" ), this,
+ SLOT( configureServer( int ) ), 0, 1 );
+ m_ServerButtonMenu->insertItem( i18n( "To Relay Tor Traffic" ), this,
+ SLOT( configureServer( int ) ), 0, 2 );
+ m_ServerButtonMenu->insertItem( i18n( "To Defeat Censorship Of Tor" ), this,
+ SLOT( configureServer( int ) ), 0, 3 );
+ m_ServerButtonMenu->insertSeparator();
+ m_ServerButtonMenu->insertItem( KGlobal::iconLoader()->loadIconSet("configure", KIcon::Small),
+ i18n( "Configure Server" ), this, SLOT( configureServer( int ) ), 0, 4 );
+ m_ServerButtonMenu->insertItem( KGlobal::iconLoader()->loadIconSet("tork_agent", KIcon::Small),
+ i18n( "Manage Hidden Services" ), this, SLOT( configureServer( int ) ), 0, 5 );
+
+ m_ServerButtonMenu->setItemChecked( 0, true );
+
+ m_ServerButtonMenu->setItemEnabled( 4, !TorkConfig::clientOnly() );
+
+ // Server Button
+ m_SecurityButton = new KActionMenu( i18n( "Fail-Safe" ), "tork_penguin", actionCollection() );
+ m_SecurityButton->setDelayed( false );
+ m_SecurityButtonMenu = m_SecurityButton->popupMenu();
+ m_SecurityButtonMenu->insertItem( KGlobal::iconLoader()->loadIconSet("tork_penguin", KIcon::Small),
+ i18n( "None" ), this, SLOT( configureSecurity( int ) ), 0, 0 );
+ m_SecurityButtonMenu->insertItem(KGlobal::iconLoader()->loadIconSet("tork_agent", KIcon::Small),
+ i18n( "DNS FailSafe" ), this, SLOT( configureSecurity( int ) ), 0, 1 );
+ m_SecurityButtonMenu->insertItem( KGlobal::iconLoader()->loadIconSet("gv", KIcon::Small),
+ i18n( "System FailSafe" ),this, SLOT( configureSecurity( int ) ), 0, 2 );
+ m_SecurityButtonMenu->insertSeparator();
+ m_SecurityButtonMenu->insertItem( KGlobal::iconLoader()->loadIconSet("configure",
+ KIcon::Small),i18n( "Configure FailSafe" ), this, SLOT( configureSecurity( int ) ), 0, 3 );
+ m_SecurityButtonMenu->setItemChecked( 0, true );
+
+ m_UnCensorButton = new KAction(i18n("Un-Censor"),"tork_uncensor", 0,this,
+ SLOT(showFirewallEvasion()),actionCollection());
+
+ torkTip = new KAction(i18n("Tip of the Day"), "idea", 0,this,
+ SLOT(showTip()),actionCollection(),"help_show_tip");
+
+ //set up all other actions
+
+ KStdAction::quit(kapp, SLOT(quit()), actionCollection());
+
+
+ setStandardToolBarMenuEnabled(true);
+ m_statusbarAction = KStdAction::showStatusbar(this, SLOT(optionsShowStatusbar()),
+ actionCollection());
+
+ KStdAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection());
+ KStdAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection());
+ KStdAction::preferences(this, SLOT(optionsPreferences()), actionCollection());
+
+ createGUI();
+
+ m_ModeButton = new KAction(i18n("More Options"),"add", 0,this,
+ SLOT(switchMode()),actionCollection());
+
+ //Set Up Advanced Toolbar
+ toolBar("MoreToolBar")->setIconText( KToolBar::IconTextRight, false );
+ m_PseudoButton->plug( toolBar("MoreToolBar") );
+ m_ServerButton->plug( toolBar("MoreToolBar") );
+#ifndef LIVECD
+ #ifdef USE_FAILSAFE
+ m_SecurityButton->plug( toolBar("MoreToolBar") );
+ #endif
+#endif
+ toolBar("MoreToolBar")->setIconText( KToolBar::IconOnly, false );
+
+ //Set Up Core Toolbar
+ toolBar("TorToolBar")->setIconText( KToolBar::IconTextRight, false );
+ m_UnCensorButton->plug( toolBar("TorToolBar") );
+#ifndef LIVECD
+ //m_IdentityButton->plug( toolBar("TorToolBar") );
+#endif
+ toolBar("TorToolBar")->setIconText( KToolBar::IconOnly, false );
+
+
+ m_PseudoButton->setToolTip( i18n( "Pretend you're using the Internet <br> in another country." ) );
+ m_IdentityButton->setToolTip( i18n( "Reset all Tor's open channels (i.e. 'circuits') and <br>"
+ "enter the internet "
+ "from a new set of channels." ) );
+ m_UnCensorButton->setToolTip( i18n( "Evade a state or service provider's attempts <br> to block"
+ " your use of Tor." ) );
+ m_ModeButton->setToolTip( i18n( "Show/hide TorK's advanced features <br> and configuration options."
+ ) );
+ enableTormon->setToolTip( i18n( "Show/hide TorK's on-screen display (OSD) <br> of your active "
+ "connections." ) );
+ m_SecurityButton->setToolTip( i18n( "Ensure selected traffic is <br> forced through Tor." ) );
+ m_ServerButton->setToolTip( i18n( "Run a Server on the Tor Network. <br> 'Relay Tor Traffic' "
+ "is Recommended for Home Use." ) );
+
+ m_ServerButton->setEnabled(false);
+ torkStart->setEnabled(true);
+ m_LaunchMenuButton->setEnabled(false);
+ m_IdentityButton->setEnabled(false);
+ m_PseudoButton->setEnabled(false);
+ m_ServerFilterButton->setEnabled(false);
+ m_SecurityButton->setEnabled(false);
+ torkStop->setEnabled(false);
+ enableKonqi->setEnabled(false);
+ browseHiddenServices->setEnabled(false);
+
+ torkStart->plug(conf_menu);
+ torkStop->plug(conf_menu);
+ m_IdentityButton->plug(conf_menu);
+ enableKonqi->plug(conf_menu);
+ torkConfigure->plug(conf_menu);
+
+
+
+ m_set_max_rate = new SetMaxRate(this);
+ _tray->contextMenu()->insertItem(i18n("Server Bandwidth"),m_set_max_rate);
+
+ _tray->updateStats(BytesPerSecToString(0),BytesPerSecToString(0),
+ BytesPerSecToString(0),BytesPerSecToString(0),
+ QStringList("<font color='#990000'>Status Not Known</font>"),
+ QStringList("<font color='#990000'>Status Not Known</font>"),
+ BytesPerSecToString(0));
+ _tray->show();
+
+
+ toolBar("TorToolBar")->setToggle(toolBar("TorToolBar")->idAt(0),true);
+ if (m_view->getShowTormon())
+ toolBar("TorToolBar")->toggleButton(toolBar("TorToolBar")->idAt(0));
+
+}
+
+void tork::populateCountryMenu()
+{
+ //GeoIP_country_name
+
+ QValueList<int> tmplist = m_view->countryList();
+ qHeapSort( tmplist );
+ for ( QValueList<int>::Iterator it = tmplist.begin(); it != tmplist.end(); ++it )
+ {
+ if (!continentMapList.contains(GeoIP_country_continent[(*it)])) {
+ kdDebug() << "unknown continent" << GeoIP_country_continent[(*it)] << endl;
+ continue;
+ }
+
+ if ( continentMapList[GeoIP_country_continent[(*it)]]->findItem( (*it) ) ){
+ continue;
+ }
+ continentMapList[GeoIP_country_continent[(*it)]]->insertItem(
+ QString(GeoIP_country_code[(*it)]).contains("--") ? SmallIcon("help") :
+ SmallIcon(QString("tork_%1").arg(GeoIP_country_code[(*it)]).lower()),
+ GeoIP_country_name[(*it)],
+ this, SLOT( filterCountries( int ) ), 0, (*it) );
+ }
+
+}
+
+void tork::populatePseudoMenu()
+{
+ //GeoIP_country_name
+
+ QValueList<int> tmplist = m_view->countryList();
+ qHeapSort( tmplist );
+ for ( QValueList<int>::Iterator it = tmplist.begin(); it != tmplist.end(); ++it )
+ {
+ if (!continentMap.contains(GeoIP_country_continent[(*it)])) {
+ kdDebug() << "unknown continent" << GeoIP_country_continent[(*it)] << endl;
+ continue;
+ }
+
+ if ( continentMap[GeoIP_country_continent[(*it)]]->findItem( (*it) ) )
+ continue;
+ continentMap[GeoIP_country_continent[(*it)]]->insertItem(
+ QString(GeoIP_country_code[(*it)]).contains("--") ? SmallIcon("help") :
+ SmallIcon(QString("tork_%1").arg(GeoIP_country_code[(*it)]).lower()),
+ GeoIP_country_name[(*it)],
+ this, SLOT( applyPseudonymity( int ) ), 0, (*it) );
+ }
+
+}
+
+void tork::applyPseudonymity( int country_id )
+{
+ if (!continentMap.contains(GeoIP_country_continent[country_id])) {
+ kdDebug() << "unknown continent" << GeoIP_country_continent[country_id] << endl;
+ return;
+ }
+
+ // Update Menu
+ for ( QMap<QString, KPopupMenu*>::Iterator menu = continentMap.begin(); menu != continentMap.end(); ++menu )
+ {
+ for (unsigned int index = 0; index != menu.data()->count(); ++index){
+ menu.data()->setItemChecked( menu.data()->idAt(index),false);
+ }
+ }
+
+ if (country_id == 999){
+ TorkConfig::setCurrentExitNodes("");
+ if (client != 0L){
+ client->updateExitNodes();
+ client->strictExitNodes(false);
+ }
+ m_PseudoMenu->setItemChecked(999,true);
+ return;
+ }
+
+
+ // Select all exits in chosen country as our preferred exit nodes
+
+ continentMap[GeoIP_country_continent[country_id]]->setItemChecked( country_id,
+ !continentMap[GeoIP_country_continent[country_id]]->isItemChecked(country_id) ); //uncheck old item
+
+ QStringList currentList;
+ QString cc = QString("%1").arg(country_id);
+
+ QListViewItemIterator it(m_view->serverList);
+ while ( it.current() ) {
+ if ((*it)->text(4) == cc){
+ QString node = "$"+getFPFromFPDigest((*it)->text(2));
+ currentList.append(node);
+ }
+ ++it;
+ }
+ TorkConfig::setCurrentExitNodes(currentList);
+
+
+ // Update Tor with new exit list and flush all existing circuits
+ if (client != 0L){
+ //Close all open circuits first
+ QListView* tmp = dynamic_cast<QListView*>(m_view->circuitList);
+ client->closeAllCircuits(tmp);
+ //Then apply new exit list
+ client->updateExitNodes();
+ }
+
+ // Then ensure a new circuit is chosen
+ useNewIdentity();
+ m_PseudoMenu->setItemChecked(999,false);
+
+}
+
+void tork::populateSubNetMenu()
+{
+
+ if ( !m_IPFilterMenu->findItem( 0 ) ){
+ subnetType[0] = "All";
+ m_IPFilterMenu->insertItem( "All", this, SLOT( filterSubnets( int ) ), 0, 0);
+ }
+
+ QStringList tmplist = m_view->subnet16List();
+ tmplist.sort();
+ for ( QStringList::Iterator it = tmplist.begin(); it != tmplist.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString tmpit = (*it);
+ int index = tmpit.replace(".","").toInt();
+
+ if ( m_IPFilterMenu->findItem( index ) )
+ continue;
+ subnetType[index] = (*it);
+ m_IPFilterMenu->insertItem( (*it)+"*", this, SLOT( filterSubnets( int ) ), 0, index );
+ }
+
+}
+
+void tork::torkify(int id)
+{
+
+ m_view->torify(torkifyApp[id]);
+
+}
+
+void
+tork::currentTabChanged(QWidget* cur ) //SLOT
+{
+
+ toolBar()->setIconText( KToolBar::IconTextRight, false );
+
+ if (cur == prev)
+ return;
+
+ prev = m_view->TorkTabs->currentPage();
+
+ if (cur == m_view->TorkTabs->page(0)){
+ m_LaunchMenuButton->plug( toolBar() );
+ m_ServerFilterButton->unplug( toolBar() );
+ m_LogFilterButton->unplug( toolBar() );
+ m_TrafficFilterButton->unplug( toolBar() );
+ }else if (cur == m_view->TorkTabs->page(1)){
+ m_ServerFilterButton->plug( toolBar() );
+ m_LaunchMenuButton->unplug( toolBar() );
+ m_LogFilterButton->unplug( toolBar() );
+ m_TrafficFilterButton->unplug( toolBar() );
+ }else if (cur == m_view->TorkTabs->page(2)){
+ m_LogFilterButton->plug( toolBar() );
+ m_ServerFilterButton->unplug( toolBar() );
+ m_LaunchMenuButton->unplug( toolBar() );
+ m_TrafficFilterButton->unplug( toolBar() );
+ }else if (cur == m_view->TorkTabs->page(3)){
+ m_TrafficFilterButton->plug( toolBar() );
+ m_ServerFilterButton->unplug( toolBar() );
+ m_LaunchMenuButton->unplug( toolBar() );
+ m_LogFilterButton->unplug( toolBar() );
+
+ }
+
+ toolBar()->setIconText( KToolBar::IconOnly, false );
+ m_ServerFilterButton->setToolTip( i18n( "Filter the List of Servers." ) );
+ m_LaunchMenuButton->setToolTip( i18n( "Launch anonymized applications <br> with a single click." ) );
+ m_LogFilterButton->setToolTip( i18n( "Filter Log Messages by Type." ) );
+ m_TrafficFilterButton->setToolTip( i18n( "Filter displayed traffic by type." ) );
+
+}
+
+void
+tork::toggleTextFilter( int id ) //SLOT
+{
+
+ m_view->clearButton->setHidden(!m_view->clearButton->isHidden());
+ m_view->serverFilter->setHidden(!m_view->serverFilter->isHidden());
+ m_ServerFilterMenu->setItemChecked( id, !m_view->serverFilter->isHidden() );
+ m_view->serverFilter->setFocus();
+ if (m_view->clearButton->isHidden())
+ m_view->serverFilter->clear();
+}
+
+void
+tork::sortByCountry( ) //SLOT
+{
+
+ m_view->serverList->setSortColumn(4);
+ m_view->serverList->sort();
+
+}
+
+
+void
+tork::filterSubnets( int ) //SLOT
+{
+ //filterView(subnetType, (QListView*&)m_view->serverList, m_IPFilterMenu, id, 5);
+}
+
+void
+tork::filterNonTorTraffic( int id ) //SLOT
+{
+ QListViewItemIterator it(m_view->NonTorTraffic);
+ while ( it.current() ) {
+ it.current()->setVisible(false);
+ ++it;
+ }
+
+ m_NonTorTrafficFilterMenu->setItemChecked( id, !m_NonTorTrafficFilterMenu->isItemChecked(id) ); // Toggle selected item
+
+ filterView(nonTorTrafficType, m_view->NonTorTraffic, m_NonTorTrafficFilterMenu, id, 1);
+}
+
+void
+tork::filterTorTraffic( int id ) //SLOT
+{
+ QListViewItemIterator it(m_view->TorTraffic);
+ while ( it.current() ) {
+ it.current()->setVisible(false);
+ ++it;
+ }
+
+ m_TorTrafficFilterMenu->setItemChecked( id, !m_TorTrafficFilterMenu->isItemChecked(id) ); // Toggle selected item
+
+ filterView(torTrafficType, m_view->TorTraffic, m_TorTrafficFilterMenu, id, 2);
+}
+
+void
+tork::toggleServerButton( bool on ) //SLOT
+{
+ m_ServerButton->setEnabled(!on);
+ if (!on)
+ m_ServerButton->setToolTip( i18n( "Run a Server on the Tor Network. <br> 'Relay Tor Traffic' "
+ "is Recommended for Home Use." ) );
+ else
+ m_ServerButton->setToolTip( i18n( "You Can't Run a Server While <br> Using Tor's Un-Censor "
+ "Feature." ) );
+
+}
+
+void
+tork::updateServerButton( ) //SLOT
+{
+ //Set quick-select dropdown to reflect setting in config panel
+ m_view->welcomeitem->score->setCurrentItem(TorkConfig::quickConfigure());
+
+ for (unsigned int index = 0; index != 3; ++index){
+ m_ServerButtonMenu->setItemChecked( index, false ); //uncheck old item
+ }
+
+ if (TorkConfig::clientOnly()){
+ m_ServerButtonMenu->setItemChecked( 0, true );
+ return;
+ }
+
+ if (TorkConfig::middleMan()){
+ m_ServerButtonMenu->setItemChecked( 2, true );
+ return;
+ }
+
+ m_ServerButtonMenu->setItemChecked( 1, true );
+
+}
+
+void
+tork::switchMode() //SLOT
+{
+ TorkConfig::setAdvancedMode(!TorkConfig::advancedMode());
+ TorkConfig::writeConfig();
+
+
+ if (TorkConfig::advancedMode()){
+ m_ModeButton->unplug( toolBar("TorToolBar") );
+ toolBar("TorToolBar")->setIconText( KToolBar::IconOnly, false );
+ m_ModeButton->plug( toolBar("TorToolBar") );
+ toolBar("TorToolBar")->setToggle(toolBar("TorToolBar")->idAt(2),true);
+ toolBar("TorToolBar")->toggleButton(toolBar("TorToolBar")->idAt(2));
+ toolBar("MoreToolBar")->show();
+
+ }else{
+ m_ModeButton->unplug( toolBar("TorToolBar") );
+ toolBar("TorToolBar")->setIconText( KToolBar::IconTextRight, false );
+ m_ModeButton->plug( toolBar("TorToolBar") );
+ toolBar("MoreToolBar")->hide();
+ }
+}
+
+void
+tork::configureServer( int id ) //SLOT
+{
+ kdDebug() << "configuring server" << endl;
+ if ((TorkConfig::runFirstServerWizard()) && (id !=0 && id != 4)){
+ ServerWizard wizard;
+ wizard.setCaption( i18n( "Server Assistant" ));
+ wizard.setServerType(id);
+ connect( &wizard, SIGNAL(setUpServer(int)),this,
+ SLOT(configureServer(int )) );
+
+ wizard.exec();
+ return;
+ }
+ /* We need to let upnp configuration through now, even if settings
+ were not originally applied */
+ m_CanApplyServerSettingsIfSet=true;
+
+ if (id < 4){
+
+ for (unsigned int index = 0; index != 4; ++index){
+ m_ServerButtonMenu->setItemChecked( index, false ); //uncheck old item
+ }
+ m_ServerButtonMenu->setItemChecked( id, true );
+
+ }
+
+ switch(id)
+ {
+ case 0:
+ TorkConfig::setClientOnly(true);
+ if (client != 0L)
+ client->configureServer(upnpORPort(), upnpDirPort());
+ break;
+ case 1:
+ TorkConfig::setClientOnly(false);
+ TorkConfig::setBridgeRelay(false);
+ TorkConfig::setMiddleMan(false);
+ if (client != 0L)
+ client->configureServer(upnpORPort(), upnpDirPort());
+ break;
+ case 2:
+ TorkConfig::setClientOnly(false);
+ TorkConfig::setMiddleMan(true);
+ TorkConfig::setBridgeRelay(false);
+ if (client != 0L)
+ client->configureServer(upnpORPort(), upnpDirPort());
+ break;
+ case 3:
+ TorkConfig::setClientOnly(false);
+ TorkConfig::setMiddleMan(true);
+ TorkConfig::setBridgeRelay(true);
+ if (client != 0L)
+ client->configureServer(upnpORPort(), upnpDirPort());
+ break;
+ case 4:
+ openConfig("My Tor Server");return;
+ case 5:
+ showMyHiddenServices();return;
+ default:
+ break;
+ }
+
+
+ if ((!TorkConfig::clientOnly()) && (TorkConfig::forwardPorts())){
+ // Do we need to forward ports on the router?
+ if (UPnPManager::Manager()->routersDiscovered())
+ configureRouter(false);
+ }
+
+ m_ServerButtonMenu->setItemEnabled( 4, !TorkConfig::clientOnly() );
+ TorkConfig::writeConfig();
+}
+
+void
+tork::configureSecurity( int id ) //SLOT
+{
+
+ if (m_SecurityButtonMenu->isItemChecked( id))
+ return;
+
+ QString cmd;
+ QString iconstring;
+ QString filterRequest;
+
+ filterId = id;
+
+ cmd = createFailSafeCommand(TorkConfig::filterRules(), false);
+ cmd += createFailSafeCommand(TorkConfig::systemFilterRules(), false);
+
+ switch(id)
+ {
+ case 0:
+ iconstring = "tork_penguin";
+ filterRequest = "Normal Mode";
+ break;
+ case 1:
+ cmd += createFailSafeCommand(TorkConfig::filterRules(), true);
+ iconstring = "agent";
+ filterRequest = "DNS FailSafe";
+ break;
+ case 2:
+ cmd += createFailSafeCommand(TorkConfig::filterRules(), true);
+ cmd += createFailSafeCommand(TorkConfig::systemFilterRules(), true);
+ iconstring = "gv";
+ filterRequest = "System FailSafe";
+ break;
+
+ case 3:
+ openConfig("FailSafe");return;
+ default:
+ return;
+ }
+
+ filterError = "";
+ filterWasApplied = false;
+
+ cmd += "echo run";
+
+ filterproc = new KProcIO();
+ filterproc->setUseShell(TRUE);
+ QString filterCommand= QString("kdesu --noignorebutton --miniicon tork --caption '%1' -t -i %2 -d -c "
+ "'%3'").arg(filterRequest).arg(iconstring).arg(cmd);
+ connect( filterproc, SIGNAL(readReady(KProcIO * )),
+ SLOT(processFilter(KProcIO * )) );
+ connect( filterproc, SIGNAL(processExited(KProcess *)),
+ SLOT(filterExited()) );
+
+ *filterproc<<filterCommand;
+ filterproc->start(KProcIO::NotifyOnExit,TRUE);
+
+}
+
+void tork::processFilter(KProcIO *filterproc)
+{
+ QString item = "";
+ int pos;
+
+ while ((pos = (filterproc->readln(item,true))) != -1) {
+ if (item.contains("No chain/target/match by that name"))
+ continue;
+ if (item == "run"){
+ filterWasApplied = true;
+ continue;
+ }
+ filterError += item;
+ }
+ filterproc->ackRead();
+
+}
+
+void tork::filterExited()
+{
+
+ if (!filterError.isEmpty()){
+ processQuestion( "filterfailed", filterError );
+ return;
+ }
+
+ if (!filterWasApplied)
+ return;
+
+ m_view->toggleParanoidMode(filterId);
+
+ if (filterId < 3){
+
+ for (unsigned int index = 0; index != 3; ++index){
+ m_SecurityButtonMenu->setItemChecked( index, false ); //uncheck old item
+ }
+ m_SecurityButtonMenu->setItemChecked( filterId, true );
+
+ }
+
+
+ switch(filterId)
+ {
+ case 0:
+ m_DNSTorified = false;
+ if (client != 0L){
+ client->enableDNS(false);
+ client->enableTransPort(false);
+ }
+ m_SecurityButton->setIconSet(SmallIconSet("tork_penguin"));
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled", i18n("You are now in <b>Normal Mode</b>. <br> Tor and TorK will operate normally."));
+ break;
+ case 1:
+ m_DNSTorified = true;
+ if (client != 0L){
+ client->enableDNS(true);
+ client->enableTransPort(true);
+ }
+ m_SecurityButton->setIconSet(SmallIconSet("tork_agent"));
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled", i18n("You are now in <b>DNS FailSafe Mode</b>. <br> All DNS queries will be routed through Tor."));
+ break;
+ case 2:
+ m_DNSTorified = true;
+ if (client != 0L){
+ client->enableDNS(true);
+ client->enableTransPort(true);
+ }
+ m_SecurityButton->setIconSet(SmallIconSet("gv"));
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled", i18n("You are now in <b>System FailSafe Mode</b>. <br> Tor will use new routes for every new connection as often as possible. <br> All secure traffic will be routed through Tor."));
+ break;
+ default:
+ break;
+ }
+
+ delete filterproc;
+ filterproc = 0L;
+}
+
+QString tork::createFailSafeCommand( const QStringList &filterRules, bool set ) //SLOT
+{
+
+
+ QString cmd;
+ QStringList rules = filterRules;
+ for ( QStringList::Iterator it = rules.begin(); it != rules.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString active = (*it).section("%:%",0,0);
+
+ if (active.contains("button_cancel") && (set))
+ continue;
+
+ QString entry = (*it).section("%:%",2,2);
+ if (set){
+ cmd.append(QString("%1;").arg(entry));
+ }else{
+ cmd.append(QString("%1;").arg(entry.replace(" -I "," -D ")));
+ }
+ }
+
+ return cmd;
+
+}
+
+void
+tork::filterLog( int id ) //SLOT
+{
+ QListViewItemIterator it(m_view->infoList);
+ while ( it.current() ) {
+ it.current()->setVisible(false);
+ ++it;
+ }
+
+ m_LogFilterMenu->setItemChecked( id, !m_LogFilterMenu->isItemChecked(id) ); // Toggle selected item
+
+ filterView(logType, m_view->infoList, m_LogFilterMenu, id, 1);
+}
+
+void
+tork::filterCountries( int id ) //SLOT
+{
+
+ // If 'All' is already selected, return
+ if (countryType[id] == "All"){
+ if (m_CountryMenu->isItemChecked(251))
+ return;
+ m_CountryMenu->setItemChecked( 251, true);
+ }else
+ m_CountryMenu->setItemChecked( 251, false);
+
+
+ // If 'All'is selected, display all entries; otherwise hide all entries
+ QListViewItemIterator it(m_view->serverList);
+ while ( it.current() ) {
+ it.current()->setVisible(m_CountryMenu->isItemChecked(251));
+ ++it;
+ }
+
+ //Re-apply any text filter
+ if ((m_view->serverFilter->isShown()) &&
+ (!m_view->serverFilter->text().isEmpty()))
+ m_view->serverFilter->updateSearch();
+
+
+ // Display servers for each selected country
+ for ( QMap<QString, KPopupMenu*>::Iterator menu = continentMapList.begin();
+ menu != continentMapList.end(); ++menu ){
+ if (m_CountryMenu->isItemChecked(251)){ // If 'All' selected, deselect all items
+ for (unsigned int index = 0; index != menu.data()->count(); ++index){
+ menu.data()->setItemChecked( menu.data()->idAt(index), false );
+ }
+ continue;
+ }
+ menu.data()->setItemChecked( id, !menu.data()->isItemChecked(id) ); // Toggle selected item
+ QListView* tmp = dynamic_cast<QListView*>(m_view->serverList);
+ filterView(countryType, tmp, menu.data(), id, 4);
+ }
+
+
+ //If 'All' type-filter is selected, we are already displaying all servers, so return
+ if ( m_ServerFilterMenu->isItemChecked( 0 )){
+ return;
+ }
+
+ // Of servers displayed above, display only the ones with all selected criteria.
+ QListView* tmp = dynamic_cast<QListView*>(m_view->serverList);
+ filterViewServers(serverCondition, tmp, m_ServerFilterMenu, 99, 3);
+
+}
+
+void
+tork::toggleIP( int id ) //SLOT
+{
+
+ QListViewItemIterator it(m_view->serverList);
+ if (m_ServerFilterMenu->text( id ).contains("IP")) {
+ while ( it.current() ) {
+ it.current()->setText(1,it.current()->text(5));
+ ++it;
+ }
+ m_ServerFilterMenu->changeItem( id, "Show Name" );
+ } else {
+ while ( it.current() ) {
+ it.current()->setText(1,getNickNameFromFPDigest(it.current()->text(2)));
+ ++it;
+ }
+ m_ServerFilterMenu->changeItem( id, "Show IP" );
+ }
+
+}
+void
+tork::filterServers( int id ) //SLOT
+{
+
+ //If 'All' was clicked and is already selected, just return
+ if (serverCondition[id] == "All" && m_ServerFilterMenu->isItemChecked(id))
+ return;
+
+ //Uncheck/Check Selected Item
+ m_ServerFilterMenu->setItemChecked( id, !m_ServerFilterMenu->isItemChecked(id) );
+
+ //If nothing is selected any longer, check 'All'
+ bool somethingchecked = false;
+ for (unsigned int index = 1; index != serverCondition.count(); ++index){
+ if (m_ServerFilterMenu->isItemChecked( index))
+ somethingchecked = true;
+ }
+ if (!somethingchecked){
+ m_ServerFilterMenu->setItemChecked( 0, true );
+ id = 0;
+ }
+
+ //Re-apply any text filter
+ if ((m_view->serverFilter->isShown()) &&
+ (!m_view->serverFilter->text().isEmpty()))
+ m_view->serverFilter->updateSearch();
+
+
+ //We always need to get all servers for selected countries again
+ if (m_CountryMenu->isItemChecked( 251 )){ // If 'All' countries are selected
+
+ QListViewItemIterator it(m_view->serverList);
+ while ( it.current() ) {
+ it.current()->setVisible(true);
+ ++it;
+ }
+
+ }else{
+
+ QListViewItemIterator it(m_view->serverList);
+ while ( it.current() ) {
+ it.current()->setVisible(false);
+ ++it;
+ }
+
+ for ( QMap<QString,
+ KPopupMenu*>::Iterator menu = continentMapList.begin();
+ menu != continentMapList.end(); ++menu ){
+ QListView* tmp = dynamic_cast<QListView*>(m_view->serverList);
+ filterView(countryType, tmp, menu.data(), 255, 4);
+ }
+ }
+
+
+ //If 'All' is selected, just ensure all items are unchecked and return
+ if (serverCondition[id] == "All"){
+
+ for (unsigned int index = 1; index != serverCondition.count(); ++index){
+ m_ServerFilterMenu->setItemChecked( index, false ); //uncheck old item
+ }
+ m_ServerFilterMenu->setItemChecked( id, true );
+ return;
+ }
+
+
+ //Uncheck 'All' to be sure
+ m_ServerFilterMenu->setItemChecked( 0, false );
+
+ // Of servers displayed above, display only the ones with all selected
+ //criteria.
+ QListView* tmp = dynamic_cast<QListView*>(m_view->serverList);
+ filterViewServers(serverCondition, tmp, m_ServerFilterMenu, id, 3);
+}
+
+
+
+void
+tork::filterView( QValueVector<QString> &possibleValues, QListView* &view,
+ KPopupMenu* &menu, int id, int column ){
+
+ if (possibleValues[id] == "All"){
+ QListViewItemIterator it(view);
+ while ( it.current() ) {
+ it.current()->setVisible(true);
+ ++it;
+ }
+
+ for (unsigned int index = 1; index != possibleValues.count(); ++index){
+ menu->setItemChecked( menu->idAt(index), false );
+ }
+ if (menu->findItem(id))
+ menu->setItemChecked( id, true );
+ return;
+ }
+
+ if (continentMapList.values().contains(menu))
+ menu->setItemChecked( 251, false ); //Uncheck 'All' Item
+ else
+ menu->setItemChecked( 0, false ); //Uncheck 'All' Item
+
+ QString check;
+ for (unsigned int index = 0; index != possibleValues.count(); ++index){
+ if (menu->isItemChecked( menu->idAt(index) )){
+ QListViewItemIterator it(view);
+ while ( it.current() ) {
+ if (possibleValues == countryType)
+ check = GeoIP_country_code[it.current()->text(column).toInt()];
+ else
+ check = it.current()->text(column);
+ if (check.contains(possibleValues[menu->idAt(index)]))
+ it.current()->setVisible(true);
+ ++it;
+ }
+ }
+ }
+
+
+}
+
+void
+tork::filterViewServers( QValueVector<QString> &possibleValues,
+ QListView* &view, KPopupMenu* &menu, int ,
+ int column) //SLOT
+{
+
+
+ for (unsigned int index = 0; index != possibleValues.count(); ++index){
+ if (menu->isItemChecked( menu->idAt(index) )){
+ QListViewItemIterator it(view,QListViewItemIterator::Visible);
+ while ( it.current() ) {
+
+ if (!it.current()->text(column)
+ .contains(possibleValues[index]))
+ it.current()->setVisible(false);
+ else
+ it.current()->setVisible(true);
+ ++it;
+ }
+ }
+ }
+
+
+}
+
+void
+tork::createSubnetList( ) //SLOT
+{
+
+ QListViewItem *nextOne;
+ QListViewItem *tm;
+
+ for (QListViewItem *child = m_view->serverList->firstChild(); child;
+ child = nextOne) {
+ nextOne = child->nextSibling();
+
+ QRegExp rx("^[0-9]{1,3}\\.[0-9]{1,3}\\.");
+ rx.search(child->text(5));
+ QString tmp = rx.cap(0);
+ if (tmp.isEmpty()){
+ break;
+ }
+
+ if (!( tm = m_view->serverList->findItem((tmp),0))){
+ tm = new QListViewItem(m_view->serverList, tmp,
+ "a","a","a","a","a");
+ }
+
+ m_view->serverList->takeItem(child);
+ tm->insertItem(child);
+ child->moveItem(tm);
+ }
+
+}
+
+void tork::fileNew()
+{
+ // this slot is called whenever the File->New menu is selected,
+ // the New shortcut is pressed (usually CTRL+N) or the New toolbar
+ // button is clicked
+
+ // create a new window
+ (new tork)->show();
+}
+
+void tork::optionsShowToolbar()
+{
+ // this is all very cut and paste code for showing/hiding the
+ // toolbar
+ if (m_toolbarAction->isChecked())
+ toolBar()->show();
+ else
+ toolBar()->hide();
+
+}
+
+void tork::optionsShowStatusbar()
+{
+ // show/hide the statusbar
+ if (m_statusbarAction->isChecked())
+ statusBar()->show();
+ else
+ statusBar()->hide();
+}
+
+void tork::optionsConfigureKeys()
+{
+ KKeyDialog::configure(actionCollection());
+}
+
+void tork::optionsConfigureToolbars()
+{
+ // use the standard toolbar editor
+ #if defined(KDE_MAKE_VERSION)
+ # if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0)
+ saveMainWindowSettings(KGlobal::config(), autoSaveGroup());
+ # else
+ saveMainWindowSettings(KGlobal::config());
+ # endif
+ #else
+ saveMainWindowSettings(KGlobal::config());
+ #endif
+ KEditToolbar dlg(factory());
+ connect(&dlg,SIGNAL(newToolbarConfig()),this,SLOT(newToolbarConfig()));
+ dlg.exec();
+}
+
+void tork::newToolbarConfig()
+{
+ // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor.
+ // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.)
+ createGUI();
+
+ #if defined(KDE_MAKE_VERSION)
+ # if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0)
+ applyMainWindowSettings(KGlobal::config(), autoSaveGroup());
+ # else
+ applyMainWindowSettings(KGlobal::config());
+ # endif
+ #else
+ applyMainWindowSettings(KGlobal::config());
+ #endif
+
+}
+
+void tork::copyOldConfig()
+{
+
+ TorkConfig::writeConfig();
+ KConfigSkeletonItem::List pitems(TorkConfig::self()->items());
+ KConfigSkeletonItem::List::ConstIterator it;
+ PrevConfig::PrevConfigList::iterator tp;
+
+ for( it = pitems.begin(); it != pitems.end(); ++it ) {
+ if (((TorkConfig::clientOnly())) && ((*it)->group() == "MyServer"))
+ continue;
+ for( tp = prevlist.begin(); tp != prevlist.end(); ++tp ) {
+
+ if ((*tp).name() == (*it)->name()){
+ (*tp).setProperty((*it)->property());
+ continue;
+ }
+ }
+ if ( tp == prevlist.end())
+ prevlist.append(PrevConfig((*it)->name(),(*it)->property()));
+ }
+
+ if (client != 0L)
+ client->updatePrevConfig(prevlist);
+
+
+}
+
+void tork::optionsPreferences()
+{
+ // The preference dialog is derived from prefs-base.ui which is subclassed into Prefs
+ //
+ // compare the names of the widgets in the .ui file
+ // to the names of the variables in the .kcfg file
+
+ copyOldConfig();
+
+
+ TorkConfigDialog* dialog = (TorkConfigDialog*) KConfigDialog::exists( "settings" );
+
+ if( !dialog )
+ {
+
+ //KConfigDialog didn't find an instance of this dialog, so lets create it :
+ dialog = new TorkConfigDialog( this, "settings", TorkConfig::self() );
+
+ }
+
+ //FIXME it seems that if the dialog is on a different desktop it gets lost
+ // what do to? detect and move it?
+
+ if (client != 0L)
+ dialog->m_quickconfig->quickGroup->setEnabled(false);
+ dialog->show();
+ dialog->raise();
+ dialog->setActiveWindow();
+
+}
+
+void tork::openConfig(const QCString& page)
+{
+ copyOldConfig();
+
+ // The preference dialog is derived from prefs-base.ui which is subclassed into Prefs
+ //
+ // compare the names of the widgets in the .ui file
+ // to the names of the variables in the .kcfg file
+ TorkConfigDialog* dialog = (TorkConfigDialog*) KConfigDialog::exists( "settings" );
+
+ if( !dialog )
+ {
+ //KConfigDialog didn't find an instance of this dialog, so lets create it :
+ dialog = new TorkConfigDialog( this, "settings", TorkConfig::self() );
+ }
+
+ //FIXME it seems that if the dialog is on a different desktop it gets lost
+ // what do to? detect and move it?
+
+ if (client != 0L)
+ dialog->m_quickconfig->quickGroup->setEnabled(false);
+
+ dialog->showPage(page);
+ dialog->show();
+ dialog->raise();
+ dialog->setActiveWindow();
+
+
+}
+
+void tork::updateTrayIcon(const QString& iconName)
+{
+ kdDebug() << "show icon " << iconName << endl;
+
+
+ if (iconName.isEmpty())
+ _tray->setPixmap(KSystemTray::loadIcon("tork_little"));
+ else
+ _tray->setPixmap(KSystemTray::loadIcon(iconName));
+
+ if (TorkConfig::clientOnly())
+ return;
+
+ QPixmap icon = KSystemTray::loadIcon( iconName );
+ QPixmap overlay = KSystemTray::loadIcon( "tork_server" );
+
+ if ( !overlay.isNull() )
+ {
+ int x = icon.width() - overlay.width();
+ int y = icon.height() - overlay.height();
+ if ( icon.mask() )
+ {
+ QBitmap mask = *icon.mask();
+ bitBlt( &mask, x, y,
+ overlay.mask() ? const_cast<QBitmap *>(overlay.mask()) : &overlay,
+ 0, 0, overlay.width(), overlay.height(),
+ overlay.mask() ? OrROP : SetROP );
+ icon.setMask(mask);
+ }
+ bitBlt( &icon, x, y, &overlay );
+ }
+
+ _tray->setPixmap(icon);
+
+}
+
+
+void tork::updateTrayStats(const QString& totin,const QString& totout, const QString& in,const QString& out)
+{
+ if (client == 0L)
+ return;
+ QStringList cli = client->currentClientReport();
+ QStringList server = client->currentServerReport();
+ _tray->updateStats(totin, totout, in, out, server, cli,
+ BytesPerSecToString(client->getCurBandwidthRate()));
+
+ QString tmp1 = i18n("Transferred up: %1 / down: %2")
+ .arg(totout)
+ .arg(totin);
+ m_statusTransfer->setText(tmp1);
+ updateServerClientStatusBar(cli,server);
+}
+
+void tork::updateServerClientStatusBar(const QStringList &client, const QStringList &server)
+{
+ static unsigned int iter = 0;
+ unsigned int serverCount = server.count();
+
+ if (iter > serverCount){
+ iter = 0;
+ QString tmp1 = i18n("Client: %1")
+ .arg(client[0]);
+ m_statusInfo->setText(tmp1.replace("<font color='#990000'>","")
+ .replace("</font>",""));
+ }else if (iter == serverCount){
+ m_statusInfo->setText(i18n("%1 servers on network").arg(m_view->serverList->childCount()));
+ iter++;
+ }else{
+ if (TorkConfig::clientOnly()){
+ iter = serverCount;
+ return;
+ }
+ m_statusInfo->setText(QString("Server: %1").arg(server[iter])
+ .replace("<font color='#990000'>","")
+ .replace("</font>",""));
+ iter++;
+ }
+
+}
+
+void tork::changeStatusbar(const QString& in,const QString& out)
+{
+
+ if ((in == "zero") && (out =="zero")){
+ QString tmp1 = i18n("Transferred up: 0 B / down: 0 B");
+ m_statusTransfer->setText(tmp1);
+
+ }
+
+}
+
+void tork::sayWhatImDoing(const QString& text)
+{
+ // display the text on the caption
+ m_statusInfo->setText(text);
+}
+
+void tork::changeCaption(const QString& text)
+{
+ // display the text on the caption
+ setCaption(text);
+}
+
+void tork::startTor()
+{
+
+ m_ShutdownRequested = false;
+
+ if (childproc !=0L)
+ return;
+ m_list.clear();
+
+ if (TorkConfig::torLocation().isEmpty() || (!QFile::exists(TorkConfig::torLocation()))){
+
+ processWarning( "notorexecutable",i18n("You can't find me.") );
+ return;
+ }
+
+
+ sayWhatImDoing("Starting Tor..");
+ childproc = new KProcIO();
+ childproc->setUseShell(TRUE);
+
+ QString torConfFile = writeConf();
+
+
+
+ *childproc << TorkConfig::torLocation() << " -f " + torConfFile;
+
+ connect( childproc, SIGNAL(processExited(KProcess *)),
+ SLOT(childExited()) );
+ connect( childproc, SIGNAL(readReady(KProcIO *)),
+ SLOT(receivedOutput(KProcIO *)) );
+
+ childproc->start(KProcIO::NotifyOnExit) ;
+
+
+}
+
+void tork::stopTorGracefully()
+{
+
+ m_ShutdownRequested = true;
+
+ if (TorkConfig::clientOnly()){
+ stopTor();
+ return;
+ }
+
+ if ((childproc !=0L) && (client != 0L)){
+ client->terminateTor();
+ processQuestion("terminatetor",
+ i18n("Give me 30 seconds to close connections."));
+ }else
+ stopTor();
+
+}
+void tork::stopTor()
+{
+
+ if (m_DNSTorified){
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled", i18n("<b>You are now in FailSafe Mode</b>. <br> You need to be in Normal Mode before you can stop Tor."));
+ return;
+ }
+
+ // start Tor
+ stopController();
+ stopNetStat();
+
+ if (privoxyproc !=0L){
+ privoxyproc->kill();
+ delete privoxyproc;
+ privoxyproc = 0L;
+ }
+
+ if (tfPrivoxy !=0L){
+ delete tfPrivoxy;
+ tfPrivoxy = 0L;
+ }
+
+ if (tfTor !=0L){
+ delete tfTor;
+ tfTor = 0L;
+ }
+
+ if (childproc !=0L){
+ childproc->kill();
+ delete childproc;
+ childproc = 0L;
+ }
+ torkStart->setEnabled(true);
+ m_LaunchMenuButton->setEnabled(false);
+ m_IdentityButton->setEnabled(false);
+ m_PseudoButton->setEnabled(false);
+ m_ServerFilterButton->setEnabled(false);
+ m_ServerButton->setEnabled(false);
+ m_SecurityButton->setEnabled(false);
+
+ //Reset Country filter menu to 'All' checked
+
+ for ( QMap<QString, KPopupMenu*>::Iterator menu = continentMapList.begin(); menu != continentMapList.end(); ++menu ){
+ for (unsigned int index = 0; index != menu.data()->count(); ++index){
+ menu.data()->setItemChecked( menu.data()->idAt(index), false );
+ }
+ }
+ m_CountryMenu->setItemChecked( 251, true );
+
+ //Reset server filter menu to 'All' checked
+ for (unsigned int index = 1; index != serverCondition.count(); ++index){
+ m_ServerFilterMenu->setItemChecked( index, false ); //uncheck old item
+ }
+ m_ServerFilterMenu->setItemChecked( 0, true );
+
+ //Reset Pseudonymity filter menu to 'All' checked
+
+ for ( QMap<QString, KPopupMenu*>::Iterator menu = continentMap.begin(); menu != continentMap.end(); ++menu )
+ {
+ for (unsigned int index = 0; index != menu.data()->count(); ++index){
+ menu.data()->setItemChecked( menu.data()->idAt(index),false);
+ }
+ }
+
+ m_PseudoMenu->setItemChecked(999,true);
+
+ torkStop->setEnabled(false);
+ enableKonqi->setEnabled(false);
+ browseHiddenServices->setEnabled(false);
+ //timer->stop();
+ _tray->setPixmap(KSystemTray::loadIcon("tork_pressplay"));
+ changeStatusbar("zero","zero");
+ turnOffKDE();
+ m_view->m_osd->infoList->clear();
+ m_view->m_osd->hide();
+ sayWhatImDoing(i18n("To connect to Tor, press play."));
+
+ m_view->toggleAnonymizerTork(false);
+
+}
+
+void tork::stopController()
+{
+ m_view->resetBWHistory();
+ m_view->updateChart();
+
+ disconnect( client, SIGNAL(fatalError()),this, SLOT(cannotContactTor()));
+ disconnect( client, SIGNAL(torConnectionClosed()), this, SLOT(torClosedConnection()) );
+ disconnect( client, SIGNAL(streamStatusUpdate(const QString &, const QString &,
+ const QString &, const QString &, const QString &)),
+ m_view,SLOT(streamStatusUpdated(const QString &, const QString &,
+ const QString &, const QString &, const QString &)) );
+ disconnect( client, SIGNAL(ORStatusUpdate(const QString &, const QString &)),
+ m_view,SLOT(ORStatusUpdated(const QString &, const QString &)) );
+ disconnect( client, SIGNAL(guardStatusUpdate(const QString &, const QString &)),
+ m_view,SLOT(guardStatusUpdated(const QString &, const QString &)) );
+ disconnect( client, SIGNAL(circuitStatusUpdate(const QString &, const QString &,
+ const QString &, const QString &)),
+ m_view,SLOT(circuitStatusUpdated(const QString &, const QString &,
+ const QString &, const QString &)) );
+ disconnect( client, SIGNAL(infoUpdate(const QString &,const QString &, const QString &)),
+ this,SLOT(infoUpdated(const QString &,const QString &, const QString &)) );
+ disconnect( client, SIGNAL(bwUpdate(const QString &,const QString &)),
+ m_view,SLOT(bwUpdated(const QString &,const QString &)) );
+ disconnect( client, SIGNAL(streamBwUpdate(const QString &,const QString &,const QString &)),
+ m_view,SLOT(streamBwUpdated(const QString &,const QString &,const QString &)) );
+
+ disconnect( client, SIGNAL(updateActiveServers(const QStringList &)),
+ m_view,SLOT(activeServersUpdated(const QStringList &)) );
+ disconnect( client, SIGNAL(updateServerStatus(const QString &,const QString &,
+ const QString &,const QString &)),
+ m_view,SLOT(serverStatusUpdated(const QString &,const QString &,
+ const QString &,const QString &)) );
+
+ disconnect( client, SIGNAL(setTorCaption(const QString &)),
+ this,SLOT(setTorCaption(const QString &)) );
+
+
+ disconnect(m_view->circuitList, SIGNAL(attach(const QString &,const QString &)),
+ client, SLOT(attemptAttach(const QString &,const QString & )) );
+ disconnect(m_view->circuitList, SIGNAL(extendCircuit(const QString &, const QString &, bool)),
+ client, SLOT(attemptExtendCircuit(const QString &, const QString &, bool)) );
+ disconnect(m_view->circuitList, SIGNAL(createCircuit(const QString &, bool)),
+ client, SLOT(attemptCreateCircuit(const QString &, bool)) );
+
+
+ disconnect( m_view->serverList, SIGNAL(mouseButtonPressed (int, QListViewItem *,
+ const QPoint &, int)), this, SLOT(slotOnItem ( int, QListViewItem *,
+ const QPoint &, int )));
+ disconnect( m_view->ORList, SIGNAL(pressed ( QListViewItem * )), this,
+ SLOT(slotOnORItem ( QListViewItem * )));
+
+
+ disconnect(m_view->m_osd, SIGNAL(closeStream(const QString &)),
+ client, SLOT(attemptCloseStream(const QString & )) );
+ disconnect(m_view, SIGNAL(closeStream(const QString &)),
+ client, SLOT(attemptCloseStream(const QString & )) );
+ disconnect(m_view, SIGNAL(attachStreams(bool)),
+ client, SLOT(attemptAttachStreams( bool )) );
+
+ disconnect(m_view, SIGNAL(closeCircuit(const QString &)),
+ client, SLOT(attemptCloseCircuit(const QString & )) );
+ disconnect(m_view, SIGNAL(closeAllCircuits( QListView* &)),
+ client, SLOT(closeAllCircuits( QListView* & )) );
+
+ disconnect(client, SIGNAL(displayError(const QString &, const QString &)),
+ m_view, SLOT(displayError(const QString &,const QString & )) );
+ disconnect(client, SIGNAL(displayServer(const QString &, const QString &)),
+ m_view, SLOT(displayServer(const QString &,const QString & )) );
+
+ disconnect(client, SIGNAL(whatImDoing(const QString &)),
+ this, SLOT(sayWhatImDoing(const QString & )) );
+ disconnect(client, SIGNAL(copyOldConfig()),
+ this, SLOT(copyOldConfig()) );
+
+ disconnect(client, SIGNAL(shouldIApplySettings()),
+ this, SLOT(shouldIApplySettings()) );
+
+ disconnect(client, SIGNAL(makeTorkStoppable()),
+ this, SLOT(makeTorkStoppable()) );
+
+ disconnect(m_view->streamList, SIGNAL(attach(const QString &,const QString &)),
+ client, SLOT(attemptAttach(const QString &,const QString & )) );
+
+ disconnect(client, SIGNAL(warnNoServerInfo()),
+ this, SLOT(warnNoServerInfo()) );
+
+ disconnect(client, SIGNAL(needAlphaVersion()),
+ this, SLOT(needAlphaVersion()) );
+
+ disconnect(client, SIGNAL(connectedToTor()),
+ client, SLOT(authenticate()) );
+
+ disconnect(m_view, SIGNAL(updateExcludeNodes()),
+ client, SLOT(updateExcludeNodes()) );
+ disconnect(m_view, SIGNAL(updateEntryNodes()),
+ client, SLOT(updateEntryNodes()) );
+ disconnect(m_view, SIGNAL(updateExitNodes()),
+ client, SLOT(updateExitNodes()) );
+ disconnect(m_view, SIGNAL(clearNodes()),
+ client, SLOT(clearNodes()) );
+ disconnect(m_view, SIGNAL(updateStrictExitNodes(bool)),
+ client, SLOT(strictExitNodes(bool)) );
+ disconnect(m_view, SIGNAL(safeLogging(bool)),
+ client, SLOT(safeLogging(bool)) );
+
+ disconnect( m_view, SIGNAL(signalCheckTorNet()),
+ client, SLOT( slotCheckTorNet() ) );
+ disconnect( m_view, SIGNAL(signalCheckGuards()),
+ client, SLOT( slotCheckGuards() ) );
+ disconnect( m_view, SIGNAL(signalCheckBWSettings()),
+ this, SLOT( checkBandwidthSettings() ) );
+
+ disconnect(client, SIGNAL(processWarning(const QString& , const QString& )),
+ this, SLOT(processWarning(const QString& , const QString& )));
+ disconnect(client, SIGNAL(processQuestion(const QString& , const QString& )),
+ this, SLOT(processQuestion(const QString& , const QString& )));
+
+ disconnect(client, SIGNAL(updateTrayIcon(const QString&)),
+ this, SLOT(updateTrayIcon(const QString&)));
+
+ disconnect( client, SIGNAL(showServerBW(const QString&)),
+ m_view, SLOT( showServerBW(const QString&) ) );
+
+ disconnect( m_view, SIGNAL(resolveAddress(const QString&)),
+ client, SLOT( resolveAddress(const QString&) ) );
+
+ disconnect( client, SIGNAL(resolvedAddress(const QString&)),
+ m_view, SLOT( resolvedAddress(const QString&) ) );
+
+ if (bwtimer != 0L){
+ disconnect( bwtimer, SIGNAL( timeout() ), m_view, SLOT( reportBW() ) );
+ delete bwtimer;
+ bwtimer = 0L;
+ }
+ if (bwLimitTimer != 0L){
+ disconnect( bwLimitTimer, SIGNAL( timeout() ), this, SLOT( checkBandwidthSettings() ) );
+ delete bwLimitTimer;
+ bwLimitTimer = 0L;
+ }
+
+ if (client != 0L){
+ client->cleanUp();
+ client->socketReadyRead();
+ client->deleteLater();
+ client = 0L;
+ }
+ _tray->setPixmap(KSystemTray::loadIcon("tork_pressplay"));
+
+ m_view->circuitList->clear();
+ m_view->ORList->clear();
+ m_view->serverList->clear();
+ m_view->streamList->clear();
+ m_list.clear();
+ m_view->clearStreamMaps();
+
+ setCaption("");
+
+ TorkConfig::setCurrentExcludeNodes("");
+ TorkConfig::setCurrentEntryNodes("");
+ TorkConfig::setCurrentExitNodes("");
+ TorkConfig::writeConfig();
+
+ m_CanApplyServerSettingsIfSet=false;
+
+ _tray->updateStats(BytesPerSecToString(0),BytesPerSecToString(0),
+ BytesPerSecToString(0),BytesPerSecToString(0),
+ QStringList("<font color='#990000'>Status Not Known</font>"),
+ QStringList("<font color='#990000'>Status Not Known</font>"),
+ BytesPerSecToString(0));
+}
+
+
+QString tork::writeConf()
+{
+ if (tfTor != 0L)
+ delete tfTor;
+
+ tfTor = new KTempFile();
+ tfTor->setAutoDelete(true);
+ if ( tfTor->status() != 0 ) {
+ tfTor->close();
+ KMessageBox::information (this,"KMFilterActionWithCommand: Could not create temp file!");
+ return QString();
+ }
+
+
+ QTextStream &ts = *(tfTor->textStream());
+
+ switch (TorkConfig::quickConfigure()) {
+ case 0 : //Tor client and server with default settings
+ configureServer(1);
+ ts << "ContactInfo " << TorkConfig::contactInfo() << "\n";
+ ts << "ControlPort " << TorkConfig::controlPort() << "\n";
+ ts << "NickName " << TorkConfig::nickName() << "\n";
+ ts << "ORPort " << upnpORPort() << "\n";
+ ts << "ORListenAddress 0.0.0.0:" << TorkConfig::oRListenAddress() << "\n";
+ ts << "DirPort " << upnpDirPort() << "\n";
+ ts << "DirListenAddress 0.0.0.0:" << TorkConfig::dirListenAddress() << "\n";
+ ts << "CookieAuthentication " << TorkConfig::cookieAuthentication() << "\n";
+ break;
+ case 1 : //Tor client and relay server with default settings
+ configureServer(2);
+ ts << "ContactInfo " << TorkConfig::contactInfo() << "\n";
+ ts << "ControlPort " << TorkConfig::controlPort() << "\n";
+ ts << "NickName " << TorkConfig::nickName() << "\n";
+ ts << "ORPort " << upnpORPort() << "\n";
+ ts << "ORListenAddress 0.0.0.0:" << TorkConfig::oRListenAddress() << "\n";
+ ts << "DirPort " << upnpDirPort() << "\n";
+ ts << "DirListenAddress 0.0.0.0:" << TorkConfig::dirListenAddress() << "\n";
+ if (TorkConfig::middleMan()){
+ ts << "ExitPolicy reject *:*\n";
+ }
+ ts << "CookieAuthentication " << TorkConfig::cookieAuthentication() << "\n";
+ break;
+
+ case 2 : //Tor server with default settings
+ configureServer(1);
+ ts << "ContactInfo " << TorkConfig::contactInfo() << "\n";
+ ts << "ControlPort " << TorkConfig::controlPort() << "\n";
+ ts << "NickName " << TorkConfig::nickName() << "\n";
+ ts << "ORPort " << upnpORPort() << "\n";
+ ts << "ORListenAddress 0.0.0.0:" << TorkConfig::oRListenAddress() << "\n";
+ ts << "DirPort " << upnpDirPort() << "\n";
+ ts << "DirListenAddress 0.0.0.0:" << TorkConfig::dirListenAddress() << "\n";
+ ts << "CookieAuthentication " << TorkConfig::cookieAuthentication() << "\n";
+ break;
+
+ case 3 : //Tor relay server with default settings
+ configureServer(2);
+ ts << "ContactInfo " << TorkConfig::contactInfo() << "\n";
+ ts << "ControlPort " << TorkConfig::controlPort() << "\n";
+ ts << "NickName " << TorkConfig::nickName() << "\n";
+ ts << "ORPort " << upnpORPort() << "\n";
+ ts << "ORListenAddress 0.0.0.0:" << TorkConfig::oRListenAddress() << "\n";
+ ts << "DirPort " << upnpDirPort() << "\n";
+ ts << "DirListenAddress 0.0.0.0:" << TorkConfig::dirListenAddress() << "\n";
+ if (TorkConfig::middleMan()){
+ ts << "ExitPolicy reject *:*\n";
+ }
+ ts << "CookieAuthentication " << TorkConfig::cookieAuthentication() << "\n";
+ break;
+
+ case 4 : //Tor client with default settings
+ configureServer(0);
+ ts << "ControlPort " << TorkConfig::controlPort() << "\n";
+ ts << "CookieAuthentication " << TorkConfig::cookieAuthentication() << "\n";
+ break;
+
+
+ case 5 : //Use custom settings
+ ts << "ContactInfo " << TorkConfig::contactInfo() << "\n";
+ ts << "NickName " << TorkConfig::nickName() << "\n";
+ ts << "ControlPort " << TorkConfig::controlPort() << "\n";
+ writeCustomOptions2(ts);
+ break;
+ }
+
+ if (TorkConfig::useProxy()){
+ if ((TorkConfig::httpProxyPort() > 0) && (!TorkConfig::httpProxyHost().isEmpty()))
+ ( ts << "HttpProxy " << TorkConfig::httpProxyHost() << ":"
+ << TorkConfig::httpProxyPort() << "\n") ;
+ if ((TorkConfig::httpsProxyPort() > 0) && (!TorkConfig::httpsProxyHost().isEmpty()))
+ ( ts << "HttpsProxy " << TorkConfig::httpsProxyHost() << ":"
+ << TorkConfig::httpsProxyPort() << "\n") ;
+
+ if ((!TorkConfig::httpProxyAuthenticatorUserName().isEmpty()) &&
+ (!TorkConfig::httpProxyAuthenticatorPassword().isEmpty()))
+ (ts << "HttpProxyAuthenticator " << TorkConfig::httpProxyAuthenticatorUserName()
+ << ":" << TorkConfig::httpProxyAuthenticatorPassword() << "\n");
+
+ if ((!TorkConfig::httpsProxyAuthenticatorUserName().isEmpty()) &&
+ (!TorkConfig::httpsProxyAuthenticatorPassword().isEmpty()))
+ (ts << "HttpsProxyAuthenticator " << TorkConfig::httpsProxyAuthenticatorUserName()
+ << ":" << TorkConfig::httpsProxyAuthenticatorPassword() << "\n");
+ }
+
+ tfTor->close();
+
+ return tfTor->name();
+
+}
+
+void tork::writeCustomOptions2(QTextStream &ts)
+{
+
+ //Add any new servers to excludeNodes that we want excluded by Country
+ QStringList existingServers = TorkConfig::serversHistory();
+ QStringList currentExcludeNodes = TorkConfig::excludeNodes();
+ for ( QStringList::Iterator it = existingServers.begin(); it != existingServers.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+
+ int cc = (*it).section("-",0,0).toInt();
+ QString nick = (*it).section("-",1);
+
+ QString fp = getFPFromFPDigest(nick);
+ if (fp.isEmpty())
+ continue;
+
+ if ((!TorkConfig::excludeNodes().contains("$"+fp)) &&
+ (TorkConfig::excludeCountries().contains(GeoIP_country_code[cc])))
+ currentExcludeNodes.append("$"+fp);
+ }
+ if (!currentExcludeNodes.isEmpty()){
+ TorkConfig::setExcludeNodes(currentExcludeNodes);
+ }
+
+
+ KConfigSkeletonItem::List items = TorkConfig::self()->items();
+ KConfigSkeletonItem::List::ConstIterator it;
+ for( it = items.begin(); it != items.end(); ++it ) {
+ kdDebug() << (*it)->name() << endl;
+ if (elementShouldBeUsed((*it))){
+ if (noSpecialProcessing((*it), ts)){
+ if ( (*it)->property().type() == QVariant::String ) {
+ if (!((*it)->property().toString()).isEmpty()){
+ ( ts << (*it)->name() << " " << (*it)->property().toString() << "\n");
+ kdDebug() << (*it)->name() << " " << (*it)->property().toString() << endl;
+ }
+ }else if ( (*it)->property().type() == QVariant::StringList ) {
+ if (!((*it)->property().toStringList()).isEmpty()){
+ ( ts << (*it)->name() << " " << (*it)->property().toStringList().join(",")
+ << "\n");
+ }
+ }else if ( (*it)->property().type() == QVariant::Int ) {
+ if (((*it)->property().toInt()) > 0){
+ ( ts << (*it)->name() << " " << (*it)->property().toString() << "\n");
+ kdDebug() << (*it)->name() << " " << (*it)->property().toString() << endl;
+ }
+ }else if ( (*it)->property().type() == QVariant::Bool ) {
+ if (((*it)->property().toInt()) > 0){
+ ( ts << (*it)->name() << " " << (*it)->property().toInt() << "\n");
+ kdDebug() << (*it)->name() << " " << (*it)->property().toInt() << endl;
+ }
+ }
+
+ }
+ }
+ //if ( p.type() == QVariant::Bool ) {
+ }
+
+
+ if ((!TorkConfig::sOCKSBindAddressHost().isEmpty()) && (TorkConfig::sOCKSBindAddressPort() > -1))
+ ( ts << "SOCKSListenAddress " << TorkConfig::sOCKSBindAddressHost() << ":" << TorkConfig::sOCKSBindAddressPort() <<"\n") ;
+
+ if ((TorkConfig::sOCKSBindAddressHost().isEmpty()) && (TorkConfig::sOCKSBindAddressPort() > -1))
+ ( ts << "SOCKSPort " << TorkConfig::sOCKSBindAddressPort() <<"\n") ;
+
+}
+
+bool tork::elementShouldBeUsed(const KConfigSkeletonItem* it)
+{
+
+
+ if ((((!TorkConfig::defaultMaxMinOptions())) && ((*it).group() == "MaxMin")) ||
+ (((!TorkConfig::defaultRunningNormalOptions())) && ((*it).group() == "RunningNormal")) ||
+ ((!(TorkConfig::clientOnly())) && ((*it).group() == "DefaultServerAddress")) ||
+ ((TorkConfig::fascistFirewall()) && ((*it).group() == "FirewallEvasion")) ||
+ ((TorkConfig::useBridges()) && ((*it).group() == "Censorship")) ||
+ (((*it).group() == "RunningSpecial")) ||
+ (((*it).group() == "Servers")) ||
+ ((!(TorkConfig::clientOnly())) && ((*it).group() == "MyServer")) ||
+ (((*it).group() == "Usability")) ||
+ (((*it).group() == "UsingTor")) ||
+ (((*it).group() == "MyHiddenServices")) ||
+ ((!(TorkConfig::defaultServerPerformance())) && ((*it).group() == "ServerPerformance")))
+ return true;
+
+
+ return false;
+}
+
+bool tork::noSpecialProcessing(const KConfigSkeletonItem* it, QTextStream &ts)
+{
+
+ if (((*it).name() == "DirListenAddress") ||
+ ((*it).name() == "ORListenAddress")){
+ ( ts << (*it).name() << "0.0.0.0:" <<
+ (*it).property().toString() << "\n");
+ return false;
+ }
+
+ if (((*it).name() == "BandwidthBurst") ||
+ ((*it).name() == "BandwidthRate")){
+ ( ts << (*it).name() << " " << (*it).property().toString() << "KB\n");
+ return false;
+ }
+
+ if ((*it).name() == "MaxAdvertisedBandwidth"){
+ ( ts << (*it).name() << " " << (*it).property().toString() << "KB\n");
+ return false;
+ }
+
+ if ((*it).name() == "AccountingMax"){
+ ( ts << (*it).name() << " " << ((*it).property().toInt() * 1024 * 1024) << "bytes\n");
+ return false;
+ }
+
+ if ((*it).name() == "AccountingStart"){
+ if ((*it).property().toString() == "day")
+ ( ts << (*it).name() << " " << (*it).property().toString() << " 00:00\n");
+ else
+ ( ts << (*it).name() << " " << (*it).property().toString() << " 1 00:00\n");
+ return false;
+ }
+
+
+ if ((*it).name() == "KeepalivePeriod"){
+ if (!TorkConfig::reachableAddresses().isEmpty()){
+ ( ts << (*it).name() << " " << ((*it).property().toInt() * 60) << "\n") ;
+ }
+ return false;
+ }
+
+ if ((*it).name() == "TrackHostExits"){
+ if (!TorkConfig::trackHostExits().isEmpty()){
+ ( ts << (*it).name() << " " << ((*it).property().toStringList().join(",")) << "\n") ;
+ if (TorkConfig::trackHostExitsExpire() > 0)
+ ( ts << "TrackHostExitsExpire " << (TorkConfig::trackHostExitsExpire() * 60) << "\n") ;
+ }
+ return false;
+ }
+
+
+ if ((*it).name() == "SOCKSBindAddressMany"){
+
+ if (!TorkConfig::sOCKSBindAddressMany().isEmpty()){
+ QStringList socksbind = TorkConfig::sOCKSBindAddressMany();
+ for ( QStringList::Iterator it = (socksbind).begin(); it != (socksbind).end(); it++ )
+ {
+ if ((*it).isEmpty())
+ continue;
+ ts << "SOCKSListenAddress " << (*it) << "\n" ;
+ }
+ }
+ return false;
+ }
+
+ if ((*it).name() == "HashedControlPassword"){
+ if (!TorkConfig::hashedControlPassword().isEmpty()){
+ QString hash = hashPassword(TorkConfig::hashedControlPassword());
+ if(!hash.isEmpty())
+ ts << "HashedControlPassword 16:" << hash << "\n" ;
+ }
+ return false;
+ }
+
+
+ if ((*it).name() == "ExitPolicy"){
+ if (TorkConfig::middleMan())
+ ts << "ExitPolicy " << "reject *:*" << "\n" ;
+ else
+ ts << "ExitPolicy " << (*it).property().toStringList().join(",") << "\n" ;
+ return false;
+ }
+
+ if ((*it).name() == "HiddenServices"){
+ QStringList hiddenServices = TorkConfig::hiddenServices();
+ for ( QStringList::Iterator it = (hiddenServices).begin(); it != (hiddenServices).end(); it++ )
+ {
+ if ((*it).isEmpty())
+ continue;
+ ts << "HiddenServiceDir " << (*it).section("\n",-1) << "\n" ;
+ ts << "HiddenServicePort " << (*it).section("\n",-4,-4) << " " << (*it).section("\n",-3,-3) << "\n";
+ }
+ return false;
+ }
+
+ if ((*it).name() == "Bridge"){
+
+ QStringList bridges = TorkConfig::bridge();
+ for ( QStringList::Iterator it = (bridges).begin(); it != (bridges).end(); it++ )
+ {
+ if ((*it).isEmpty())
+ continue;
+ ts << "Bridge " << (*it) << "\n";
+ }
+
+ return false;
+ }
+
+ if ((*it).name() == "MyFamily"){
+
+ QStringList family = TorkConfig::myFamily();
+ QStringList allfamily;
+ for ( QStringList::Iterator it = (family).begin(); it != (family).end(); it++ )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString node = "$"+getFPFromFPDigest((*it).section("-",1,1));
+ allfamily.append(node) ;
+ }
+ ts << "MyFamily " << allfamily.join(",") << "\n";
+
+ return false;
+ }
+
+ if ((*it).name() == "MapAddress"){
+ QStringList maps = TorkConfig::mapAddress();
+ for ( QStringList::Iterator it = (maps).begin();
+ it != (maps).end(); it++ )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString mapAddress = QString("\"%2\"").arg((*it));
+ ts << "MapAddress " << mapAddress << "\n";
+ }
+ return false;
+ }
+
+ return true;
+}
+
+
+QString tork::doHashPassword()
+{
+
+ hashproc = new KProcIO();
+ hashproc->setUseShell(TRUE);
+ m_hashedpassword = "";
+ QString hashCommand=QString("tor --hash-password %1").arg(TorkConfig::hashedControlPassword());
+
+ *hashproc<<hashCommand;
+
+ connect( hashproc, SIGNAL(readReady(KProcIO * )),
+ SLOT(processHashProc(KProcIO * )) );
+ hashproc->start(KProcIO::NotifyOnExit,TRUE);
+
+ while (hashproc->isRunning() && m_hashedpassword.isEmpty())
+ kapp->processEvents();
+
+ return m_hashedpassword;
+}
+
+void tork::processHashProc(KProcIO *hashproc)
+{
+ QString item = "";
+ int pos;
+
+ while ((pos = (hashproc->readln(item,true))) != -1) {
+ if (item.startsWith("16:"))
+ m_hashedpassword = item;
+ }
+ hashproc->ackRead();
+
+}
+
+
+
+
+
+void tork::childExited()
+{
+
+ delete childproc;
+ childproc = 0L;
+ torkStart->setEnabled(true);
+ m_LaunchMenuButton->setEnabled(false);
+ m_IdentityButton->setEnabled(false);
+ m_PseudoButton->setEnabled(false);
+ m_ServerFilterButton->setEnabled(false);
+ m_ServerButton->setEnabled(false);
+ m_SecurityButton->setEnabled(false);
+
+ torkStop->setEnabled(false);
+ enableKonqi->setEnabled(false);
+ browseHiddenServices->setEnabled(false);
+ sayWhatImDoing(i18n("To connect to Tor, press play."));
+
+ turnOffKDE();
+
+
+
+}
+
+void tork::privoxyExited()
+{
+
+ bool died = false;
+ if ((privoxyproc->normalExit()) || (privoxyproc->signalled()))
+ died = true;
+
+ if (privoxyproc != 0L){
+ disconnect( privoxyproc, SIGNAL(processExited(KProcess *)),
+ this,SLOT(privoxyExited()) );
+ delete privoxyproc;
+ privoxyproc = 0L;
+ }
+
+ QString question;
+ if (stillStarting)
+ question = "privoxycouldntstart";
+ else
+ question = "privoxydied";
+
+ if (died)
+ processQuestion( question, i18n("Nothing.") );
+
+
+}
+
+void tork::startEverything()
+{
+
+ if (client != 0L)
+ return;
+
+ m_showstopperAlreadyDisplayed = false;
+
+ switch (TorkConfig::quickConfigure()) {
+ case 0 :
+ case 1 :
+ case 2 :
+ case 3 :
+ case 4 :
+ case 5 :
+ /* This allows upnp/server configuration if we are starting a
+ server */
+ m_CanApplyServerSettingsIfSet=true;
+ startNetStat();
+ startPrivoxy();
+ startTor();
+ break;
+ case 6 :
+ startNetStat();
+ startController();
+ break;
+ case 7 :
+ startNetStat();
+ startPrivoxy();
+ startController();
+ break;
+ default:
+ return;
+ }
+}
+
+void tork::checkForSystemManagedPrivoxy()
+{
+ QString host;
+ int port;
+
+ host = TorkConfig::konqHttpProxy();
+ port = TorkConfig::konqHttpProxyPort();
+ host = host.replace("http://","");
+
+ if (privoxytest == 0L) {
+ privoxytest = new TestPrivoxy();
+ connect( privoxytest, SIGNAL(fatalError()),this, SLOT(cannotContactPrivoxy()));
+ connect( privoxytest, SIGNAL(connectedToPrivacyProxy()),
+ this, SLOT(privacyProxyPassed()) );
+ }
+ privoxytest->connectTo(host,port);
+
+}
+
+void tork::cannotContactPrivoxy()
+{
+
+ processQuestion("privoxynotrunning",i18n("Is your privacy proxy running?"));
+ privoxytest->closeConnection();
+}
+
+void tork::privacyProxyPassed()
+{
+
+ privoxytest->closeConnection();
+}
+
+void tork::letTorKManagePrivoxy()
+{
+ TorkConfig::setSystemProxy(false);
+ TorkConfig::setTorkProxy(true);
+ TorkConfig::writeConfig();
+ startPrivoxy();
+}
+
+void tork::startPrivoxy()
+{
+
+ stillStarting = true;
+ QTimer::singleShot( 20000, this, SLOT(startingPeriodOver()) );
+
+ if (TorkConfig::systemProxy()) {
+ checkForSystemManagedPrivoxy();
+ return;
+ }
+
+ if (TorkConfig::privoxyLocation().isEmpty()){
+
+ processWarning( "noprivoxyexecutable", i18n("You can't find Privoxy."));
+ return;
+ }
+
+ if (privoxyproc != 0L){
+ disconnect( privoxyproc, SIGNAL(processExited(KProcess *)),
+ this,SLOT(privoxyExited()) );
+ delete privoxyproc;
+ privoxyproc = 0L;
+ }
+
+ privoxyproc = new KProcIO();
+ privoxyproc->setUseShell(TRUE);
+
+ QString curpath = (QString) getenv("PATH");
+ privoxyproc->setEnvironment("PATH",curpath +
+ ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin");
+
+ QString location = getenv("HOME");
+ location += "/.tork";
+ QDir torkdir(location);
+ if (!torkdir.exists() && !torkdir.mkdir(location))
+ location = getenv("HOME");
+
+ QString privoxypid = QString("%1/.tork/privoxypid").arg(location);
+ QString privoxyConfFile = writePrivoxyConf();
+ *privoxyproc << TorkConfig::privoxyLocation() << " --user " << getenv("USER")
+ << " --no-daemon --pidfile " << privoxypid << " " << privoxyConfFile;
+
+ connect( privoxyproc, SIGNAL(processExited(KProcess *)),
+ SLOT(privoxyExited()) );
+
+ privoxyproc->start(KProcIO::NotifyOnExit) ;
+
+
+}
+
+
+void tork::startingPeriodOver()
+{
+ stillStarting = false;
+}
+
+QString tork::writePrivoxyConf()
+{
+
+ if (tfPrivoxy != 0L)
+ delete tfPrivoxy;
+
+ tfPrivoxy = new KTempFile();
+ tfPrivoxy->setAutoDelete(true);
+ if ( tfPrivoxy->status() != 0 ) {
+ tfPrivoxy->close();
+ KMessageBox::information (this,"KMFilterActionWithCommand: Could not create temp file!");
+ return "";
+ }
+
+
+ QTextStream &ts = *(tfPrivoxy->textStream());
+
+ ts << "forward-socks4a / " << TorkConfig::sOCKSBindAddressHost() << ":"
+ << TorkConfig::sOCKSBindAddressPort() << " ." << "\n";
+ ts << "confdir " << locate("data","tork/privoxy/") << "\n";
+ ts << "logdir ." << "\n";
+ ts << "listen-address " << TorkConfig::konqHttpProxy().replace("http://","") << ":"
+ << TorkConfig::konqHttpProxyPort() << "\n";
+ ts << "debug 1 # URLs" << "\n";
+ ts << "debug 4096 # Info" << "\n";
+ ts << "debug 8192 # Errors - *we highly recommended enabling this*" << "\n";
+ ts << "toggle 1" << "\n";
+ ts << "buffer-limit 4069" << "\n";
+ ts << "forward 192.168.*.*/ ." << "\n";
+ ts << "forward 10.*.*.*/ ." << "\n";
+ ts << "forward 127.*.*.*/ ." << "\n";
+
+// Following two config lines removed because of:
+// http://archives.seul.org/or/talk/Oct-2007/msg00291.html
+// ts << "enable-edit-actions 1" << "\n";
+// ts << "enable-remote-toggle 1" << "\n";
+
+ tfPrivoxy->close();
+
+ return tfPrivoxy->name();
+
+}
+
+void tork::startController()
+{
+
+
+ QString host;
+ int port;
+
+ if (TorkConfig::quickConfigure() == 6){
+ host = TorkConfig::remoteTorAddress();
+ port = TorkConfig::remoteTorPort();
+ }else if (TorkConfig::quickConfigure() == 7){
+ host = "localhost";
+ port = TorkConfig::remoteTorPort();
+ }else{
+ host = "localhost";
+ port = TorkConfig::controlPort();
+ }
+ torCaption = QString("%1:%2").arg(host).arg(port);
+ client = new TorClient(host,port);
+ setCaption(torCaption);
+
+ connect( client, SIGNAL(fatalError()),this, SLOT(cannotContactTor()));
+ connect( client, SIGNAL(torConnectionClosed()), SLOT(torClosedConnection()) );
+ connect( client, SIGNAL(streamStatusUpdate(const QString &, const QString &,
+ const QString &, const QString &, const QString &)),
+ m_view,SLOT(streamStatusUpdated(const QString &, const QString &,
+ const QString &, const QString &, const QString &)) );
+ connect( client, SIGNAL(ORStatusUpdate(const QString &, const QString &)),
+ m_view,SLOT(ORStatusUpdated(const QString &, const QString &)) );
+ connect( client, SIGNAL(guardStatusUpdate(const QString &, const QString &)),
+ m_view,SLOT(guardStatusUpdated(const QString &, const QString &)) );
+ connect( client, SIGNAL(circuitStatusUpdate(const QString &, const QString &,
+ const QString &, const QString &)),
+ m_view,SLOT(circuitStatusUpdated(const QString &, const QString &,
+ const QString &, const QString &)) );
+ connect( client, SIGNAL(infoUpdate(const QString &,const QString &, const QString &)),
+ this,SLOT(infoUpdated(const QString &,const QString &, const QString &)) );
+ connect( client, SIGNAL(bwUpdate(const QString &,const QString &)),
+ m_view,SLOT(bwUpdated(const QString &,const QString &)) );
+ connect( client, SIGNAL(streamBwUpdate(const QString &,const QString &,const QString &)),
+ m_view,SLOT(streamBwUpdated(const QString &,const QString &,const QString &)) );
+
+ connect( client, SIGNAL(updateActiveServers(const QStringList &)),
+ m_view,SLOT(activeServersUpdated(const QStringList &)) );
+ connect( client, SIGNAL(updateServerStatus(const QString &,const QString &,
+ const QString &,const QString &)),
+ m_view,SLOT(serverStatusUpdated(const QString &,const QString &,
+ const QString &,const QString &)) );
+
+ connect( client, SIGNAL(setTorCaption(const QString &)),
+ this,SLOT(setTorCaption(const QString &)) );
+
+
+ connect(m_view->circuitList, SIGNAL(attach(const QString &,const QString &)),
+ client, SLOT(attemptAttach(const QString &,const QString & )) );
+ connect(m_view->circuitList, SIGNAL(extendCircuit(const QString &, const QString &, bool)),
+ client, SLOT(attemptExtendCircuit(const QString &, const QString &, bool)) );
+ connect(m_view->circuitList, SIGNAL(createCircuit(const QString &, bool)),
+ client, SLOT(attemptCreateCircuit(const QString &, bool)) );
+
+ connect( m_view->serverList, SIGNAL(mouseButtonPressed ( int, QListViewItem * ,
+ const QPoint &, int )),
+ SLOT(slotOnItem ( int, QListViewItem * , const QPoint &, int )));
+ connect( m_view->ORList, SIGNAL(pressed ( QListViewItem * )),
+ SLOT(slotOnORItem ( QListViewItem * )));
+
+
+ connect(m_view->m_osd, SIGNAL(closeStream(const QString &)),
+ client, SLOT(attemptCloseStream(const QString & )) );
+ connect(m_view, SIGNAL(closeStream(const QString &)),
+ client, SLOT(attemptCloseStream(const QString & )) );
+ connect(m_view, SIGNAL(attachStreams(bool)),
+ client, SLOT(attemptAttachStreams( bool )) );
+
+ connect(m_view, SIGNAL(closeCircuit(const QString &)),
+ client, SLOT(attemptCloseCircuit(const QString & )) );
+ connect(m_view, SIGNAL(closeAllCircuits( QListView* &)),
+ client, SLOT(closeAllCircuits( QListView* & )) );
+
+ connect(client, SIGNAL(displayError(const QString &, const QString &)),
+ m_view, SLOT(displayError(const QString &,const QString & )) );
+ connect(client, SIGNAL(displayServer(const QString &, const QString &)),
+ m_view, SLOT(displayServer(const QString &,const QString & )) );
+
+ connect(client, SIGNAL(whatImDoing(const QString &)),
+ this, SLOT(sayWhatImDoing(const QString & )) );
+ connect(client, SIGNAL(copyOldConfig()),
+ this, SLOT(copyOldConfig()) );
+
+ connect(client, SIGNAL(shouldIApplySettings()),
+ this, SLOT(shouldIApplySettings()) );
+
+ connect(client, SIGNAL(makeTorkStoppable()),
+ this, SLOT(makeTorkStoppable()) );
+
+ connect(m_view->streamList, SIGNAL(attach(const QString &,const QString &)),
+ client, SLOT(attemptAttach(const QString &,const QString & )) );
+
+ connect(client, SIGNAL(warnNoServerInfo()),
+ this, SLOT(warnNoServerInfo()) );
+
+ connect(client, SIGNAL(needAlphaVersion()),
+ this, SLOT(needAlphaVersion()) );
+
+ connect(client, SIGNAL(connectedToTor()),
+ client, SLOT(authenticate()) );
+
+ connect(m_view, SIGNAL(updateExcludeNodes()),
+ client, SLOT(updateExcludeNodes()) );
+ connect(m_view, SIGNAL(updateEntryNodes()),
+ client, SLOT(updateEntryNodes()) );
+ connect(m_view, SIGNAL(updateExitNodes()),
+ client, SLOT(updateExitNodes()) );
+ connect(m_view, SIGNAL(clearNodes()),
+ client, SLOT(clearNodes()) );
+ connect(m_view, SIGNAL(updateStrictExitNodes(bool)),
+ client, SLOT(strictExitNodes(bool)) );
+ connect(m_view, SIGNAL(safeLogging(bool)),
+ client, SLOT(safeLogging(bool)) );
+
+ connect( m_view, SIGNAL(signalCheckTorNet()),
+ client, SLOT( slotCheckTorNet() ) );
+ connect( m_view, SIGNAL(signalCheckGuards()),
+ client, SLOT( slotCheckGuards() ) );
+ connect( m_view, SIGNAL(signalCheckBWSettings()),
+ this, SLOT( checkBandwidthSettings() ) );
+
+ connect(client, SIGNAL(processWarning(const QString& , const QString& )),
+ this, SLOT(processWarning(const QString& , const QString& )));
+ connect(client, SIGNAL(processQuestion(const QString& , const QString& )),
+ this, SLOT(processQuestion(const QString& , const QString& )));
+
+ connect(client, SIGNAL(updateTrayIcon(const QString&)),
+ this, SLOT(updateTrayIcon(const QString&)));
+
+ connect( client, SIGNAL(showServerBW(const QString&)),
+ m_view, SLOT( showServerBW(const QString&) ) );
+
+ connect( m_view, SIGNAL(resolveAddress(const QString&)),
+ client, SLOT( resolveAddress(const QString&) ) );
+
+ connect( client, SIGNAL(resolvedAddress(const QString&)),
+ m_view, SLOT( resolvedAddress(const QString&) ) );
+
+ QTimer::singleShot( 10000, this, SLOT(isControllerWorking()) );
+
+ torkStart->setEnabled(false);
+ m_view->welcomeitem->setEnabled(false);
+ _tray->setPixmap(KSystemTray::loadIcon("tork_green"));
+
+ if( TorkConfig::alwaysAnonymizeKDE())
+ enableKDE(true);
+ else
+ TorkConfig::setKDEUsesTor(false);
+
+ TorkConfig::setCurrentExcludeNodes("");
+ TorkConfig::setCurrentEntryNodes("");
+ TorkConfig::setCurrentExitNodes("");
+ TorkConfig::writeConfig();
+
+ updateServerButton();
+
+#ifndef EXTERNAL_GEOIP
+ geoip_db = !locate("data", "tork/geoip/GeoIP.dat").isNull();
+#else
+ GeoIP * gi = 0;
+ gi = GeoIP_new(GEOIP_STANDARD);
+ if (gi)
+ geoip_db = true;
+ else
+ geoip_db = false;
+#endif
+
+ client->setGeoIPAvailable(geoip_db);
+ m_view->setGeoIPAvailable(geoip_db);
+
+ if (!geoip_db)
+ processWarning("geoipmissing",i18n("Your GeoIP installation is broken."));
+
+}
+
+void tork::makeTorkStoppable()
+{
+
+ torkStop->setEnabled(true);
+ m_LaunchMenuButton->setEnabled(true);
+ m_IdentityButton->setEnabled(true);
+ m_PseudoButton->setEnabled(true);
+ m_ServerFilterButton->setEnabled(true);
+ toggleServerButton(TorkConfig::useBridges());
+ m_SecurityButton->setEnabled(true);
+
+ enableKonqi->setEnabled(true);
+ browseHiddenServices->setEnabled(true);
+ sayWhatImDoing("Ready for use.");
+ m_view->toggleAnonymizerTork(true);
+
+}
+
+void tork::startFromBeginning()
+{
+ stopController();
+ startTor();
+}
+
+
+void tork::receivedOutput(KProcIO *)
+{
+ int pos;
+ QString item2;
+
+ if (!(childproc))
+ return;
+
+
+ while ((childproc) && ((pos = (childproc->readln(item2,true))) != -1)) {
+ if ((pos = (item2.find("Opening Control listener on"))) != -1){
+ QTimer::singleShot( 200, this, SLOT(startController()) );
+ }
+ int i;
+ for (i = 0; _tork_messages[i].logmessage; ++i) {
+ message_t *msg = &_tork_messages[i];
+ if (item2.contains(msg->logmessage)){
+ if ((*this.*(msg->pt2Member))()){
+ strncpy(msg->torsaid,item2,249);
+ showWarning(msg->state, msg->headline, item2, msg->body, msg->type,
+ msg->icon, msg->always, msg->showstopper);
+ }
+ }
+
+ }
+
+ for (i = 0; _tork_questions[i].logquestion; ++i) {
+ question_t *msg = &_tork_questions[i];
+ if (item2.contains(msg->logquestion)){
+ if ((*this.*(msg->pt2Member2))()){
+ (*this.*msg->silentAction)();
+ strncpy(msg->torsaid,item2,249);
+ askQuestion(msg->state, msg->headline, msg->torsaid, msg->body,
+ msg->question,msg->pt2Member, msg->type, msg->icon,
+ msg->persistent, msg->showstopper);
+ }
+ }
+
+ }
+
+ item2 = "";
+
+
+ }
+
+
+}
+
+void tork::infoUpdated(const QString &type, const QString &summary, const QString &data)
+{
+
+ int i;
+ for (i = 0; _tork_messages[i].logmessage; ++i) {
+ message_t *msg = &_tork_messages[i];
+ if (summary.contains(msg->logmessage)){
+ if ((*this.*(msg->pt2Member))()){
+ strncpy(msg->torsaid,summary,249);
+ showWarning(msg->state, msg->headline, summary, msg->body,
+ msg->type,msg->icon, msg->always, msg->showstopper);
+ }
+ }
+
+ }
+
+ for (i = 0; _tork_questions[i].logquestion; ++i) {
+ question_t *msg = &_tork_questions[i];
+ if (summary.contains(msg->logquestion)){
+ if ((*this.*(msg->pt2Member2))()){
+ (*this.*msg->silentAction)();
+ strncpy(msg->torsaid,summary,249);
+ askQuestion(msg->state, msg->headline, msg->torsaid, msg->body,
+ msg->question,msg->pt2Member, msg->type,msg->icon,
+ msg->persistent, msg->showstopper);
+ }
+ }
+
+ }
+ m_view->infoUpdated(type,summary,data);
+
+ if (waitingForServers){
+ if (summary.contains("now have enough directory information")){
+ waitingForServers = false;
+ //QTimer::singleShot(20000, client, SLOT(slotCheckTorNet()) );
+ if (client != 0L)
+ client->slotCheckTorNet();
+ }
+ }
+}
+
+bool tork::showUsage()
+{
+ return TorkConfig::showUsageWarnings();
+}
+
+bool tork::showSecurityWarnings()
+{
+ return TorkConfig::showSecurityWarnings();
+}
+
+bool tork::showGuideQuestions()
+{
+ return TorkConfig::showGuideQuestions();
+}
+
+bool tork::showApplySettingsQuestions()
+{
+ return TorkConfig::showApplySettingsQuestions();
+}
+
+bool tork::showDNSLeaks()
+{
+ return TorkConfig::showDNSLeaks();
+}
+
+bool tork::contactInfoSet()
+{
+ if ((TorkConfig::showGuideQuestions()) && (TorkConfig::contactInfo().isEmpty()))
+ return true;
+ return false;
+}
+
+void tork::continueAsClient()
+{
+
+ TorkConfig::setQuickConfigure(1);
+ startFromBeginning();
+
+}
+
+void tork::reconnectWithCookie()
+{
+
+ TorkConfig::setCookieAuthentication(1);
+ startEverything();
+
+}
+
+void tork::copyCookie()
+{
+
+ KProcIO *catproc = new KProcIO();
+ catproc->setUseShell(TRUE);
+ QString whichCommand= QString(
+ "kdesu -c '"
+ "mkdir -p -m 600 %1/.tor;"
+ "cp -u /var/lib/tor/control_auth_cookie %2/.tor/control_auth_cookie;"
+ "cp -u /usr/local/var/lib/tor/control_auth_cookie %3/.tor/control_auth_cookie;"
+ "chown -R %4 %5/.tor/;"
+ "chown %6 %7/.tor/control_auth_cookie"
+ "'").arg(getenv("HOME")).arg(getenv("HOME")).arg(getenv("HOME"))
+ .arg(getenv("USER")).arg(getenv("HOME"))
+ .arg(getenv("USER")).arg(getenv("HOME"));
+
+ *catproc<<whichCommand;
+ catproc->start(KProcIO::NotifyOnExit,TRUE);
+
+}
+
+void tork::shouldIApplySettings()
+{
+
+ disconnect(client, SIGNAL(shouldIApplySettings()),
+ this, SLOT(shouldIApplySettings()) );
+
+ switch (TorkConfig::quickConfigure()) {
+ case 0 :
+ case 1 :
+ case 2 :
+ case 3 :
+ case 4 :
+ case 5 :
+ break;
+ case 6 :
+ case 7 :
+ if (!TorkConfig::showApplySettingsQuestions()){
+ applySettingsToRunningTor();
+ return;
+ }
+ processQuestion( "applysettings", i18n("Nothing.") );
+ break;
+ default:
+ break;
+ }
+
+ makeTorkStoppable();
+
+}
+
+void tork::applySettingsToRunningTor()
+{
+ m_CanApplyServerSettingsIfSet=true;
+ kdDebug() << "applying settings" << endl;
+ if (client != 0L){
+ sayWhatImDoing("Applying settings to Tor..");
+ client->applySettingsToRunningTor();
+ }
+ if (client != 0L){
+ //We're setting the server config here. The server values aren't used if we're 'client only'.
+ //It needs to be called so that the sys tray icon reflects our choice of server vs client.
+ client->configureServer(upnpORPort(), upnpDirPort());
+ }
+ // Do we need to forward ports on the router?
+ if (m_routerDiscovered)
+ configureRouter(true,true);
+}
+
+void tork::updateTork()
+{
+ if (!updater)
+ updater = new TorkUpdate(this);
+ updater->checkForNewTorkDirectly();
+
+}
+
+void tork::updateTorStable()
+{
+
+ if (!updater)
+ updater = new TorkUpdate(this);
+ updater->checkForNewTorDirectly(false);
+
+}
+
+void tork::updateTorUnstable()
+{
+ if (!updater)
+ updater = new TorkUpdate(this);
+ updater->checkForNewTorDirectly(true);
+
+}
+
+void tork::updatePrivoxy()
+{
+ if (!updater)
+ updater = new TorkUpdate(this);
+ updater->checkForNewPrivoxyDirectly();
+
+}
+
+void tork::assignPortToRemove()
+{
+ if (client != 0L)
+ client->assignPortToRemove();
+}
+
+void tork::allowPlainTextPorts()
+{
+ if (client != 0L)
+ client->allowPlainTextPorts();
+}
+
+void tork::runWizard()
+{
+
+ if (!client){
+ FirstRunWizard wizard;
+ wizard.setCaption( i18n( "First-Run Wizard" ));
+ wizard.exec();
+ m_view->welcomeitem->score->setCurrentItem(TorkConfig::quickConfigure());
+ }else{
+ processWarning( "torrunning",i18n("You should only run the set-up wizard while TorK is not connected.") );
+ }
+}
+
+
+void tork::turnOffKDE()
+{
+ setKDE(false);
+}
+
+void tork::toggleTorBar()
+{
+ TorkConfig::setShowTorBar(!TorkConfig::showTorBar());
+
+ if (TorkConfig::showTorBar())
+ m_view->frame4->show();
+ else
+ m_view->frame4->hide();
+}
+
+void tork::toggleTorMon()
+{
+ m_view->setShowTormon(!m_view->getShowTormon());
+ bool tormon = m_view->getShowTormon();
+ TorkConfig::setShowTorMon(tormon);
+ if (tormon){
+ if (m_view->streamList->childCount() == 0)
+ m_view->m_osd->hide();
+ else
+ m_view->m_osd->show();
+ }else{
+ m_view->m_osd->hide();
+ }
+
+}
+
+void tork::toggleTorMon2()
+{
+ toggleTorMon();
+ toolBar("TorToolBar")->toggleButton(toolBar("TorToolBar")->idAt(0));
+
+}
+
+void tork::mixminionHome()
+{
+
+ KURL url = "http://www.mixminion.net";
+ kapp->invokeBrowser(url.url(), "0");
+}
+
+void tork::hiddenServices()
+{
+
+ KURL url = "tor://nnqtnsoohprzqcke.onion";
+ kapp->invokeBrowser(url.url(), "0");
+}
+
+void tork::networkList()
+{
+
+ KURL url = "http://torstatus.blutmagie.de/";
+ kapp->invokeBrowser(url.url(), "0");
+}
+
+void tork::toggleKDESetting()
+{
+ TorkConfig::setKDEUsesTor(!TorkConfig::kDEUsesTor());
+ setKDE(TorkConfig::kDEUsesTor());
+
+ if (TorkConfig::kDEUsesTor())
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled", i18n("All <b>Konqueror</b> Sessions Are Now Safe for Anonymous Use. <br> <b>Amarok, Akregator, KTorrent should be treated with caution! </b><br> This is because they may have javascript/java/plugins/flash enabled."));
+ else
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled", i18n("<b>Konqueror</b> is Now Back to "
+ "Non-Anonymous Use! <br> Close Konqueror completely and do not use it non-anonymously for a while. <br>"
+ "This is because malicious websites could gain access to information from your anonymous "
+ "session."));
+
+}
+
+void tork::enableKDE(bool enable)
+{
+ TorkConfig::setKDEUsesTor(enable);
+ setKDE(TorkConfig::kDEUsesTor());
+
+ if (TorkConfig::kDEUsesTor())
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled", i18n("All <b>Konqueror</b> Sessions Are Now Safe for Anonymous Use. <br> <b>Amarok, Akregator, KTorrent should be treated with caution! </b><br> This is because they may have javascript/java/plugins/flash enabled."));
+ else
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled", i18n("<b>Konqueror</b> is Now Back to "
+ "Non-Anonymous Use! <br>Close Konqueror completely and do not use it non-anonymously for a while. <br>"
+ "This is because malicious websites could gain access to information from your anonymous "
+ "session."));
+
+}
+
+void tork::toggleKDESettingAndLaunchKonq()
+{
+ toggleKDESetting();
+
+ if (TorkConfig::kDEUsesTor()){
+
+ KRun::runCommand( "konqueror --caption \"Anonymous Browsing Session\" "
+ "http://healthcheck.anonymityanywhere.com/",
+ "konqueror", "konqueror" );
+
+
+ }
+}
+
+void tork::enableKDEAndLaunchKonqWithUrl(const QString &url)
+{
+ if (!TorkConfig::kDEUsesTor())
+ toggleKDESetting();
+
+ if (TorkConfig::kDEUsesTor()){
+
+ KRun::runCommand( QString("konqueror --caption \"Anonymous Browsing Session\" "
+ "%1").arg(url),
+ "konqueror", "konqueror" );
+ }
+}
+
+bool tork::getKDESetting()
+{
+ return TorkConfig::kDEUsesTor();
+}
+
+void tork::setKDE(bool set)
+{
+
+ if (!m_view->konqitem)
+ return;
+
+ KConfig* config = new KConfig("kioslaverc", false, false);
+ config->setGroup( "Proxy Settings" );
+ if (set){
+ config->writeEntry( "httpProxy", QString("%1:%2")
+ .arg(TorkConfig::konqHttpProxy())
+ .arg(TorkConfig::konqHttpProxyPort()) );
+ config->writeEntry( "httpsProxy", QString("%1:%2")
+ .arg(TorkConfig::konqHttpsProxy())
+ .arg(TorkConfig::konqHttpsProxyPort()) );
+ config->writeEntry( "ftpProxy", QString("%1:%2")
+ .arg(TorkConfig::konqFtpProxy())
+ .arg(TorkConfig::konqFtpProxyPort()) );
+ config->writeEntry( "ProxyType", "1" );
+ config->sync();
+ config = new KConfig("kcookiejarrc", false, false);
+ config->setGroup( "Cookie Policy" );
+ //KConfig doesn't return a bool, just a text representation of the bool
+ TorkConfig::setOriginalCookies(config->readEntry( "Cookies" )
+ == "true" ? true : false);
+ config->writeEntry( "Cookies", !TorkConfig::disableCookies() );
+ TorkConfig::writeConfig();
+ config->sync();
+ config = new KConfig("kio_httprc", false, false);
+ TorkConfig::setOriginalUseCache(config->readEntry( "UseCache" )
+ == "true" ? true : false);
+ TorkConfig::setOriginalSendUserAgent(config->readEntry("SendUserAgent" )
+ == "true" ? true : false);
+ config->writeEntry( "UseCache", !TorkConfig::disableCaching() );
+ config->writeEntry( "SendUserAgent",
+ !TorkConfig::disableBrowserIdentification() );
+ TorkConfig::writeConfig();
+ config->sync();
+ config = new KConfig("konquerorrc", false, false);
+ config->setGroup( "Java/JavaScript Settings" );
+ TorkConfig::setOriginalEnableJavascript(config->readEntry( "EnableJavaScript" )
+ == "true" ? true : false);
+ TorkConfig::setOriginalEnableJava(config->readEntry( "EnableJava" )
+ == "true" ? true : false);
+ TorkConfig::setOriginalEnablePlugins(config->readEntry( "EnablePlugins" )
+ == "true" ? true : false);
+ TorkConfig::writeConfig();
+ config->writeEntry( "EnableJavaScript",!TorkConfig::disableJava());
+ config->writeEntry( "EnableJava", !TorkConfig::disableJava() );
+ config->writeEntry( "EnablePlugins", !TorkConfig::disableJava() );
+ config->sync();
+ }else{
+ config->writeEntry( "httpProxy", TorkConfig::originalHttpProxy() );
+ config->writeEntry( "httpsProxy", TorkConfig::originalHttpsProxy() );
+ config->writeEntry( "ftpProxy", TorkConfig::originalFtpProxy() );
+ config->writeEntry( "ProxyType", TorkConfig::originalProxyType() );
+ config->sync();
+
+ config = new KConfig("kcookiejarrc", false, false);
+ config->setGroup( "Cookie Policy" );
+ config->writeEntry( "Cookies", TorkConfig::originalCookies() );
+ config->sync();
+
+ config = new KConfig("kio_httprc", false, false);
+ config->writeEntry( "UseCache", TorkConfig::originalUseCache() );
+ config->writeEntry( "SendUserAgent", TorkConfig::originalSendUserAgent() );
+ config->sync();
+ kdDebug() << "UseCache" << config->readEntry( "UseCache" )
+ << endl;
+
+ config = new KConfig("konquerorrc", false, false);
+ config->setGroup( "Java/JavaScript Settings" );
+ config->writeEntry( "EnableJavaScript", TorkConfig::originalEnableJavascript() );
+ config->writeEntry( "EnableJava", TorkConfig::originalEnableJava() );
+ config->writeEntry( "EnablePlugins", TorkConfig::originalEnablePlugins() );
+
+ }
+ config->sync();
+
+ // Inform all running io-slaves about the changes...
+ // if we cannot update, ioslaves inform the end user...
+ if (!DCOPRef("*", "KIO::Scheduler").send("reparseSlaveConfiguration", QString::null))
+ {
+ QString caption = i18n("Update Failed");
+ QString message = i18n("You have to restart the running applications "
+ "for these changes to take effect.");
+ KMessageBox::information (this, message, caption);
+ return;
+ }
+ DCOPRef("konqueror*", "KonquerorIface").send("reparseConfiguration");
+
+
+ if (set){
+ enableKonqi->setIcon("tork_konqueroroff");
+ m_view->m_osd->toggleKDE->setIconSet(SmallIconSet( "tork_konqueroroff"));
+ m_view->konqitem->setIcon("tork_konqueror_stop");
+ m_view->konqitem->icon->repaint();
+ m_view->konqitem->setDescriptionText("<qt>"+
+ i18n("<b>Anonymous Browsing is now enabled.</b> "
+ "Click the icon to disable it.<br>"
+ "- You can toggle this setting at any time "
+ "using the konqueror icon in the toolbar or "
+ "the miniview.<br>"
+ )+"</qt>");
+
+
+
+ if (TorkConfig::torkProxy()){
+ m_view->configurePriv->setEnabled(true);
+ m_view->configurePrivText->setEnabled(true);
+ }
+
+ }else{
+ enableKonqi->setIcon("tork_konqueroron");
+ m_view->m_osd->toggleKDE->setIconSet(SmallIconSet( "tork_konqueroron"));
+ m_view->konqitem->setIcon("tork_konqueror_play");
+ m_view->konqitem->setDescriptionText("<qt>"+
+ i18n("<b>Click the icon to launch an anonymous "
+ "browsing session. </b><br>"
+ )+"</qt>");
+ m_view->konqitem->setPropertiesText("<qt>"+i18n(
+ "- Konqueror uses Privoxy in combination with Tor to "
+ "anonymize your browsing. <br>"
+ "- This will also make any other Konqueror sessions you "
+ "use anonymous. <br>"
+ "- It will <b>partially</b> anonymize applications "
+ "such as <b>KTorrent (tracker/search only)</b> and "
+ "<b>Amarok</b>. <br>"
+ "&nbsp;&nbsp;This is because they may still "
+ "have java/javascript enabled, which can compromise "
+ "anonymity. <br>"
+ "- You can toggle this setting at any time using "
+ "the Konqueror icon in the toolbar or the miniview.<br>"
+ )+"</qt>");
+
+
+
+ if (TorkConfig::torkProxy()){
+ m_view->configurePriv->setEnabled(false);
+ m_view->configurePrivText->setEnabled(false);
+ }
+
+ }
+
+
+}
+
+
+void tork::checkForKonqWindow(WId id)
+{
+
+ if (KWin::WindowInfo(id,0,0).name().contains("Anonymous Browsing Session"))
+ KWin::setIcons(id,SmallIcon("tork"),SmallIcon("tork"));
+
+}
+
+void tork::showWarning( display_status_t &msg, const QString &headline,const QString &torsaid,const QString &thismeans, const QString &type, const QString &icon, bool always, bool showstopper)
+{
+
+ kdDebug() << "in showwarning" << endl;
+
+ if (m_showstopperAlreadyDisplayed)
+ return;
+
+ if (m_list.contains(thismeans) && !always)
+ return;
+
+ if (m_toolTipShowing){
+ msg = DISPLAY_QUEUED;
+ return;
+ }
+
+ m_showstopperAlreadyDisplayed = showstopper;
+
+ if (!headline.contains("You May Be Leaking DNS Requests!") &&
+ !headline.contains("TorK has reset the bandwidth rates on Tor as per your instructions!"))
+ m_body = thismeans;
+ else
+ m_body = "";
+
+ m_toolTipShowing = true;
+ m_msg = &msg;
+
+ m_tooltip = new KDE::PopupMessage(statusBar(), m_statusInfo, 40000, type );
+ QString text = i18n( "<b>%1</b>").arg(headline);
+ text += QString( "<br>" ) + i18n( "<b>Message: </b> %1" ).arg(torsaid);
+ text += QString( "<br>" ) + i18n( "<b>This means: </b> %1" ).arg(thismeans);
+ text += QString( "<br>" );
+
+ //connect(m_tooltip, SIGNAL(yesClicked()),this, SLOT(serverHelp()));
+
+ connect(m_tooltip, SIGNAL(noClicked( )), SLOT(noClicked( )));
+ connect(m_tooltip, SIGNAL(Closed( )), SLOT(popUpClosed( )));
+
+ m_tooltip->showOkButton( true );
+ m_tooltip->showCounter( true );
+ m_tooltip->setMaskEffect( KDE::PopupMessage::Slide );
+ m_tooltip->setText( text );
+
+ //QString icon = QString("tork_%1").arg(type).replace(" ","_");
+ m_tooltip->setImage( DesktopIcon( icon, 48 ) );
+
+ m_tooltip->move( x(), y() + m_tooltip->height() );
+
+ m_tooltip->display();
+
+ if (!kmain->isActiveWindow()){
+
+ KPassivePopup *pop;
+
+ QPoint pnt;
+ pop = new KPassivePopup( kmain->_tray );
+ pnt = kmain->_tray->pos();
+ pop->setTimeout(15000);
+ pop->setView( i18n("%1").arg(headline),i18n("See TorK window for details.") );
+ pop->show(QPoint(pnt));
+ }
+
+
+}
+
+void tork::askQuestion(display_status_t &msg, const QString &headline,const QString &torsaid,const QString &body,const QString &question,void (tork::*pt2Func)(), const QString &type, const QString &icon, bool persistent, bool showstopper)
+{
+
+ kdDebug() << "in askqeustion" << endl;
+
+ if (m_showstopperAlreadyDisplayed)
+ return;
+
+ if (m_list.contains(body))
+ return;
+
+ if (m_toolTipShowing){
+ msg = DISPLAY_QUEUED;
+ return;
+ }
+
+ m_showstopperAlreadyDisplayed = showstopper;
+
+ m_body = body;
+ m_toolTipShowing = true;
+ m_msg = &msg;
+ m_persistent = persistent;
+
+ m_pt2Func = pt2Func;
+ m_tooltip = new KDE::PopupMessage(statusBar(), m_statusInfo, 40000, type );
+ QString text = i18n( "<b>%1</b>").arg(headline);
+ text += QString( "<br>" ) + i18n( "<b>Message: </b> %1" ).arg(torsaid);
+ text += QString( "<br>" ) + i18n( "<b>Reason: </b> %1" ).arg(body);
+ text += QString( "<br>" ) + i18n( "%1" ).arg(question);
+
+ //damn. functions pointers can't be used in slots. i don't have the heart to unroll it atm.
+ connect(m_tooltip, SIGNAL(yesClicked( )), SLOT(slotHandle( )));
+ connect(m_tooltip, SIGNAL(noClicked( )), SLOT(noClicked( )));
+ connect(m_tooltip, SIGNAL(Closed( )), SLOT(popUpClosed( )));
+
+
+ m_tooltip->showBothButton( true );
+ m_tooltip->showCounter( true );
+ m_tooltip->setMaskEffect( KDE::PopupMessage::Slide );
+ m_tooltip->setText( text );
+ //QString icon = QString("tork_%1").arg(type).replace(" ","_").replace("'","");
+ m_tooltip->setImage( DesktopIcon( icon, 48 ) );
+
+ m_tooltip->move( x(), y() + m_tooltip->height() );
+
+ m_tooltip->display();
+
+ if (!kmain->isActiveWindow()){
+
+ KPassivePopup *pop;
+
+ QPoint pnt;
+ pop = new KPassivePopup( kmain->_tray );
+ pnt = kmain->_tray->pos();
+ pop->setTimeout(15000);
+ pop->setView( i18n("%1").arg(headline),i18n("%1 See TorK window for details.").arg(body) );
+ pop->show(QPoint(pnt));
+ }
+
+
+}
+
+
+void tork::slotHandle()
+{
+ kdDebug() << "in slothandle" << endl;
+ (*this.*m_pt2Func)();
+ if (!m_body.isEmpty() && !m_persistent)
+ m_list.append( m_body );
+ processQueue( );
+}
+
+void tork::noClicked()
+{
+ kdDebug() << "innoclicked" << endl;
+ if (!m_body.isEmpty() && !m_persistent)
+ m_list.append( m_body );
+ processQueue( );
+}
+
+
+void tork::popUpClosed()
+{
+ kdDebug() << "in popupclosed" << endl;
+ processQueue();
+}
+
+void tork::processQueue()
+{
+
+ kdDebug() << "in processqueue" << endl;
+ m_toolTipShowing = false;
+ *m_msg = DISPLAY_NONE;
+
+ int i;
+ for (i = 0; _tork_questions[i].logquestion; ++i) {
+ question_t *msg = &_tork_questions[i];
+ if (msg->state == DISPLAY_QUEUED){
+ (*this.*msg->silentAction)();
+ askQuestion(msg->state, msg->headline, msg->torsaid, msg->body,
+ msg->question,msg->pt2Member, msg->type,msg->icon,
+ msg->persistent, msg->showstopper);
+ return;
+ }else
+ strcpy(msg->torsaid,"");
+
+ }
+
+ for (i = 0; _tork_messages[i].logmessage; ++i) {
+ message_t *msg = &_tork_messages[i];
+ if (msg->state == DISPLAY_QUEUED){
+ showWarning(msg->state, msg->headline, msg->torsaid, msg->body,
+ msg->type, msg->icon,msg->always, msg->showstopper);
+ return;
+ }else
+ strcpy(msg->torsaid,"");
+ }
+
+
+}
+
+
+void tork::serverHelp()
+{
+
+ KURL url = "http://tork.sourceforge.net/wiki/index.php/FAQ#Tor.2FTorK_say_my_server_isn.27t_reachable._What_do_I_do.3F";
+ kapp->invokeBrowser(url.url(), "0");
+
+}
+
+
+void tork::readEavesdropping()
+{
+
+ KURL url = "http://tork.sourceforge.net/wiki/index.php/FAQ#Is_Tor_more_secure_than_ordinary_internet_use.3F";
+ kapp->invokeBrowser(url.url(), "0");
+
+}
+
+void tork::aboutTorify()
+{
+
+ KURL url = "http://tork.sourceforge.net/wiki/index.php/FAQ#How_do_I_use_TorK_to_anonymize_applications.3F";
+ kapp->invokeBrowser(url.url(), "0");
+
+}
+
+void tork::aboutTor()
+{
+
+ IntroWizard wizard;
+ wizard.setCaption( i18n( "Introduction To TorK" ));
+ wizard.exec();
+
+}
+
+void tork::configurePrivoxy()
+{
+
+ KURL url = "http://config.privoxy.org";
+ kapp->invokeBrowser(url.url(), "0");
+
+}
+
+void tork::aboutParanoidMode()
+{
+
+ KURL url = "http://tork.sourceforge.net/wiki/index.php/FAQ#What_is_.27Paranoid_Mode.27.3F";
+ kapp->invokeBrowser(url.url(), "0");
+
+}
+
+void tork::enterContactInfo()
+{
+
+ openConfig("My Tor Server");
+
+}
+
+void tork::cannotContactTor()
+{
+
+ stopTor();
+
+ processQuestion( "cannotcontacttor", i18n("Nothing. TorK tried to connect to Tor and failed.") );
+
+
+}
+
+void tork::torClosedConnection()
+{
+
+
+ if (m_DNSTorified){
+ KNotifyClient::event(kmain->_tray->winId(),"TorDisabled",
+ i18n("<b>You are still in"
+ " FailSafe Mode</b>. <br> If Tor is still running its capacity to route FailSafe traffic <br> will"
+ " remain enabled. Enter your password to return <br> the rest of your system to Normal Mode."));
+ configureSecurity(0);
+ m_DNSTorified = false;
+ }
+
+ stopTor();
+
+ if (!m_ShutdownRequested)
+ processWarning( "torclosedconnection",
+ i18n("Did something happen to me?") );
+
+ return;
+
+
+}
+
+void tork::quickConfig()
+{
+ openConfig("Quick Configure");
+
+}
+
+void tork::fixAddressPort()
+{
+ TorkConfig::setQuickConfigure(7);
+ TorkConfig::writeConfig();
+ startEverything();
+
+}
+
+void tork::slotOnItem( int button, QListViewItem * item, const QPoint &, int)
+{
+
+ if ((item == NULL) || (button == 2))
+ return;
+ if (client != 0L)
+ client->fetchServerInfo(item->text(2));
+ m_prevItem = item;
+
+}
+
+void tork::slotOnORItem( QListViewItem * item)
+{
+
+ if (item == NULL)
+ return;
+ if (client != 0L)
+ client->fetchServerInfoByNick(item->text(1));
+ m_prevItem = item;
+
+}
+
+void tork::slotOffItem( )
+{
+
+ m_view->hidePopup( );
+}
+
+void tork::isControllerWorking( )
+{
+ if (!client)
+ return;
+
+ if (!client->isControllerWorking()){
+
+ processQuestion( "jdsklajdkslajdskla", i18n("TorK can't communicate with Tor on the controller port %1. Do you have something limiting/blocking traffic on that port?").arg(TorkConfig::controlPort()) );
+ QTimer::singleShot( 10000, this, SLOT(isControllerWorking()) );
+
+ }
+
+}
+
+void tork::warnNoServerInfo( )
+{
+ processWarning( "we have none",i18n("I don't have a list of any servers yet!") );
+ waitingForServers = true;
+
+}
+
+void tork::needAlphaVersion( )
+{
+ processQuestion( "needalpha",i18n("The feature it needs is available in 0.1.2.6 alpha and forward!") );
+ waitingForServers = true;
+
+}
+
+void tork::showTip()
+{
+ KTipDialog::showTip(this,QString::null,true);
+}
+
+void tork::showTipOnStart()
+{
+ KTipDialog::showTip(this);
+}
+
+
+void tork::startNetStat()
+{
+
+ // Don't log netstat traffic if the feature is disabled or we are running a relay
+ if (!TorkConfig::logNonTorTraffic()
+ || !TorkConfig::clientOnly())
+ return;
+
+ netstatproc = new KProcIO();
+ netstatproc->setUseShell(TRUE);
+
+ QString netstatcmd = "netstat -ntucpe";
+ if (!TorkConfig::netstatLocation().isEmpty())
+ netstatcmd = QString("%1 -ntucpe").arg(TorkConfig::netstatLocation());
+
+ *netstatproc << netstatcmd;
+
+ connect( netstatproc, SIGNAL(processExited(KProcess *)),
+ SLOT(netStatExited()) );
+ connect( netstatproc, SIGNAL(readReady(KProcIO *)),
+ SLOT(receivedNetStatOutput(KProcIO *)) );
+
+ netstatproc->start(KProcIO::NotifyOnExit) ;
+
+}
+
+void tork::stopNetStat()
+{
+
+ if (netstatproc !=0L){
+ netstatproc->kill();
+ delete netstatproc;
+ netstatproc = 0L;
+ }
+
+}
+
+void tork::netStatExited()
+{
+
+ delete netstatproc;
+ netstatproc = 0L;
+}
+
+
+void tork::receivedNetStatOutput(KProcIO *)
+{
+ int pos;
+ QString item2;
+
+ // Don't print netstat output if we are running a relay
+ if (!TorkConfig::clientOnly())
+ return;
+
+ if (!(netstatproc))
+ return;
+
+
+ while ((netstatproc) && ((pos = (netstatproc->readln(item2,true))) != -1)) {
+ QString foreignAddress = item2.mid(44,24);
+ QString state = item2.mid(68,11);
+ QString inode = item2.mid(90,11);
+ QString program = item2.mid(102,19).stripWhiteSpace();
+ QListViewItem* nonTorTrafficLine;
+
+ uint tmpents = TorkConfig::nonTorTrafficMaxEntries();
+ if (inodes.count() > tmpents){
+ inodes.clear();
+ m_view->NonTorTraffic->clear();
+
+ }
+ if (program.isEmpty())
+ program = "unknown";
+
+ if (foreignAddress.contains("*:*"))
+ continue;
+ if (foreignAddress.contains("127.0.0.1"))
+ continue;
+ if ((!item2.left(3).contains("tcp")) && (!item2.left(3).contains("udp")))
+ continue;
+
+ QListViewItem* ba = inodes.find( inode );
+
+ if (ba)
+ continue;
+
+
+ nonTorTrafficLine = new QListViewItem(m_view->NonTorTraffic,QDateTime::currentDateTime ().toString(Qt::ISODate).replace("T"," "), foreignAddress,program,inode);
+ inodes.insert( inode, nonTorTrafficLine );
+ QString cleanedTarget = foreignAddress.section(":",0,0).stripWhiteSpace();
+ QString cleanedPort = foreignAddress.section(":",1,1).stripWhiteSpace();
+ QString iconPath = locate("cache", KMimeType::favIconForURL("http://"+cleanedTarget)+".png");
+
+ if (!iconPath.isEmpty()){
+ nonTorTrafficLine->setPixmap( 1, QPixmap( iconPath ) );
+ }else{
+ int i;
+ for (i = 0; _port_icon[i].port; ++i) {
+ portsandicons_t *pics = &_port_icon[i];
+ if (cleanedPort == pics->port){
+ nonTorTrafficLine->setPixmap( 1, SmallIcon(pics->icon) );
+ }
+ }
+ }
+
+ if (program.endsWith("/tor"))
+ continue;
+
+ if ((foreignAddress.contains(":domain")) || (foreignAddress.contains(":53 "))){
+ m_program = program;
+ QTimer::singleShot( 3000, this, SLOT(torUsedAfterDNSRequest()) );
+ }
+
+ item2 = "";
+
+ }
+
+
+}
+
+void tork::torUsedAfterDNSRequest()
+{
+
+ if (QTime::currentTime().secsTo(m_view->timeTorWasLastUsed()) > -6){
+ processWarning("dnsrequestsdetected",i18n("Shortly before traffic to %1 passed through Tor, the program <b>%2</b> bypassed Tor to turn a domain name to an IP address. Traffic to <b>%3</b> may therefore not be fully anonymous.").arg(m_view->addrTorWasLastUsed()).arg(m_program).arg(m_view->addrTorWasLastUsed()));
+
+ }
+
+
+}
+
+void tork::processWarning(const QString& type, const QString& text)
+{
+
+ int i;
+ for (i = 0; _tork_messages[i].logmessage; ++i) {
+ message_t *msg = &_tork_messages[i];
+ if (QString(msg->logmessage).contains(type)){
+ if ((*this.*(msg->pt2Member))()){
+ strncpy(msg->torsaid,text,249);
+ showWarning(msg->state, msg->headline, msg->torsaid,
+ msg->body, msg->type, msg->icon, msg->always, msg->showstopper);
+ m_view->infoUpdated("TorK",msg->headline,msg->body);
+ }
+ }
+ }
+
+}
+
+void tork::processQuestion(const QString& type, const QString& text)
+{
+
+ QString tmptext = text;
+ tmptext.replace(",",", ");
+ int i;
+ for (i = 0; _tork_questions[i].logquestion; ++i) {
+ question_t *msg = &_tork_questions[i];
+ if ((*this.*(msg->pt2Member2))()){
+ if (QString(msg->logquestion).contains(type)){
+ (*this.*msg->silentAction)();
+ strncpy(msg->torsaid,tmptext,249);
+ askQuestion(msg->state, msg->headline, msg->torsaid, msg->body,
+ msg->question,msg->pt2Member, msg->type, msg->icon,
+ msg->persistent, msg->showstopper);
+ m_view->infoUpdated("TorK",msg->headline,msg->body);
+ }
+ }
+
+ }
+
+
+}
+
+void tork::showSecurityNotice(const QString& port)
+{
+
+ processQuestion("securitynotice",i18n("Traffic on port %1 is not "
+ "encrypted. <b> Passwords </b> transmitted on this "
+ "channel could be harvested by the owner of the exit "
+ "node.").arg(port));
+
+}
+
+void tork::showScreamingNotice(const QString& port)
+{
+
+ if (TorkConfig::currentTorVersion().left(3) != "0.1")
+ return;
+
+ processQuestion("screamingnotice",i18n("Now that I have your attention: "
+ "Traffic on port %1 is not encrypted and usually involves "
+ "passwords. <b> Passwords </b> transmitted on this channel"
+ " could be harvested by the owner of the exit node.")
+ .arg(port));
+
+
+}
+
+void tork::showFirewallEvasion()
+{
+ openConfig("Firewall/Censor Evasion");
+}
+
+void tork::showMyServer()
+{
+ openConfig("My Tor Server");
+}
+
+void tork::showMyHiddenServices()
+{
+
+ if (!myHiddenDialog)
+ myHiddenDialog = new MyHidden(this);
+
+ myHiddenDialog->show();
+ myHiddenDialog->raise();
+ myHiddenDialog->setActiveWindow();
+
+}
+
+void tork::showMyKonqueror()
+{
+ openConfig("Konqueror");
+}
+
+void tork::useNewIdentity()
+{
+
+ if (recentNewIdentityRequest)
+ return;
+
+ if (client != 0L){
+ recentNewIdentityRequest = true;
+ QTimer::singleShot( 20000, this, SLOT(allowNewIdentityRequests()) );
+
+ client->newIdentity();
+
+ }
+}
+
+void tork::allowNewIdentityRequests()
+{
+
+ recentNewIdentityRequest = false;
+
+}
+void tork::createService(const QString& dir, const QString& port)
+{
+
+ if (client != 0L)
+ client->createService(dir,port);
+
+}
+
+void tork::toggleNonTorTraffic(bool state)
+{
+ if (state)
+ startNetStat();
+ else
+ stopNetStat();
+}
+
+void tork::toggleTorTraffic(bool )
+{
+
+}
+
+void tork::checkBandwidthSettings( )
+{
+
+ if (client == 0L)
+ return;
+ if (TorkConfig::bandwidthSlots().isEmpty() || !TorkConfig::useScheduledBandwidth())
+ return;
+
+
+ QString newBW, newLdBW, nextBW;
+ int largestCandidateSoFar = -86400, newCandidate = 0, bestCandidate = -86400;
+ int nextScheduledCandidate =0, nextCandidate = 0;
+ int BWDayAsInt = 0;
+ int TodayAsInt = QDate::currentDate().dayOfWeek();
+ // Get current date/time
+ QDateTime currentDateTime = QDateTime::currentDateTime();
+ QDate nextDate;
+ QTime nextTime;
+
+ QStringList bandwidthSlots = TorkConfig::bandwidthSlots();
+ for ( QStringList::Iterator it = bandwidthSlots.begin(); it != bandwidthSlots.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+
+ //Get the entry's day as an int between 1 and 7
+ if ((*it).section("\n",-4,-4) == "Day")
+ BWDayAsInt = TodayAsInt;
+ else{
+ for (int i=1; i<8;i++){
+ if ((*it).section("\n",-4,-4) == QDate::longDayName(i)){
+ BWDayAsInt = i;
+ break;
+ }
+ }
+ }
+
+ //Construct entry's date/time
+ QDateTime BWDateTime = QDateTime::currentDateTime();
+ BWDateTime.setTime(QTime::fromString((*it).section("\n",-5,-5)));
+ signed int daysFrom = BWDayAsInt - TodayAsInt;
+ newCandidate = currentDateTime.secsTo(BWDateTime.addDays(daysFrom));
+
+ // Find the next scheduled change of BW after this one, for reporting
+ // to user if we change the BW now.
+
+ if (newCandidate < 0){
+ daysFrom = ((*it).section("\n",-4,-4) != "Day")?daysFrom+7:1;
+ nextCandidate = currentDateTime.secsTo(BWDateTime.addDays(daysFrom));
+ }else{
+ nextCandidate = newCandidate;
+ }
+ if ((nextScheduledCandidate == 0) || (nextCandidate < nextScheduledCandidate)){
+ nextScheduledCandidate = nextCandidate;
+ nextDate = BWDateTime.addDays(daysFrom).date();
+ nextTime = BWDateTime.addDays(daysFrom).time();
+ }
+
+ //Remember the largest date/time combination because if there is no other
+ // date/time combination in the past, then the largest is the most recent
+ if (newCandidate > largestCandidateSoFar){
+ largestCandidateSoFar = newCandidate;
+ newLdBW = (*it);
+ }
+
+ //If the date/time combo is in the past and it is 'larger' than our current
+ //candidate then we have a new candidate
+ if ((newCandidate < 0) && (newCandidate > bestCandidate)){
+ bestCandidate = newCandidate;
+ newBW = (*it);
+ }
+
+ }
+
+ if (newBW.isEmpty())
+ newBW = newLdBW;
+
+ if (newBW.isEmpty())
+ return;
+
+ unsigned long int cndBWRate = (newBW.section("\n",-3,-3).toInt() * 1024);
+ unsigned long int cndBWBurst = (newBW.section("\n",-2,-2).toInt() * 1024);
+ unsigned long int cndBWMax = (newBW.section("\n",-1).toInt() * 1024 );
+
+ if ((cndBWRate != client->getCurBandwidthRate()) ||
+ (cndBWBurst != client->getCurBandwidthBurst()) ||
+ (cndBWMax != client->getCurMaxAdvertisedBandwidth())){
+ client->setBandwidth(newBW.section("\n",-3,-3),newBW.section("\n",-2,-2),
+ newBW.section("\n",-1));
+ QTime bwtime = QTime::fromString(nextBW.section("\n",-5,-5));
+ processWarning( "bwreset",i18n("Tor bandwidth has been reset to: Max Incoming -"
+ " <b>%1 KB/s</b>."
+ " Max Burst - <b>%2 KB/s</b>. Max Advertised - <b>%3 KB/s</b>."
+ " Your next scheduled bandwidth change is on %4 at %5.")
+ .arg(newBW.section("\n",-3,-3)).arg(newBW.section("\n",-2,-2))
+ .arg(newBW.section("\n",-1)).arg(nextDate.toString("dddd MMMM d"))
+ .arg(nextTime.toString("h:mm ap")));
+ client->getBandwidth();
+
+ }
+}
+
+void tork::setBandwidthFromSysTray(int rate )
+{
+ if (client == 0L)
+ return;
+
+ client->setBandwidth(QString("%1").arg(rate),QString("%1").arg(rate*2),
+ "");
+ client->getBandwidth();
+
+}
+
+void tork::setTorCaption(const QString& caption)
+{
+ setCaption(QString("%1 using Tor %2").arg(torCaption).arg(caption));
+ TorkConfig::setCurrentTorVersion(caption);
+ TorkConfig::writeConfig();
+
+ if (caption.left(3) == "0.1"){
+ m_view->streamList->hideColumn(1);
+ m_view->streamList->header()->setResizeEnabled(FALSE, 1);
+ m_view->streamList->setResizeMode( QListView::NoColumn );
+ m_UnCensorButton->unplug( toolBar("TorToolBar") );
+ m_SecurityButton->unplug( toolBar("MoreToolBar") );
+ m_ServerButtonMenu->setItemEnabled( 3, false );
+ emit processWarning("featuresdisabled",i18n("Nothing."));
+ }
+}
+
+void tork::resetTor()
+{
+ KProcIO *catproc = new KProcIO();
+ catproc->setUseShell(TRUE);
+ QString whichCommand= "kdesu -c 'killall -s HUP tor'";
+ *catproc<<whichCommand;
+ catproc->start(KProcIO::NotifyOnExit,TRUE);
+ connect( catproc, SIGNAL(processExited(KProcess *)),
+ SLOT(resetExited()) );
+
+}
+
+void tork::resetExited()
+{
+ startEverything();
+}
+
+void tork::upnpForwardingOK(kt::UPnPRouter* router,const QString& string, bool fwd)
+{
+ kdDebug() << "UPNPforwardingok" << endl;
+ QString tmpports = QStringList::split("<NewExternalPort>",string)[1];
+ QString extport = QStringList::split("</NewExternalPort>",tmpports)[0];
+ tmpports = QStringList::split("<NewInternalPort>",string)[1];
+ QString intport = QStringList::split("</NewInternalPort>",tmpports)[0];
+
+
+// if (!(router->forwardedPorts()->contains(net::ForwardPort(443,
+// TorkConfig::oRListenAddress(),
+// net::TCP,false))) ||
+// (!router->forwardedPorts()->contains(net::ForwardPort(80,
+// TorkConfig::dirListenAddress(),
+// net::TCP,false))))
+// return;
+
+ if (client != 0L)
+ client->configureServer(upnpORPort(), upnpDirPort());
+
+ if (UPnPManager::Manager()->silentUpdate())
+ return;
+
+ if (fwd)
+ processWarning("fwdok",i18n("Ports 80 and 443 on your router "
+ "<b>%1</b> successfully forwarded to the ports "
+ "%2 and %3 used by your Tor server.")
+ .arg(router->getDescription().friendlyName)
+ .arg(TorkConfig::dirListenAddress())
+ .arg(TorkConfig::oRListenAddress()));
+ else
+ processWarning("unfwok",i18n("Ports 80 and 443 on "
+ "<b>%1</b> have been successfully unmapped "
+ "from the ports "
+ "%2 and %3 used by your Tor server.")
+ .arg(router->getDescription().friendlyName)
+ .arg(TorkConfig::dirListenAddress())
+ .arg(TorkConfig::oRListenAddress()));
+
+
+}
+
+
+void tork::upnpForwardingError(kt::UPnPRouter* router,const QString& string, bool fwd)
+{
+
+ QString tmpports = QStringList::split("<NewExternalPort>",string)[1];
+ QString extport = QStringList::split("</NewExternalPort>",tmpports)[0];
+ tmpports = QStringList::split("<NewInternalPort>",string)[1];
+ QString intport = QStringList::split("</NewInternalPort>",tmpports)[0];
+
+ //Reset the ORPort or DirPort to the non-forwarded value
+ if (extport == "80")
+ setUpnpDirPort(TorkConfig::dirListenAddress());
+ else
+ setUpnpORPort(TorkConfig::oRListenAddress());
+
+ if (client != 0L)
+ client->configureServer(upnpORPort(), upnpDirPort());
+
+ if (UPnPManager::Manager()->silentUpdate())
+ return;
+
+ if (fwd)
+ processWarning("fwderror",i18n("There was a problem forwarding port %1 "
+ " on your router <b>%1</b> to port %3 on Tor.")
+ .arg(extport).arg(router->getServer()).arg(intport));
+ else
+ processWarning("unfwerror",i18n("There was a problem un-forwarding port %1 "
+ " on your router <b>%1</b> to port %3 on Tor.")
+ .arg(extport).arg(router->getServer()).arg(intport));
+
+}
+
+void tork::routerDiscovered(kt::UPnPRouter* r)
+{
+ kdDebug() << r->getServer() << endl;
+ kdDebug() << "routerdiscovered" << endl;
+ discoveredRouters.append(r->getDescription().friendlyName);
+ m_routerDiscovered = true;
+
+ configureRouter(false);
+}
+
+void tork::configureRouter(bool force, bool silent)
+{
+
+ if (!m_CanApplyServerSettingsIfSet)
+ return;
+ if (TorkConfig::clientOnly())
+ return;
+
+ kdDebug() << "configuring router" << endl;
+ kdDebug() << TorkConfig::forwardPorts() << endl;
+
+ forwardPortList = new ForwardPortList();
+
+ if (TorkConfig::forwardPorts()){
+ setUpnpORPort(443);
+ setUpnpDirPort(80);
+ }else{
+ setUpnpORPort(TorkConfig::oRListenAddress());
+ setUpnpORPort(TorkConfig::dirListenAddress());
+ }
+
+
+ forwardPortList->addNewForwardPort(443,
+ TorkConfig::oRListenAddress(),net::TCP,false);
+ forwardPortList->addNewForwardPort(80,
+ TorkConfig::dirListenAddress(),net::TCP,false);
+
+ if (TorkConfig::forwardPorts())
+ UPnPManager::Manager()->forward(*forwardPortList, force, silent);
+ else
+ UPnPManager::Manager()->undoForward(*forwardPortList,silent);
+
+}
+
+void tork::checkRouterDiscovered()
+{
+
+ if (!m_routerDiscovered)
+ processWarning("cantfindrouter",i18n("TorK can't contact your router to optimize "
+ " it's configuration for Tor."));
+
+}
+
+void tork::dummyAction()
+{
+
+}
+
+void tork::retryUPnP()
+{
+ //Force UPnP forwarding, even if we think it's already forwarded.
+ //Do not inform user of the result.
+ configureRouter(true,true);
+}
+
+#include "tork.moc"
+
diff --git a/src/tork.desktop b/src/tork.desktop
new file mode 100644
index 0000000..8518c14
--- /dev/null
+++ b/src/tork.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Name=TorK
+GenericName=Anonymity Manager
+Comment=An Anonymity Manager for KDE
+Type=Application
+Categories=Qt;KDE;Network;FileTransfer
+Terminal=false
+Icon=tork
+Exec=tork %i %m -caption "%c" %u
+X-DCOP-ServiceType=Unique
diff --git a/src/tork.h b/src/tork.h
new file mode 100644
index 0000000..f239029
--- /dev/null
+++ b/src/tork.h
@@ -0,0 +1,435 @@
+/***************************************************************************
+ * $Id: tork.h,v 1.115 2009/08/12 19:41:23 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#ifndef _TORK_H_
+#define _TORK_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <kapplication.h>
+#include <kmainwindow.h>
+#include <ktempfile.h>
+
+#include "torkview.h"
+#include "torclient.h"
+#include "statgraph.h"
+#include "popupMessage.h"
+#include "torkconfig.h"
+#include "version.h"
+#include "dcoptork.h"
+#include "testprivacyproxy.h"
+
+#include <kconfigskeleton.h>
+#include <kwinmodule.h>
+#include <kpopupmenu.h>
+#include <qvaluevector.h>
+
+#include "update.h"
+#include "trayicon.h"
+#include "upnpmanager.h"
+#include "hiddensrvs.h"
+
+class KPrinter;
+class KToggleAction;
+class KPopupMenu;
+class KActionMenu;
+class KURL;
+class TrayIcon;
+class QLabel;
+class KProcIO;
+class TorClient;
+class QPoint;
+class StatGraph;
+class TorkConfig;
+class KConfigSkeleton;
+class KConfigSkeletonItem;
+class KTempFile;
+class KWindModule;
+class UPnPManager;
+class SetMaxRate;
+class MyHidden;
+class TestProxy;
+
+//class QValueVector;
+
+/** Enumeration of types which option values can take */
+typedef enum display_status_t {
+ DISPLAY_NONE = 0, /**< An arbitrary string. */
+ DISPLAY_QUEUED, /**< A non-negative integer less than MAX_INT */
+} display_status_t;
+
+
+
+/**
+ * This class serves as the main window for tork. It handles the
+ * menus, toolbars, and status bars.
+ *
+ * @short Main window class
+ * @author Robert Hogan <robert@roberthogan.net>
+ * @version 0.03
+ */
+class tork : public KMainWindow, virtual public DCOPTork
+{
+ Q_OBJECT
+public:
+ /**
+ * Default Constructor
+ */
+ tork();
+
+ /**
+ * Default Destructor
+ */
+ virtual ~tork();
+
+ torkView *m_view;
+
+ TrayIcon *_tray;
+ QDict<QListViewItem> inodes;
+ bool connectedToTor(){return (client!=0) ? true : false;};
+ KPopupMenu* m_LaunchMenu;
+ void anonymousFirefox(){m_view->anonymousFirefox();};
+ void anonymousOpera(){m_view->anonymousOpera();};
+ void anonymousEmail(){m_view->sendAnonymousEmail(); hide();};
+ void anonymizedFirefox(const QString & url){m_view->anonymizedFirefox(url);};
+ void anonymizedOpera(const QString & url){m_view->anonymizedOpera(url);};
+ void anonymousKonversation(){torkify( 0 );};
+ void anonymousKopete(){torkify( 1 );};
+ void anonymousGaim(){torkify( 2 );};
+ void anonymousPidgin(){torkify( 3 );};
+ void anonymousKonsole(){torkify( 4 );};
+ bool getKDESetting();
+ bool routerDiscovered(){ return m_routerDiscovered;};
+ void setRouterDiscovered(bool discovered){ m_routerDiscovered = discovered;};
+
+ QStringList getDiscoveredRouters(){ return discoveredRouters;};
+ void setBandwidthFromSysTray(int rate );
+ void enableKDEAndLaunchKonqWithUrl(const QString &);
+ int upnpORPort(){ return orPort; };
+ int upnpDirPort(){ return dirPort; };
+ void setUpnpDirPort(int port){ dirPort=port; };
+ void setUpnpORPort(int port){ orPort=port; };
+
+private slots:
+ void fileNew();
+ void optionsShowToolbar();
+ void optionsShowStatusbar();
+ void optionsConfigureKeys();
+ void optionsConfigureToolbars();
+ void optionsPreferences();
+ void newToolbarConfig();
+ void startTor();
+ void startNetStat();
+ void stopNetStat();
+ void updatePrivoxy();
+ void childExited();
+ void privoxyExited();
+ void netStatExited();
+ void filterExited();
+ void startFromBeginning();
+ void isControllerWorking( );
+ void checkRouterDiscovered( );
+
+
+ void changeStatusbar(const QString& in,const QString& out);
+ void changeCaption(const QString& text);
+ void startController();
+ void stopController();
+ void receivedOutput(KProcIO *);
+ void processFilter(KProcIO *filterproc);
+ void receivedNetStatOutput(KProcIO *);
+ void toggleKDESetting();
+ void enableKDE(bool enable);
+ void toggleKDESettingAndLaunchKonq();
+ void setKDE(bool set);
+ void turnOffKDE();
+ void sayWhatImDoing(const QString& );
+ void slotOnItem( int, QListViewItem *, const QPoint &, int );
+ void slotOnORItem( QListViewItem * );
+ void slotOffItem( );
+ void openConfig(const QCString& page);
+
+ void slotHandle(/*TFunctor *functor*/);
+ void noClicked(/*TFunctor *functor*/);
+ void popUpClosed();
+ void processHashProc(KProcIO *hashproc);
+ void toggleTorMon();
+ void toggleTorMon2();
+ void toggleTorBar();
+ void hiddenServices();
+ void mixminionHome();
+ void networkList();
+ void infoUpdated(const QString &type, const QString &summary, const QString &data);
+ void shuttingDown();
+ void showMyServer();
+ void showFirewallEvasion();
+ void useNewIdentity();
+ void showMyKonqueror();
+ void showMyHiddenServices();
+ void toggleNonTorTraffic(bool state);
+ void toggleTorTraffic(bool state);
+ void checkForKonqWindow(WId);
+ void configurePrivoxy();
+ void warnNoServerInfo();
+ void startingPeriodOver();
+ void needAlphaVersion( );
+ void filterServers( int );
+ void toggleIP( int );
+ void filterLog( int );
+ void filterSubnets( int );
+ void filterCountries( int );
+ void filterTorTraffic( int );
+ void filterNonTorTraffic( int );
+ void sortByCountry( );
+ void toggleTextFilter( int );
+ void createSubnetList( );
+ void torkify( int );
+ void allowNewIdentityRequests();
+ void populateSubNetMenu();
+ void populatePseudoMenu();
+ void populateCountryMenu();
+ void applyPseudonymity( int country_id );
+ void checkBandwidthSettings();
+ void setTorCaption(const QString &caption);
+ void configureServer(int);
+ void configureSecurity( int id );
+ void updateServerButton( );
+ void torUsedAfterDNSRequest();
+ void updateTrayStats(const QString &,const QString &,const QString &,const QString &);
+ void updateTrayIcon(const QString &);
+ void resetExited();
+ void switchMode();
+ void upnpForwardingOK(kt::UPnPRouter*,const QString &, bool);
+ void upnpForwardingError(kt::UPnPRouter*,const QString &, bool);
+ void routerDiscovered(kt::UPnPRouter* );
+ void configureRouter(bool force,bool silent=false);
+ void checkForSystemManagedPrivoxy();
+ void cannotContactPrivoxy();
+ void privacyProxyPassed();
+
+public slots:
+
+ void startPrivoxy();
+ void letTorKManagePrivoxy();
+ void serverHelp();
+ void enterContactInfo();
+ void fixAddressPort();
+ void continueAsClient();
+ void updateTorStable();
+ void reconnectWithCookie();
+ void copyCookie();
+ void updateTork();
+ void quickConfig();
+ void cannotContactTor();
+ void showTip();
+ void showTipOnStart();
+ void runWizard();
+ void copyOldConfig();
+ void shouldIApplySettings();
+ void applySettingsToRunningTor();
+ bool showUsage();
+ bool showSecurityWarnings();
+ bool showGuideQuestions();
+ bool showApplySettingsQuestions();
+ bool contactInfoSet();
+ bool showDNSLeaks();
+ void readEavesdropping();
+ void aboutTorify();
+ void aboutTor();
+ void showSecurityNotice(const QString &port);
+ void showScreamingNotice(const QString &port);
+ void torClosedConnection();
+ void makeTorkStoppable();
+ void createService(const QString& dir,const QString& port);
+ void aboutParanoidMode();
+ void processWarning(const QString& type, const QString& text);
+ void processQuestion(const QString& type, const QString& text);
+ void updateTorUnstable();
+ void currentTabChanged(QWidget* cur );
+ void stopTor();
+ void resetTor();
+ void toggleServerButton( bool on );
+ void dummyAction();
+ void retryUPnP();
+ void allowPlainTextPorts();
+ void assignPortToRemove();
+ void startEverything();
+ void stopTorGracefully();
+
+private:
+ void setupAccel();
+ void setupActions();
+ QString writeConf();
+ QString writePrivoxyConf();
+ void writeCustomOptions(QTextStream &ts);
+ void writeCustomOptions2(QTextStream &ts);
+ void showWarning( display_status_t &msg, const QString &headline,const QString &torsaid,const QString &thismeans, const QString &type, const QString &icon, bool always, bool showstopper);
+ void askQuestion(display_status_t &msg, const QString &headline,const QString &torsaid,const QString &body,const QString &question,void (tork::*pt2Func)(), const QString &type, const QString &icon, bool persistent, bool showstopper);
+ void processQueue();
+ bool elementShouldBeUsed(const KConfigSkeletonItem* it);
+ bool noSpecialProcessing(const KConfigSkeletonItem* it, QTextStream &ts);
+ QString doHashPassword();
+ bool queryClose();
+ void prepareToShut();
+ void filterViewServers( QValueVector<QString> &possibleValues, QListView* &view, KPopupMenu* &menu, int id, int column );
+ void filterView( QValueVector<QString> &possibleValues, QListView* &view, KPopupMenu* &menu, int id, int column );
+ QString createFailSafeCommand( const QStringList &filterRules, bool set );
+ void updateServerClientStatusBar(const QStringList &client, const QStringList &server);
+ void updateToolBar();
+
+private:
+
+ KPrinter *m_printer;
+ KToggleAction *m_toolbarAction;
+ KToggleAction *m_statusbarAction;
+ KAction *torkConfigure;
+ KAction *torkStop;
+ KAction *torkStart;
+ KAction *torkUpdateTork;
+ KAction *torkUpdateStable;
+ KAction *torkUpdateUnstable;
+ KAction *torkUpdatePrivoxy;
+ KAction *torkFirstRunWizard;
+ KAction *torkTip;
+ KAction *enableKonqi;
+ KAction *enableTormon;
+ //KAction *toggleParanoid;
+ KAction *browseHiddenServices;
+ KAction *browseNetworkList;
+ KAction *toggleTorbar;
+ KActionMenu* m_ServerFilterButton;
+ KActionMenu* m_LaunchMenuButton;
+ KActionMenu* m_LogFilterButton;
+ KActionMenu* m_TrafficFilterButton;
+ KPopupMenu* m_ServerFilterMenu;
+ KPopupMenu* m_LogFilterMenu;
+ KPopupMenu* m_TrafficFilterMenu;
+ KPopupMenu* m_TorTrafficFilterMenu;
+ KPopupMenu* m_NonTorTrafficFilterMenu;
+ KPopupMenu* m_IPFilterMenu;
+ KPopupMenu* m_PseudoMenu;
+ KPopupMenu* m_PseudoMenuEU;
+ KPopupMenu* m_PseudoMenuSA;
+ KPopupMenu* m_PseudoMenuAS;
+ KPopupMenu* m_PseudoMenuNA;
+ KPopupMenu* m_PseudoMenuAN;
+ KPopupMenu* m_PseudoMenuAF;
+ KPopupMenu* m_PseudoMenuNN;
+ KPopupMenu* m_PseudoMenuOC;
+ KActionMenu* m_PseudoButton;
+ KAction* m_IdentityButton;
+ KAction* m_ModeButton;
+ KAction* m_UnCensorButton;
+ KPopupMenu* m_CountryMenu;
+ KPopupMenu* m_CountryMenuEU;
+ KPopupMenu* m_CountryMenuSA;
+ KPopupMenu* m_CountryMenuAS;
+ KPopupMenu* m_CountryMenuNA;
+ KPopupMenu* m_CountryMenuAN;
+ KPopupMenu* m_CountryMenuAF;
+ KPopupMenu* m_CountryMenuNN;
+ KPopupMenu* m_CountryMenuOC;
+ KActionMenu* m_ServerButton;
+ KPopupMenu* m_ServerButtonMenu;
+ KActionMenu* m_SecurityButton;
+ KPopupMenu* m_SecurityButtonMenu;
+
+ QLabel* m_statusInfo;
+ QLabel* m_statusTransfer;
+ QLabel* m_statusSpeed;
+ StatGraph* m_graphIn;
+ StatGraph* m_graphOut;
+ KProcIO* childproc;
+ KProcIO* filterproc;
+ KProcIO* netstatproc;
+ KProcIO* privoxyproc;
+ TorClient* client;
+ bool m_servererrornag;
+ bool m_contactinfonag;
+ bool m_serverworking;
+ QListViewItem* m_prevItem;
+ QTimer *timer;
+ QTimer *bwtimer;
+ QTimer *bwLimitTimer;
+ void (tork::*m_pt2Func)();
+ KDE::PopupMessage *m_tooltip;
+ QStringList m_list;
+ QString m_body;
+ display_status_t* m_msg;
+ KProcIO *hashproc;
+ QString m_hashedpassword;
+ KConfigSkeletonItem::List previtems;
+ KConfigSkeleton pcopy;
+ PrevConfig::PrevConfigList prevlist;
+ TorkUpdate* updater;
+ KTempFile* tfTor;
+ KTempFile* tfPrivoxy;
+ KWinModule* winModule;
+ QWidget* prev;
+
+ QValueList<QListViewItem*> ordinaryServerList;
+ QMap<QString,KPopupMenu*> continentMap;
+ QMap<QString,KPopupMenu*> continentMapList;
+ QStringList discoveredRouters;
+
+ int filterId;
+
+ bool m_toolTipShowing;
+ bool m_persistent;
+ bool filterWasApplied;
+ bool geoip_db;
+ bool waitingForServers;
+ bool stillStarting;
+ bool m_DNSTorified;
+ bool m_showstopperAlreadyDisplayed;
+ bool m_routerDiscovered;
+ bool recentNewIdentityRequest;
+ bool m_ShutdownRequested;
+ bool m_AppliedSettings;
+ bool m_CanApplyServerSettingsIfSet;
+
+ QDialog* dialog;
+ MyHidden* myHiddenDialog;
+ QDialog* serverdialog;
+
+ UPnPManager* upnpmanager;
+ ForwardPortList* forwardPortList;
+
+ QString filterError;
+ QString torCaption;
+ QString m_program;
+
+ SetMaxRate* m_set_max_rate;
+
+ TestPrivoxy *privoxytest;
+ int orPort;
+ int dirPort;
+
+};
+
+
+extern tork *kmain;
+
+#endif // _TORK_H_
+
diff --git a/src/tork.kcfgc b/src/tork.kcfgc
new file mode 100644
index 0000000..fd797c4
--- /dev/null
+++ b/src/tork.kcfgc
@@ -0,0 +1,6 @@
+# Code generation options for kconfig_compiler
+File=torkconfig.kcfg
+ClassName=Settings
+Singleton=true
+Mutators=col_background,col_foreground
+# will create the necessary code for setting those variables
diff --git a/src/tork.lsm b/src/tork.lsm
new file mode 100644
index 0000000..500c05c
--- /dev/null
+++ b/src/tork.lsm
@@ -0,0 +1,16 @@
+Begin3
+Title: TorK -- Anonymity Manager For KDE
+Version: 0.24
+Entered-date:
+Description: An Anonymity Manager For KDE
+Keywords: KDE Qt
+Author: Robert Hogan <robert@roberthogan.net>
+Maintained-by: Robert Hogan <robert@roberthogan.net>
+Home-page: http://tork.sf.net
+Alternate-site:
+Primary-site: http://tork.sf.net
+ xxxxxx tork-0.1.tar.gz
+ xxx tork-0.1.lsm
+Platform: Linux. Needs KDE
+Copying-policy: GPL
+End
diff --git a/src/tork.xpm b/src/tork.xpm
new file mode 100644
index 0000000..e87d35a
--- /dev/null
+++ b/src/tork.xpm
@@ -0,0 +1,206 @@
+/* XPM */
+static char * tork_xpm[] = {
+"32 32 171 2",
+" c None",
+". c #7C7C7C",
+"+ c #7A7F7A",
+"@ c #A1A1A1",
+"# c #62AF5B",
+"$ c #5BBD52",
+"% c #7F957D",
+"& c #9A8D9C",
+"* c #A384A7",
+"= c #A575AB",
+"- c #748C72",
+"; c #45E936",
+"> c #4ADF3C",
+", c #4ED741",
+"' c #58C34E",
+") c #7E757F",
+"! c #46E637",
+"~ c #4BDD3E",
+"{ c #4CDA3F",
+"] c #46E737",
+"^ c #88768B",
+"/ c #778675",
+"( c #49E13B",
+"_ c #48E13B",
+": c #47E538",
+"< c #6D926A",
+"[ c #A682AC",
+"} c #7C7D7C",
+"| c #58C44E",
+"1 c #45E737",
+"2 c #44EA35",
+"3 c #50D245",
+"4 c #50D344",
+"5 c #7E767F",
+"6 c #798179",
+"7 c #5ABF51",
+"8 c #4FD443",
+"9 c #55C84B",
+"0 c #55C94A",
+"a c #777E77",
+"b c #8E7591",
+"c c #6A9F66",
+"d c #4CDA40",
+"e c #52CF46",
+"f c #5AC050",
+"g c #61B15A",
+"h c #7A737B",
+"i c #907894",
+"j c #70936D",
+"k c #51D145",
+"l c #53CD48",
+"m c #4CDB3F",
+"n c #6B9D67",
+"o c #7C717F",
+"p c #99819D",
+"q c #53CC48",
+"r c #47E439",
+"s c #5FB458",
+"t c #57C44E",
+"u c #758274",
+"v c #8B788D",
+"w c #71916E",
+"x c #4ADD3D",
+"y c #5CBA54",
+"z c #5EB756",
+"A c #49E03C",
+"B c #887F89",
+"C c #44E935",
+"D c #5EB656",
+"E c #4ADE3D",
+"F c #4BDC3E",
+"G c #49DF3C",
+"H c #60B358",
+"I c #57C44D",
+"J c #45E836",
+"K c #65A85F",
+"L c #858086",
+"M c #6E986A",
+"N c #46E638",
+"O c #4DD940",
+"P c #4DD841",
+"Q c #56C74C",
+"R c #4ED542",
+"S c #61B259",
+"T c #50D244",
+"U c #44E936",
+"V c #827983",
+"W c #51D046",
+"X c #51D045",
+"Y c #5BBE52",
+"Z c #60B259",
+"` c #46E538",
+" . c #758974",
+".. c #928A92",
+"+. c #5CBB54",
+"@. c #54CA4A",
+"#. c #5BBC53",
+"$. c #4ED642",
+"%. c #4FD344",
+"&. c #60B359",
+"*. c #848384",
+"=. c #7A8179",
+"-. c #54CB49",
+";. c #5CBC53",
+">. c #4BDB3E",
+",. c #52CE47",
+"'. c #4CD940",
+"). c #928D93",
+"!. c #6C9C67",
+"~. c #5FB557",
+"{. c #4DD840",
+"]. c #59C24F",
+"^. c #56C64C",
+"/. c #6F956C",
+"(. c #888788",
+"_. c #64AB5E",
+":. c #57C54D",
+"<. c #59C050",
+"[. c #5FB558",
+"}. c #8A898A",
+"|. c #59C14F",
+"1. c #62B05B",
+"2. c #5ABE51",
+"3. c #66A860",
+"4. c #5DB954",
+"5. c #878687",
+"6. c #48E33A",
+"7. c #5DB955",
+"8. c #4BDD3D",
+"9. c #5BBC52",
+"0. c #69A264",
+"a. c #67A562",
+"b. c #63AE5C",
+"c. c #45E837",
+"d. c #64AB5D",
+"e. c #788576",
+"f. c #67A462",
+"g. c #768775",
+"h. c #7F7F7F",
+"i. c #5DB855",
+"j. c #65AA5E",
+"k. c #68A462",
+"l. c #66A661",
+"m. c #788477",
+"n. c #5EB855",
+"o. c #63AC5D",
+"p. c #6C9C68",
+"q. c #768974",
+"r. c #6AA065",
+"s. c #6A9F65",
+"t. c #63AD5D",
+"u. c #6D996A",
+"v. c #72906F",
+"w. c #67A661",
+"x. c #67A561",
+"y. c #66A760",
+"z. c #778576",
+"A. c #63AD5C",
+"B. c #69A064",
+"C. c #69A263",
+"D. c #56C74B",
+"E. c #778775",
+"F. c #6F966C",
+"G. c #66A761",
+"H. c #47E339",
+"I. c #49E03B",
+"J. c #69A164",
+"K. c #798278",
+"L. c #738E71",
+"M. c #748B72",
+"N. c #7A8079",
+" ",
+" ",
+" . + @ ",
+" . # $ % & * = ",
+" - ; > , ' ) ",
+" . ! ~ { ] ^ ",
+" . / ( _ : , < [ ",
+" } | { 1 2 3 4 5 ",
+" . 6 7 2 8 2 2 9 2 0 a b ",
+" . . c d 2 2 e 2 2 f 2 2 : g h i ",
+" . . j e 2 2 2 1 k 2 2 l m 2 2 2 d n o p ",
+" . / 7 2 2 2 2 2 q ] ~ r r s 2 2 2 2 2 t u v ",
+" . w x 2 2 2 2 : y e 2 ~ { 2 4 z 1 2 2 2 2 A n B ",
+" . c : 2 2 2 C q D E 2 C F 4 G 2 E H I J 2 2 2 ; K L ",
+" . M N 2 2 2 O z 8 2 2 2 P r : Q 2 2 2 R S T 2 2 2 U n V ",
+" . / _ 2 2 2 W $ C 2 2 2 2 X 2 2 Y 2 2 2 2 C ' Z ; 2 2 ` ... ",
+" . $ 2 2 2 +.l 2 2 2 2 2 > @.N N #.$.2 2 2 2 2 %.&.J 2 2 $ *. ",
+". =.: 2 2 I -.2 2 2 2 J I ;.J >.,.2 $ 7 J 2 2 2 2 '.H 2 2 : =.).",
+". !.2 2 O +.2 2 2 2 k ~.>.2 2 {.].2 2 >.~.@.2 2 2 2 ^.9 2 2 /.(.",
+". &.2 2 _.1 2 2 2 ;.:.2 2 2 2 3 <.2 2 2 2 ,.# ; 2 2 U n ! 2 [.}.",
+". |.2 ` 1.2 2 2 y ,.2 2 2 2 1 |.2.F 2 2 2 2 $.3.2 2 2 4.k 2 |.5.",
+". ~.2 6.7.2 2 W 7 2 2 2 2 ; H 8.] # A 2 2 2 2 9.7 2 2 Q W 2 ~.. ",
+". 0.2 J a.2 2 b.c.2 2 2 2 ~.x 2 2 r d.N 2 2 2 U c 2 2 g { 2 0.. ",
+". e.N 2 S O 2 S 2 2 2 2 O +.2 2 2 2 8 9.2 2 2 2 S 2 2 f.2 J g.h.",
+" . i.2 r j.2 k.` 2 2 2 i.( 2 2 2 2 2 l.2 2 2 2 a.2 W 7.2 <.. ",
+" . m.E 2 n.8 e 7 2 2 2 Z C 2 2 2 2 2 S 2 2 2 G o.J p.: r q.. ",
+" . /.: ! r.r a.: 2 2 9.P 2 2 2 2 2 s.2 2 2 t.O [.Q ] u.. ",
+" . v.~ F w.O x.; 2 d o.2 2 2 2 ~ # 2 2 e s e y.r !.. ",
+" . z.9.k j.0 A.J 2 B.6.2 2 2 y.F 2 k C.D.y.t q.. ",
+" . . E.k.F.7.G.8 m a.H.2 7 s I.g w._.e.- . . ",
+" . . . j / w J.K./ L.p.+ M.N.. . ",
+" . . . . . . . . . . "};
diff --git a/src/tork_downloadwithfirefox.desktop b/src/tork_downloadwithfirefox.desktop
new file mode 100644
index 0000000..c374e6b
--- /dev/null
+++ b/src/tork_downloadwithfirefox.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Encoding=UTF-8
+Actions=TorkDownload;
+Icon=tork_firefox
+ServiceTypes=all/allfiles
+ExcludeServiceTypes=kdedevice/*
+X-KDE-ShowIfRunning=tork
+
+[Desktop Action TorkDownload]
+Exec=dcop tork DCOPTork startEverything;dcop tork DCOPTork anonymizedFirefox %U;
+Icon=tork
+Name=Open Anonymously with Firefox
+
diff --git a/src/tork_downloadwithkonqueror.desktop b/src/tork_downloadwithkonqueror.desktop
new file mode 100644
index 0000000..e23144d
--- /dev/null
+++ b/src/tork_downloadwithkonqueror.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Encoding=UTF-8
+Actions=TorkDownload;
+Icon=konqueror
+ServiceTypes=all/allfiles
+ExcludeServiceTypes=kdedevice/*
+X-KDE-ShowIfRunning=tork
+
+[Desktop Action TorkDownload]
+Exec=konqueror tor:%U;
+Icon=tork
+Name=Open Anonymously with Konqueror
+
diff --git a/src/tork_downloadwithopera.desktop b/src/tork_downloadwithopera.desktop
new file mode 100644
index 0000000..8b21fd1
--- /dev/null
+++ b/src/tork_downloadwithopera.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Encoding=UTF-8
+Actions=TorkDownload;
+Icon=tork_opera
+ServiceTypes=all/allfiles
+ExcludeServiceTypes=kdedevice/*
+X-KDE-ShowIfRunning=tork
+
+[Desktop Action TorkDownload]
+Exec=dcop tork DCOPTork startEverything;dcop tork DCOPTork anonymizedOpera %U;
+Icon=tork
+Name=Open Anonymously with Opera
+
diff --git a/src/torkactivelabel.cpp b/src/torkactivelabel.cpp
new file mode 100644
index 0000000..b76876b
--- /dev/null
+++ b/src/torkactivelabel.cpp
@@ -0,0 +1,85 @@
+/***************************************************************************
+ * $Id: torkactivelabel.cpp,v 1.4 2008/07/31 19:56:27 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "torkactivelabel.h"
+#include "kdebug.h"
+#include <qapplication.h>
+#include <qheader.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+TorkActiveLabel::TorkActiveLabel( const QString &text,QWidget * parent, const char * name) :
+ KActiveLabel( text,parent, name ), mousePressed( FALSE )
+{
+
+
+}
+
+TorkActiveLabel::TorkActiveLabel( QWidget * parent, const char * name) :
+ KActiveLabel( parent, name ), mousePressed( FALSE )
+{
+
+
+}
+
+
+
+void TorkActiveLabel::contentsMousePressEvent( QMouseEvent* e )
+{
+ thisfont = this->font();
+ thisfont.setBold(true);
+ this->setFont(thisfont);
+
+ KActiveLabel::contentsMousePressEvent( e );
+}
+
+void TorkActiveLabel::contentsMouseMoveEvent( QMouseEvent* e )
+{
+
+ if (this->frameRect().contains(e->pos())){
+ thisfont = this->font();
+ thisfont.setUnderline(true);
+ this->setFont(thisfont);
+ }else{
+ thisfont = this->font();
+ thisfont.setUnderline(false);
+ this->setFont(thisfont);
+
+ }
+ KActiveLabel::contentsMouseMoveEvent( e );
+}
+
+void TorkActiveLabel::contentsMouseReleaseEvent( QMouseEvent * e)
+{
+ thisfont = this->font();
+ thisfont.setBold(false);
+ this->setFont(thisfont);
+ KActiveLabel::contentsMouseReleaseEvent(e);
+
+}
+
+QPoint TorkActiveLabel::getMousePos()
+{
+ return m_mousepos;
+}
+
+#include "torkactivelabel.moc"
diff --git a/src/torkactivelabel.h b/src/torkactivelabel.h
new file mode 100644
index 0000000..1ba01c3
--- /dev/null
+++ b/src/torkactivelabel.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * $Id: torkactivelabel.h,v 1.4 2008/07/31 19:56:27 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#ifndef _TORKACTIVELABEL_H_
+#define _TORKACTIVELABEL_H_
+
+#include <kactivelabel.h>
+
+
+class TorkActiveLabel : public KActiveLabel
+{
+Q_OBJECT
+
+public:
+ TorkActiveLabel(const QString &text, QWidget *parent, const char *name=0);
+ TorkActiveLabel(QWidget *parent, const char *name=0);
+ QPoint m_mousepos;
+ QPoint getMousePos();
+
+protected:
+ void contentsMouseMoveEvent( QMouseEvent *e );
+ void contentsMousePressEvent( QMouseEvent *e );
+ void contentsMouseReleaseEvent( QMouseEvent *e );
+
+private:
+ QPoint presspos;
+ bool mousePressed;
+ int dropTimer;
+ bool m_recentDrop;
+ QFont thisfont;
+
+
+};
+#endif // _TORKVIEW_H_
diff --git a/src/torkapplet/Makefile.am b/src/torkapplet/Makefile.am
new file mode 100644
index 0000000..4542d3b
--- /dev/null
+++ b/src/torkapplet/Makefile.am
@@ -0,0 +1,17 @@
+INCLUDES = $(all_includes)
+LIBS =
+
+kde_module_LTLIBRARIES = kickermenu_tork.la
+
+kickermenu_tork_la_SOURCES = tork_mnu.cpp ../functions.cpp
+kickermenu_tork_la_LDFLAGS = $(all_libraries) -module -avoid-version
+kickermenu_tork_la_LIBADD = $(LIB_KDEUI) $(LIB_KIO) $(LIB_KDECORE) -lDCOP $(LIB_QT)
+
+kickermenu_tork_la_METASOURCES = AUTO
+
+desktopmenu_DATA = torkmenu.desktop
+desktopmenudir = $(kde_datadir)/kicker/menuext
+
+messages:
+ $(XGETTEXT) *.cpp -o $(podir)/libkickermenu_tork.pot
+
diff --git a/src/torkapplet/tork_mnu.cpp b/src/torkapplet/tork_mnu.cpp
new file mode 100644
index 0000000..b354612
--- /dev/null
+++ b/src/torkapplet/tork_mnu.cpp
@@ -0,0 +1,203 @@
+/***************************************************************************
+** $Id: tork_mnu.cpp,v 1.7 2008/07/31 19:56:29 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <stdlib.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+
+#include <kapplication.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kio/global.h>
+#include <klocale.h>
+#include <krun.h>
+#include <kshell.h>
+#include <ksimpleconfig.h>
+#include <kstandarddirs.h>
+#include <dcopref.h>
+#include <dcopclient.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <krun.h>
+
+#include "tork_mnu.h"
+#include "../functions.h"
+
+K_EXPORT_KICKER_MENUEXT(tork, TorkMenu)
+
+QValueVector<QString> torkifyApp(8);
+
+
+TorkMenu::TorkMenu(QWidget *parent, const char *name, const QStringList& /* args */)
+ : KPanelMenu("", parent, name),m_kdestate(true)
+{
+ p_dcopServer= new DCOPClient();
+ p_dcopServer->attach ();
+
+}
+
+TorkMenu::~TorkMenu()
+{
+ KGlobal::locale()->removeCatalogue("libkickermenu_tork");
+ p_dcopServer->detach();
+ delete p_dcopServer;
+
+}
+
+void TorkMenu::initialize()
+{
+ if (initialized())
+ {
+ clear();
+ }
+ else
+ {
+ kapp->iconLoader()->addAppDir("tork");
+ }
+
+ setInitialized(true);
+
+ torkifyApp[5] = "Konversation";
+ torkifyApp[2] = "Kopete";
+ torkifyApp[4] = "Gaim";
+ torkifyApp[3] = "Pidgin";
+ torkifyApp[6] = "Konsole";
+ torkifyApp[1] = "Opera";
+ torkifyApp[0] = "Firefox";
+ torkifyApp[7] = "Email";
+
+ QStringList paths = getProgramList();
+
+
+ if (paths.contains("firefox"))
+ insertItem( SmallIcon("tork_firefox"), i18n( "Anonymous Firefox" ), 0,1 );
+ if (paths.contains("opera"))
+ insertItem( SmallIcon("tork_opera"), i18n( "Anonymous Opera" ), 1,2 );
+ if (paths.contains("kopete"))
+ insertItem( SmallIcon("kopete"), i18n( "Anonymous Kopete" ), 2,3 );
+ if (paths.contains("pidgin"))
+ insertItem( SmallIcon("pidgin"), i18n( "Anonymous Pidgin" ), 3,4 );
+ if (paths.contains("gaim"))
+ insertItem( SmallIcon("gaim"), i18n( "Anonymous Gaim" ), 4,5 );
+ if (paths.contains("konversation"))
+ insertItem( SmallIcon("konversation"), i18n( "Anonymous Konversation" ), 5,6 );
+ if (paths.contains("konsole"))
+ insertItem( SmallIcon("tork_konsole"), i18n( "Anonymous Konsole Session" ), 6,7 );
+ insertSeparator();
+
+
+ insertItem( SmallIcon("tork_mail"), i18n( "Send Anonymous Email" ), 7,8 );
+
+ insertSeparator();
+
+ insertItem( SmallIcon("tork_konqueroron"), i18n( "Anonymize KDE" ), 9,9 );
+
+ connect( this, SIGNAL( aboutToShow() ), SLOT( showPopup() ));
+
+}
+
+void TorkMenu::showPopup()
+{
+ bool anonymized = false;
+
+
+ if (p_dcopServer->isApplicationRegistered ("tork"))
+ {
+ DCOPRef tork( "tork", "DCOPTork" );
+ anonymized = tork.call( "getKDESetting" );
+ }
+
+ if (anonymized)
+ changeItem(9, SmallIcon("tork_konqueroroff"), i18n( "De-Anonymize KDE" ));
+ else
+ changeItem(9, SmallIcon("tork_konqueroron"), i18n( "Anonymize KDE" ));
+
+
+}
+
+void TorkMenu::slotExec(int id)
+{
+
+ m_torkrunning = false;
+ if (p_dcopServer->isApplicationRegistered ("tork"))
+ m_torkrunning = true;
+
+
+ switch(id)
+ {
+ case 9:
+ anonymizeKDE(); break;
+ default:
+ anonymousApp(id);break;
+ }
+
+}
+
+void TorkMenu::anonymousApp(int id)
+{
+
+ QString app = torkifyApp[id];
+ app.prepend("anonymous");
+
+ if (m_torkrunning){
+ DCOPRef("tork*", "DCOPTork").send("startEverything");
+ DCOPRef("tork*", "DCOPTork").send(QCString(app));
+ }else
+ KRun::runCommand( QString("tork --%1").arg(app), "tork", "tork" );
+
+}
+
+
+void TorkMenu::anonymizeKDE()
+{
+ if (m_torkrunning){
+ DCOPRef("tork*", "DCOPTork").send("startEverything");
+ DCOPRef("tork*", "DCOPTork").send("toggleKDESetting");
+ }else
+ KRun::runCommand( "tork --toggleKDE", "tork", "tork" );
+
+// if (m_kdestate)
+// changeItem(9, SmallIcon("tork_konqueroroff"), i18n( "De-Anonymize KDE" ));
+// else
+// changeItem(9, SmallIcon("tork_konqueroron"), i18n( "Anonymize KDE" ));
+//
+// m_kdestate = !m_kdestate;
+
+}
+
+QStringList TorkMenu::getProgramList()
+{
+
+ //Check for the existence of anonymizable/helper programs first.
+ QStringList programList;
+ programList << "firefox" << "kopete" << "gaim" <<
+ "pidgin" << "opera" << "konversation";
+
+ return findPrograms(programList);
+}
+
+#include "tork_mnu.moc"
diff --git a/src/torkapplet/tork_mnu.h b/src/torkapplet/tork_mnu.h
new file mode 100644
index 0000000..fe49b40
--- /dev/null
+++ b/src/torkapplet/tork_mnu.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+** $Id: tork_mnu.h,v 1.5 2008/07/31 19:56:29 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#ifndef _tork_mnu_h_
+#define _tork_mnu_h_
+
+#include <qvaluevector.h>
+
+#include <kpanelmenu.h>
+#include <klibloader.h>
+#include <dcopclient.h>
+
+
+class TorkMenu : public KPanelMenu/*, public KPReloadObject*/
+{
+ Q_OBJECT
+
+public:
+ TorkMenu(QWidget *parent, const char *name, const QStringList& /* args */);
+ ~TorkMenu();
+ void anonymousApp(int id);
+ void anonymizeKDE();
+ bool m_kdestate;
+ bool m_torkrunning;
+ DCOPClient* p_dcopServer;
+ QStringList getProgramList();
+protected slots:
+ void initialize();
+ void slotExec(int id);
+ void showPopup();
+};
+
+#endif
+
diff --git a/src/torkapplet/torkmenu.desktop b/src/torkapplet/torkmenu.desktop
new file mode 100644
index 0000000..a30c5d7
--- /dev/null
+++ b/src/torkapplet/torkmenu.desktop
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Name=TorK
+Type=Application
+Comment=Menu For Managing TorK
+Icon=tork
+
+X-KDE-Library=kickermenu_tork
+X-KDE-AuthorizeAction=shell_access
diff --git a/src/torkconfig.kcfg b/src/torkconfig.kcfg
new file mode 100644
index 0000000..bdcd084
--- /dev/null
+++ b/src/torkconfig.kcfg
@@ -0,0 +1,695 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile file="torkrc"/>
+
+ <group name="FirewallEvasion">
+
+ <entry name="FascistFirewall" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="ReachableAddresses" type="StringList">
+ <label></label>
+ </entry>
+ <entry name="KeepalivePeriod" type="Int">
+ <label></label>
+ <default>5</default>
+ </entry>
+
+ </group>
+
+ <group name="Censorship">
+
+ <entry name="Bridge" type="StringList">
+ <label></label>
+ </entry>
+
+ <entry name="TunnelDirConns" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="UseBridges" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ </group>
+
+
+ <group name="Proxies">
+ <entry name="UseProxy" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="HttpProxyHost" type="String">
+ <label></label>
+ </entry>
+ <entry name="HttpProxyPort" type="Int">
+ <label></label>
+ </entry>
+ <entry name="HttpProxyAuthenticatorUserName" type="String">
+ <label></label>
+ </entry>
+ <entry name="HttpProxyAuthenticatorPassword" type="String">
+ <label></label>
+ </entry>
+ <entry name="HttpsProxyHost" type="String">
+ <label></label>
+ </entry>
+ <entry name="HttpsProxyPort" type="Int">
+ <label></label>
+ </entry>
+ <entry name="HttpsProxyAuthenticatorUserName" type="String">
+ <label></label>
+ </entry>
+ <entry name="HttpsProxyAuthenticatorPassword" type="String">
+ <label></label>
+ </entry>
+
+ </group>
+
+ <group name="MaxMin">
+ <entry name="BandwidthRate" type="Int">
+ <label></label>
+ <default>3145</default>
+ </entry>
+ <entry name="BandwidthBurst" type="Int">
+ <label></label>
+ <default>6291</default>
+ </entry>
+ <entry name="MaxAdvertisedBandwidth" type="Int">
+ <label></label>
+ <default>3145</default>
+ </entry>
+
+ </group>
+
+ <group name="RunningNormal">
+ <entry name="User" type="String">
+ <label></label>
+ </entry>
+ <entry name="Group" type="String">
+ <label></label>
+ </entry>
+ <entry name="DataDirectory" type="String">
+ <label></label>
+ </entry>
+
+ </group>
+
+ <group name="RunningSpecial">
+
+
+ <entry name="DirServer" type="String">
+ <label></label>
+ </entry>
+ <entry name="ClientOnly" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+
+ </group>
+
+ <group name="UsingTor">
+
+ <entry name="SOCKSPolicy" type="StringList">
+ <label></label>
+ </entry>
+
+ <entry name="SOCKSBindAddressMany" type="StringList">
+ <label></label>
+ </entry>
+
+ </group>
+
+ <group name="UsingTorSpecial">
+
+ <entry name="SOCKSBindAddressHost" type="String">
+ <label></label>
+ <default>127.0.0.1</default>
+ </entry>
+ <entry name="SOCKSBindAddressPort" type="Int">
+ <label></label>
+ <default>9050</default>
+ </entry>
+
+ </group>
+
+ <group name="Servers">
+ <entry name="NewCircuitPeriod" type="Int">
+ <label></label>
+ <default>30</default>
+ </entry>
+ <entry name="AllowUnverifiedNodes" type="StringList">
+ <label></label>
+
+ </entry>
+ <entry name="MapAddress" type="StringList">
+ <label></label>
+
+ </entry>
+ <entry name="ExcludeNodes" type="StringList">
+ <label></label>
+
+ </entry>
+ <entry name="EntryNodes" type="StringList">
+ <label></label>
+
+ </entry>
+ <entry name="ExitNodes" type="StringList">
+ <label></label>
+
+ </entry>
+ <entry name="RendNodes" type="StringList">
+ <label></label>
+
+ </entry>
+ <entry name="StrictExitNodes" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="StrictEntryNodes" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="NumEntryGuards" type="Int">
+ <label></label>
+ <default>3</default>
+ </entry>
+ </group>
+
+ <group name="Usability">
+ <entry name="TrackHostExits" type="StringList">
+ <label></label>
+ </entry>
+ <entry name="LongLivedPorts" type="StringList">
+ <label></label>
+ <default>21,22,23,706,1863,5050,5190,5222,5223,6667,8300,8888</default>
+ </entry>
+ <entry name="MaxCircuitDirtiness" type="Int">
+ <label></label>
+ <default>600</default>
+ </entry>
+ <entry name="CookieAuthentication" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+ <entry name="HashedControlPassword" type="String">
+ <label></label>
+ </entry>
+
+ </group>
+
+ <group name="MyServer">
+
+ <entry name="ContactInfo" type="String">
+ <label></label>
+ </entry>
+
+ <entry name="PublishServerDescriptor" type="Bool">
+ <label></label>
+ </entry>
+
+ <entry name="ExitPolicy" type="StringList">
+ <label></label>
+ <default>reject *:25,reject *:119,reject *:135-139,reject *:445,reject *:465,reject *:563,reject *:587,reject *:1214,reject *:4661-4666,reject *:6346-6429,reject *:6699,reject *:6881-6999,accept *:*</default>
+ </entry>
+
+ <entry name="MyFamily" type="StringList">
+ <label></label>
+ </entry>
+
+ <entry name="NickName" type="String">
+ <label></label>
+ </entry>
+
+ <entry name="DirListenAddress" type="Int">
+ <label></label>
+ <default>9030</default>
+ </entry>
+
+ <entry name="DirPort" type="Int">
+ <label></label>
+ <default>9030</default>
+ </entry>
+
+ <entry name="ORListenAddress" type="Int">
+ <label></label>
+ <default>9001</default>
+ </entry>
+
+ <entry name="ORPort" type="Int">
+ <label></label>
+ <default>9001</default>
+ </entry>
+
+ <entry name="OutboundBindAddress" type="String">
+ <label></label>
+ </entry>
+
+ </group>
+
+ <group name="DefaultServerAddress">
+
+ <entry name="Address" type="String">
+ <label></label>
+ </entry>
+
+
+ </group>
+
+ <group name="ServerPerformance">
+
+ <entry name="NumCPUs" type="Int">
+ <label></label>
+ <default>1</default>
+ </entry>
+ <entry name="MaxOnionsPending" type="Int">
+ <label></label>
+ <default>100</default>
+ </entry>
+ <entry name="AccountingMax" type="Int">
+ <label></label>
+ <default>0</default>
+ </entry>
+ <entry name="AccountingStart" type="String">
+ <label></label>
+ <default>month</default>
+ </entry>
+ <entry name="ShutDownWaitLength" type="Int">
+ <label></label>
+ <default>30</default>
+ </entry>
+ <entry name="ConnLimit" type="Int">
+ <label></label>
+ <default>1000</default>
+ </entry>
+
+ </group>
+
+
+
+ <group name="DynDnsServer">
+
+ <entry name="DynDnsServerIP" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+ </group>
+
+ <group name="MyHiddenServices">
+ <entry name="HiddenServices" type="StringList">
+ <label></label>
+ </entry>
+
+ </group>
+
+ <group name="UsedDirectly">
+
+ <entry name="UseScheduledBandwidth" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="GenerateRandomPassword" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+
+ <entry name="ShowTorBar" type="Bool">
+ <default>true</default>
+ <label></label>
+ </entry>
+
+ <entry name="QuickConfigure" type="Int">
+ <label></label>
+ </entry>
+ <entry name="DefaultRunningNormalOptions" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+ <entry name="DefaultServerIP" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+ <entry name="DefaultServerPerformance" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+ <entry name="DefaultMaxMinOptions" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+ <entry name="KDEUsesTor" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+ <entry name="AlwaysAnonymizeKDE" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+ <entry name="StartPrivoxyAutomatically" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+
+ <entry name="serversHistory" type="StringList">
+ <label></label>
+ </entry>
+ <entry name="excludeServersHistory" type="StringList">
+ <label></label>
+ </entry>
+ <entry name="includeServersHistory" type="StringList">
+ <label></label>
+ </entry>
+
+ <entry name="ActiveServers" type="StringList">
+ <label></label>
+ </entry>
+
+ <entry name="ControlPort" type="Int">
+ <label></label>
+ <default>9051</default>
+ </entry>
+
+ <entry name="TrackHostExitsExpire" type="Int">
+ <label></label>
+ <default>30</default>
+ </entry>
+
+ <entry name="MiddleMan" type="Bool">
+ <label></label>
+ </entry>
+
+ <entry name="BridgeRelay" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="RemoteTor" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="RemoteTorAddress" type="String">
+ <label></label>
+ <default>127.0.0.1</default>
+ </entry>
+
+ <entry name="RemoteTorPort" type="Int">
+ <label></label>
+ <default>9051</default>
+ </entry>
+
+ <entry name="ShowTorMon" type="Bool">
+ <default>true</default>
+ </entry>
+
+ <entry name="NetstatLocation" type="String">
+ <default>netstat</default>
+ <label></label>
+ </entry>
+
+ <entry name="TorLocation" type="String">
+ <label></label>
+ </entry>
+
+ <entry name="PrivoxyLocation" type="String">
+ <label></label>
+ </entry>
+
+ <entry name="ApplyTorkSettings" type="Bool">
+ <default>false</default>
+ <label></label>
+ </entry>
+
+ <entry name="ShowDNSLeaks" type="Bool">
+ <default>true</default>
+ <label></label>
+ </entry>
+
+ <entry name="ShowUsageWarnings" type="Bool">
+ <default>true</default>
+ <label></label>
+ </entry>
+
+ <entry name="ShowSecurityWarnings" type="Bool">
+ <default>true</default>
+ <label></label>
+ </entry>
+
+ <entry name="ShowGuideQuestions" type="Bool">
+ <default>true</default>
+ <label></label>
+ </entry>
+
+ <entry name="ShowApplySettingsQuestions" type="Bool">
+ <default>true</default>
+ <label></label>
+ </entry>
+
+ <entry name="ExcludeCountries" type="StringList">
+ <label></label>
+ </entry>
+
+ <entry name="PreferredCountries" type="StringList">
+ <label></label>
+ </entry>
+
+ <entry name="OriginalHttpProxy" type="String">
+ <label></label>
+ </entry>
+
+ <entry name="OriginalHttpsProxy" type="String">
+ <label></label>
+ </entry>
+ <entry name="OriginalFtpProxy" type="String">
+ <label></label>
+ </entry>
+
+ <entry name="OriginalProxyType" type="String">
+ <label></label>
+ </entry>
+
+ <entry name="NonTorTrafficMaxEntries" type="Int">
+ <label></label>
+ <default>200</default>
+ </entry>
+
+ <entry name="SystemProxy" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="TorkProxy" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+
+
+ <entry name="KonqHttpProxy" type="String">
+ <label></label>
+ <default>http://localhost</default>
+ </entry>
+ <entry name="KonqHttpsProxy" type="String">
+ <default>http://localhost</default>
+ <label></label>
+ </entry>
+ <entry name="KonqFtpProxy" type="String">
+ <label></label>
+ </entry>
+ <entry name="KonqHttpProxyPort" type="Int">
+ <label></label>
+ <default>8118</default>
+ </entry>
+ <entry name="KonqHttpsProxyPort" type="Int">
+ <label></label>
+ <default>8118</default>
+ </entry>
+ <entry name="KonqFtpProxyPort" type="Int">
+ <label></label>
+ </entry>
+
+ <entry name="DisableJava" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+ <entry name="DisableCookies" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+ <entry name="DisableBrowserIdentification" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+ <entry name="DisablePlugins" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+ <entry name="DisableCaching" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+
+ <entry name="OriginalCookies" type="Bool">
+ <label></label>
+ </entry>
+ <entry name="OriginalSendUserAgent" type="Bool">
+ <label></label>
+ </entry>
+ <entry name="OriginalUseCache" type="Bool">
+ <label></label>
+ </entry>
+ <entry name="OriginalEnableJavascript" type="Bool">
+ <label></label>
+ </entry>
+ <entry name="OriginalEnableJava" type="Bool">
+ <label></label>
+ </entry>
+ <entry name="OriginalEnablePlugins" type="Bool">
+ <label></label>
+ </entry>
+
+ <entry name="LogTorTraffic" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+ <entry name="LogNonTorTraffic" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+
+ <entry name="ParanoidMode" type="Int">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="CurrentExcludeNodes" type="StringList">
+ <label></label>
+
+ </entry>
+ <entry name="CurrentEntryNodes" type="StringList">
+ <label></label>
+
+ </entry>
+ <entry name="CurrentExitNodes" type="StringList">
+ <label></label>
+ </entry>
+
+ <entry name="BandwidthSlots" type="StringList">
+ <label></label>
+ </entry>
+
+ <entry name="FilterRules" type="StringList">
+ <label></label>
+ <default>button_ok%:%Route all DNS UDP Requests to Tor. %:% iptables -t nat -I OUTPUT -o ! lo -p udp -m udp --dport 53 -j DNAT --to-destination 127.0.0.1:9999 -m comment --comment \"Redirect UDP DNS Requests to Tor\",button_ok%:%Route all DNS TCP Requests to Tor. %:% iptables -t nat -I OUTPUT -o ! lo -p tcp -m tcp --dport 53 -j DNAT --to-destination 127.0.0.1:9040 -m comment --comment \"Redirect TCP DNS Requests to Tor\" </default>
+ </entry>
+
+ <entry name="SystemFilterRules" type="StringList">
+ <label></label>
+ <default>button_ok%:%Route all HTTP Requests to Tor. %:% iptables -t nat -I OUTPUT -o ! lo -p tcp -m tcp --dport 80 -j DNAT --to-destination 127.0.0.1:9040 -m comment --comment \"Route all HTTP Requests to Tor\",button_ok%:%Route all HTTPS Requests to Tor. %:% iptables -t nat -I OUTPUT -o ! lo -p tcp -m tcp --dport 443 -j DNAT --to-destination 127.0.0.1:9040 -m comment --comment \"Route all HTTPS Requests to Tor\",button_ok%:%Route all secure POP3 Requests to Tor. %:% iptables -t nat -I OUTPUT -o ! lo -p tcp -m tcp --dport 995 -j DNAT --to-destination 127.0.0.1:9040 -m comment --comment \"Route all secure POP3 Requests to Tor\",button_ok%:%Route all SSH Requests to Tor. %:% iptables -t nat -I OUTPUT -o ! lo -p tcp -m tcp --dport 22 -j DNAT --to-destination 127.0.0.1:9040 -m comment --comment \"Route all SSH Requests to Tor\"</default>
+ </entry>
+
+ <entry name="DNSFailSafeParanoia" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="SystemFailSafeParanoia" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+
+ <entry name="CurrentTorVersion" type="String">
+ <label></label>
+ </entry>
+
+ <entry name="DefaultBandwidthRate" type="Int">
+ <label></label>
+ <default>3145</default>
+ </entry>
+ <entry name="DefaultBandwidthBurst" type="Int">
+ <label></label>
+ <default>6291</default>
+ </entry>
+ <entry name="DefaultMaxAdvertisedBandwidth" type="Int">
+ <label></label>
+ <default>3145</default>
+ </entry>
+
+ <entry name="DefaultNumCPUs" type="Int">
+ <label></label>
+ <default>1</default>
+ </entry>
+ <entry name="DefaultMaxOnionsPending" type="Int">
+ <label></label>
+ <default>100</default>
+ </entry>
+ <entry name="DefaultAccountingMax" type="Int">
+ <label></label>
+ <default>0</default>
+ </entry>
+ <entry name="DefaultAccountingStart" type="String">
+ <label></label>
+ <default>month</default>
+ </entry>
+ <entry name="DefaultShutDownWaitLength" type="Int">
+ <label></label>
+ <default>30</default>
+ </entry>
+ <entry name="DefaultConnLimit" type="Int">
+ <label></label>
+ <default>1000</default>
+ </entry>
+
+ <entry name="DisplayBubble" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+
+ <entry name="BridgeORPort" type="Int">
+ <label></label>
+ <default>8081</default>
+ </entry>
+
+ <entry name="DefaultORPort" type="Int">
+ <label></label>
+ <default>9001</default>
+ </entry>
+
+ <entry name="DefaultDirPort" type="Int">
+ <label></label>
+ <default>9030</default>
+ </entry>
+
+ <entry name="AdvancedMode" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="AvailablePrograms" type="StringList">
+ <label></label>
+ </entry>
+
+ <entry name="ForwardPorts" type="Bool">
+ <label></label>
+ <default>false</default>
+ </entry>
+
+ <entry name="RunFirstServerWizard" type="Bool">
+ <label></label>
+ <default>true</default>
+ </entry>
+
+ </group>
+
+
+</kcfg>
diff --git a/src/torkconfig.kcfgc b/src/torkconfig.kcfgc
new file mode 100644
index 0000000..b298a03
--- /dev/null
+++ b/src/torkconfig.kcfgc
@@ -0,0 +1,7 @@
+# Code generation options for kconfig_compiler
+File=torkconfig.kcfg
+ClassName=TorkConfig
+Singleton=true
+Mutators=true
+MemberVariables=private
+
diff --git a/src/torkui.rc b/src/torkui.rc
new file mode 100644
index 0000000..8585219
--- /dev/null
+++ b/src/torkui.rc
@@ -0,0 +1,61 @@
+<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+<kpartgui name="TorK" version="1">
+<MenuBar noMerge="1">
+ <Menu name="Tor"><text>&amp;Tor</text>
+ <Action name="start_tor" />
+ <Action name="stop_tor" />
+ <Separator lineSeparator="true"/>
+ <Action name="enable_konqi" />
+ <Action name="enable_tormon" />
+ <Separator lineSeparator="true"/>
+ <Action name="toggle_torbar" />
+ <Separator lineSeparator="true"/>
+ <Action name="quit"/>
+ </Menu>
+ <Menu name="Tools"><text>&amp;Tools</text>
+ <Action name="hidden_services" />
+ <Action name="network_list" />
+ <Separator lineSeparator="true"/>
+ <Action name="update_torstable" />
+ <Action name="update_torunstable" />
+ <Separator lineSeparator="true"/>
+ <Action name="update_privoxy" />
+ <Separator lineSeparator="true"/>
+ <Action name="update_tork" />
+ <Separator lineSeparator="true"/>
+ <Action name="firstrun_wizard" />
+ </Menu>
+
+ <Menu name="settings"><text>&amp;Settings</text>
+ <Merge name="StandardToolBarMenuHandler"/>
+ <Separator />
+ <Action name="options_configure_keybinding"/>
+ <Action name="options_configure_toolbars"/>
+ <Action name="configure_tor" />
+ </Menu>
+
+ <Menu name="help"><text>&amp;Help</text>
+ <Action name="help_contents"/>
+ <Action name="help_plugins_contents"/>
+ <Action name="help_whats_this"/>
+ <Action name="help_show_tip" />
+ <Separator/>
+ <Action name="help_report_bug"/>
+ <Separator/>
+ <Action name="switch_application_language"/>
+ <Separator/>
+ <Action name="help_about_app"/>
+ <Action name="help_about_kde"/>
+ </Menu>
+
+</MenuBar>
+<ToolBar name="mainToolBar" noMerge="1"><text>Main Toolbar</text>
+ <Action name="configure_tor" />
+</ToolBar>
+<ToolBar name="TorToolBar" noMerge="1"><text>TorK Toolbar</text>
+ <Action name="enable_tormon" />
+</ToolBar>
+<ToolBar name="MoreToolBar" noMerge="1"><text>More Toolbar</text>
+</ToolBar>
+
+</kpartgui>
diff --git a/src/torkview.cpp b/src/torkview.cpp
new file mode 100644
index 0000000..eed8c8b
--- /dev/null
+++ b/src/torkview.cpp
@@ -0,0 +1,2103 @@
+/***************************************************************************
+ ** $Id: torkview.cpp,v 1.125 2009/11/07 14:21:56 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <sys/time.h>
+
+#include "torkview.h"
+#include "tork.h"
+#include "torclient.h"
+#include <klocale.h>
+#include <qlabel.h>
+#include <qlistview.h>
+#include "dndlistview.h"
+#include "portsandicons.h"
+#include "torkconfig.h"
+#include "chart.h"
+#include "functions.h"
+#include "mixminion.h"
+#include "crypto.h"
+
+#include "hitwidget.h"
+#include "kwidgetlistbox.h"
+#include "kerrylabel.h"
+
+
+#ifndef EXTERNAL_GEOIP
+# include "GeoIP-1.4.0/libGeoIP/GeoIP.h"
+#else
+# include <GeoIP.h>
+#endif
+
+#include "kdebug.h"
+#include <kstandarddirs.h>
+#include <kiconloader.h>
+#include <kmimetype.h>
+#include <ksystemtray.h>
+#include <kprocio.h>
+#include <kmessagebox.h>
+#include <krun.h>
+#include <kurl.h>
+#include <kio/netaccess.h>
+
+#include <qregexp.h>
+#include <qsplitter.h>
+#include <qgroupbox.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qpixmap.h>
+/* Linux-specific includes */
+#include <dirent.h>
+#include <unistd.h>
+#include "../config.h"
+
+using namespace tk;
+
+
+#define MAX_BW_RATE 2
+#define MAX_CG_RATE 60*5
+#define MAX_TN_RATE 60*20
+#define MAX_CBWS_RATE 60
+
+torkView::torkView(QWidget *parent)
+ : torkview_base(parent), m_pop(0L), m_tormon(TorkConfig::showTorMon()), torbtx(0), torbrx(0)
+{
+
+#ifndef EXTERNAL_GEOIP
+ geoip_db = !locate("data", "tork/geoip/GeoIP.dat").isNull();
+#else
+ GeoIP * gi = 0;
+ gi = GeoIP_new(GEOIP_STANDARD);
+ if (gi)
+ geoip_db = true;
+ else
+ geoip_db = false;
+#endif
+
+ greenonion << "green" << "up" << "built" << "good" << "connected" << "succeeded";
+ redonion << "red" << "down" << "bad" << "failed";
+ yellowonion << "yellow" << "sentconnect";
+ orangeonion << "orange" << "sentresolve";
+ littleonion << "little" << "launched" << "new" << "detached";
+ todelete << "todelete" << "closed" << "failed" << "dropped";
+ iconList << greenonion << redonion << yellowonion << orangeonion << littleonion;
+
+ guard << "up" << "up" << "built" << "good" << "connected";
+ redguard << "red" << "down" << "bad" << "dropped" << "unusable" << "failed";
+ detachedguard << "detached" << "never-connected" << "unlisted" << "succeeded";
+ littleguard << "little" << "new" << "sentresolve" << "sentconnect";
+ guardIconList << guard << redguard << detachedguard << littleguard;
+
+ greenonion << "green" << "built";
+ redonion << "red" << "failed";
+ yellowonion << "yellow" << "extended";
+ littleonion << "little" << "launched";
+ circuitIconList << greenonion << redonion << yellowonion << littleonion;
+
+
+ torType += i18n("running a Tor Client and Server With Default Settings");
+ torType += i18n("running a Tor Client and Relay Server With Default Settings");
+ torType += i18n("running a Tor Server With Default Settings");
+ torType += i18n("running a Tor Relay Server With Default Settings");
+ torType += i18n("running a Tor Client with Default Settings");
+ torType += i18n("running an instance of Tor using all the settings in the configure dialog");
+ torType += i18n("connected to a Remote Instance of Tor");
+ torType += i18n("connected to a Local Instance of Tor");
+
+ streamPurpose["DIR_FETCH"] = "Tor(Directory Fetch)";
+ streamPurpose["DNS_REQUEST"] = "Tor(DNS)";
+ streamPurpose["UPLOAD_DESC"] = "Tor(Upload Descriptor)";
+ streamPurpose["DIRPORT_TEST"] = "Tor(Server Test)";
+
+
+ mFirstUpdate = true;
+
+ if (checkInterface())
+ gotEth0 = true;
+ else
+ gotEth0 = false;
+
+ if (!TorkConfig::showTorBar())
+ frame4->hide();
+
+ settingsChanged();
+
+ populateMenu();
+
+ menuItems << sshitem << gpgitem << telnetitem << kopeteitem << ksircitem;
+ menuItems << allpurposeitem << konversationitem << pidginitem << gaimitem << operaitem << firefoxitem;
+ menuItems << hiddenservicesitem << konqitem << mixminionitem;
+
+ for ( QValueList<HitWidget*>::Iterator it = menuItems.begin(); it != menuItems.end(); ++it ){
+ if (*it)
+ (*it)->setEnabled(false);
+ }
+
+ resetBWHistory();
+
+ Chart* chart = new Chart(ChartFrame, speedHistoryTx(), speedHistoryRx(),
+ historyBufferSize(), historyPointer(), maxSpeed(),
+ sys_speedHistoryTx(), sys_speedHistoryRx(),
+ sys_historyBufferSize(), sys_historyPointer(), sys_maxSpeed(), gotEth0);
+ chart->setMinimumWidth(ChartFrame->width());
+ chart->setMinimumHeight(ChartFrame->height());
+
+ connect(this, SIGNAL(updateStats()), chart, SLOT(update()));
+
+
+ m_osd = new StreamOSD(this, true);
+ m_osd->readSettings(KGlobal::config());
+
+ m_nontorosd = new StreamOSD(this, false);
+ m_nontorosd->readSettings(KGlobal::config());
+
+ //Icons showing the status of the stream
+ streamStatusIcon["SUCCEEDED"] = QPixmap(SmallIcon("tork_green"));
+ streamStatusIcon["FAILED"] = QPixmap(SmallIcon("tork_red"));
+ streamStatusIcon["SENTCONNECT"] = QPixmap(SmallIcon("tork_yellow"));
+ streamStatusIcon["SENTRESOLVE"] = QPixmap(SmallIcon("tork_orange"));
+ streamStatusIcon["NEW"] = QPixmap(SmallIcon("tork_little"));
+ streamStatusIcon["DETACHED"] = QPixmap(SmallIcon("tork_little"));
+ streamStatusIcon["CLOSED"] = QPixmap(SmallIcon("tork_todelete"));
+ progDisplayCounter = 0;
+}
+
+void torkView::resetBWHistory() {
+
+ memset(mSpeedHistoryRx, 0, sizeof(double)*HISTORY_SIZE);
+ memset(mSpeedHistoryTx, 0, sizeof(double)*HISTORY_SIZE);
+ memset(mSpeedBufferRx, 0, sizeof(double)*SPEED_BUFFER_SIZE);
+ memset(mSpeedBufferTx, 0, sizeof(double)*SPEED_BUFFER_SIZE);
+ mMaxSpeedAge = 0;
+ mMaxSpeed = 0.0;
+ mSpeedBufferPtr = mSpeedHistoryPtr = 0;
+ mBRx = mBTx = 0;
+
+ memset(sys_mSpeedHistoryRx, 0, sizeof(double)*HISTORY_SIZE);
+ memset(sys_mSpeedHistoryTx, 0, sizeof(double)*HISTORY_SIZE);
+ memset(sys_mSpeedBufferRx, 0, sizeof(double)*SPEED_BUFFER_SIZE);
+ memset(sys_mSpeedBufferTx, 0, sizeof(double)*SPEED_BUFFER_SIZE);
+ sys_mMaxSpeedAge = 0;
+ sys_mMaxSpeed = 0.0;
+ sys_mSpeedBufferPtr = sys_mSpeedHistoryPtr = 0;
+ sysmBRx = sysmBTx = 0;
+
+ mFirstUpdate = true;
+ torbtx = 0;
+ torbrx = 0;
+}
+
+void torkView::updateChart() {
+
+ emit updateStats();
+
+}
+
+void torkView::changeQuickConfigure(int no) {
+
+/* QValueList<int> qconf;
+ qconf << 4 << 2 << 3 << 5 << 6 << 7;*/
+ TorkConfig::setQuickConfigure(no);
+}
+
+void torkView::clearStreamMaps() {
+
+ streams.clear();
+ osdstreams.clear();
+ circuitExits.clear();
+ streamBwIn.clear();
+ streamBwOut.clear();
+ logstreams.clear();
+ cachedStreamIcon.clear();
+ torservers.clear();
+}
+
+void torkView::downloadTorButton() {
+
+ int result = KMessageBox::questionYesNo(0,
+ i18n( "<p>Once you install TorButton, restart Firefox from here "
+ "rather than letting Firefox restart automatically. This will"
+ " ensure you do not browse with your normal Firefox "
+ "profile.<br> <b>Continue?</b></p>")
+ ,i18n( "Be sure to restart Firefox from Tork!" ));
+
+ switch (result) {
+ case KMessageBox::Yes :
+ anonymizedFirefox( "http://www.torproject.org/torbutton/torbutton-current.xpi");
+ }
+
+}
+
+void torkView::downloadMixminion() {
+
+
+ TorkUpdate* updater = new TorkUpdate(this);
+ updater->downloadMixminion();
+
+}
+
+void torkView::sendAnonymousEmail() {
+
+
+ if (TorkConfig::availablePrograms().contains("mixminion")){
+ QString caption;
+ QString message;
+ caption = i18n("Mixminion Not Installed!");
+ message = i18n("<p>Mixminion does not appear to be installed on your system.<br>");
+ message += i18n("<p><b>Try installing it from the main interface.</b><br>");
+ KMessageBox::information (this, message, caption);
+ return;
+ }
+
+ MixMinionClient* mixminion = new MixMinionClient();
+ mixminion->show();
+
+}
+
+bool torkView::checkInterface() {
+
+ bool gotone = false;
+ //Would anyone have this many ethernet cards?
+ QStringList devices;
+ devices << "eth" << "wlan";
+ for ( QStringList::Iterator it = devices.begin(); it != devices.end(); ++it ){
+ for (int i=0; i < 5; i++){
+ QString devpath = QString("/sys/class/net/%1%2").arg((*it)).arg(i);
+ QDir ethdir(devpath);
+ if (ethdir.exists()){
+ mSysDevPathList.append(devpath);
+ gotone = true;
+ }else
+ continue;
+ }
+ }
+
+ return gotone;
+}
+
+void torkView::torify(const QString& text)
+{
+
+ QString command = "usewithtor " + text;
+ QString icon = text.section(" ",0,0);
+ KRun::runCommand( command, icon, icon );
+
+}
+
+void torkView::anonymousFirefox()
+{
+ anonymizedFirefox("http://healthcheck.anonymityanywhere.com/");
+}
+
+void torkView::anonymizedFirefox(const QString& url)
+{
+ QString text = "firefox";
+ QString firefoxdir = QString("%1/.mozilla/firefox").arg(getenv("HOME"));
+
+ QString torkfirefox = QString("%1/tork.TorkAnonymous").arg(firefoxdir);
+ QDir torkdir(torkfirefox);
+ if (!torkdir.exists()){
+
+ QFile inf(QString("%1/profiles.ini").arg(firefoxdir));
+ QString line;
+ int profileno=0;
+ if ( inf.open(IO_ReadOnly) ) {
+ QTextStream stream( &inf );
+
+ while ( !stream.atEnd() ) {
+ line = stream.readLine(); // line of text excluding '\n'
+ if (line.contains("[Profile")){
+ QRegExp rx("([0-9]{1,4})");
+ rx.search(line);
+ profileno = rx.cap(0).toInt() + 1;
+ }
+ if (line.contains(".default"))
+ break;
+ }
+ inf.close();
+ }else{
+ emit processWarning("cantreadprofiles",i18n("Can't read %1")
+ .arg(QString("%1/profiles.ini").arg(firefoxdir)));
+ KIO::NetAccess::del(torkfirefox,0L);
+ return;
+ }
+
+ QString originalprofile = line.replace("Path=","");
+ QString originalfirefox = QString("%1/%2").arg(firefoxdir).arg(originalprofile);
+
+ if (!KIO::NetAccess::dircopy(originalfirefox,torkfirefox, 0L))
+ {
+ emit processWarning("cantcopyprofile",i18n("Can't copy %1").arg(originalfirefox));
+ KIO::NetAccess::del(torkfirefox,0L);
+ return;
+ }
+
+
+ //Update Profile
+ QFile inf2(QString("%1/profiles.ini").arg(firefoxdir));
+ if ( inf2.open(IO_WriteOnly | IO_Append) ) {
+
+ QTextStream ts( &inf2 );
+ ts << "\n";
+ ts << "[Profile" << profileno << "]" << "\n";
+ ts << "Name=TorkAnonymous" << "\n";
+ ts << "IsRelative=1" << "\n";
+ ts << "Path=tork.TorkAnonymous" << "\n";
+ ts << "\n";
+ inf2.close();
+ }else{
+ emit processWarning("cantreadprofiles",i18n("Can't read %1")
+ .arg(QString("%1/profiles.ini").arg(firefoxdir)));
+ KIO::NetAccess::del(torkfirefox,0L);
+ return;
+ }
+
+ }
+
+ //Update Profile
+ QFile inf3(QString("%1/prefs.js").arg(torkfirefox));
+ if ( inf3.open(IO_WriteOnly | IO_Append) ) {
+
+ QTextStream ts( &inf3 );
+
+ ts << "user_pref(\"network.proxy.ftp\", \"\");" << "\n";
+ ts << "user_pref(\"network.proxy.ftp_port\", 0);" << "\n";
+ ts << "user_pref(\"network.proxy.gopher\", \"\");" << "\n";
+ ts << "user_pref(\"network.proxy.gopher_port\", 0);" << "\n";
+ ts << "user_pref(\"network.proxy.http\", \"" << TorkConfig::konqHttpProxy().replace("http://","") << "\");" << "\n";
+ ts << "user_pref(\"network.proxy.http_port\", " << TorkConfig::konqHttpProxyPort() << ");" << "\n";
+ ts << "user_pref(\"network.proxy.share_proxy_settings\", true);" << "\n";
+ ts << "user_pref(\"network.proxy.ssl\", \"" << TorkConfig::konqHttpsProxy().replace("http://","") << "\");" << "\n";
+ ts << "user_pref(\"network.proxy.ssl_port\", " << TorkConfig::konqHttpsProxyPort() << ");" << "\n";
+ ts << "user_pref(\"network.proxy.type\", 1);" << "\n";
+ //Java/Javascript disabled
+ ts << "user_pref(\"javascript.enabled\", false);" << "\n";
+ ts << "user_pref(\"pref.advanced.javascript.disable_button.advanced\", false);" << "\n";
+ ts << "user_pref(\"security.enable_java\", false);" << "\n";
+ //Cookies Disabled
+ ts << "user_pref(\"network.cookie.cookieBehavior\", 2);" << "\n";
+ //Point SOCKS to Tor
+ ts << "user_pref(\"network.proxy.socks\", \"" << TorkConfig::sOCKSBindAddressHost().replace("http://","") << "\");" << "\n";
+ ts << "user_pref(\"network.proxy.socks_port\", " << TorkConfig::sOCKSBindAddressPort() << ");" << "\n";
+ ts << "user_pref(\"network.proxy.socks_version\", 5);" << "\n";
+
+ //Ensure dns requests go through proxy
+ ts << "user_pref(\"network.proxy.socks_remote_dns\", true);" << "\n";
+ //Tor doesn't do IPv6
+ ts << "user_pref(\"network.dns.disableIPv6\", true);" << "\n";
+
+ //Additional settings taken from TorToGo
+ //
+
+ //Disable Auto-Updating of Extensions
+ ts << "user_pref(\"extensions.update.autoUpdateEnabled\", false);" << "\n";
+ ts << "user_pref(\"extensions.update.autoUpdate\",false);" << "\n";
+ ts << "user_pref(\"extensions.update.enabled\",false);" << "\n";
+
+ //Disable Auto-Updating of Firefox
+ ts << "user_pref(\"app.update.auto\",false);" << "\n";
+ ts << "user_pref(\"app.update.enabled\",false);" << "\n";
+
+ //Disable Updating of Searchbar
+ ts << "user_pref(\"browser.search.update\",false);" << "\n";
+
+ //No compression. Compression can prevent munging of environmental variables
+ ts << "user_pref(\"network.http.accept-encoding:gzip;q=0,deflate;q=0,compress;q=0\",false);" << "\n";
+ // --Accept MIME type
+ ts << "user_pref(\"network.http.accept.default:text/xml,application/xml, application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5);" << "\n";
+
+ //--English non-localized
+ ts << "user_pref(\"intl.accept_languages\",en);" << "\n";
+ ts << "user_pref(\"intl.accept_charsets\",ISO-8859-1,*);" << "\n";
+
+ //~User Agent/Anonymity Set (This will create a large anonymity set for Tor users):
+
+ ts << "user_pref(\"general.useragent.override\",Mozilla/5.0 (Windows; U; Windows NT 5.1; en; rv:1.7.10) Gecko/20050716 Firefox/1.5.0.7);" << "\n";
+ // --Spoof the version of Firefox in use (real version is v.2.0.0.3rc)
+ ts << "user_pref(\"general.useragent.extra.firefox\",Firefox/1.5.0.7);" << "\n";
+ //--Required to match "intl.accept_languages" above
+ ts << "user_pref(\"general.useragent.locale\",en);" << "\n";
+ ts << "user_pref(\"extensions.torbutton.tor_enabled\", true);" << "\n";
+ inf3.close();
+
+ }else{
+ emit processWarning("cantwritefirefoxsettings", i18n("Can't write to %1").arg(QString("%1/prefs.js").arg(torkfirefox)));
+ KIO::NetAccess::del(torkfirefox,0L);
+ return;
+ }
+
+ KRun::runCommand( QString("%1 -P TorkAnonymous %2").arg(text).arg(url), text, text );
+
+
+}
+
+void torkView::anonymousOpera()
+{
+ anonymizedOpera("http://healthcheck.anonymityanywhere.com/");
+}
+
+void torkView::anonymizedOpera(const QString& url)
+{
+
+ QString text = "opera";
+ QString originalopera = QString("%1/.opera").arg(getenv("HOME"));
+ QString torkopera = QString("%1/.opera-tork").arg(getenv("HOME"));
+ QDir torkdir(torkopera);
+ if (!torkdir.exists())
+ KIO::NetAccess::dircopy(originalopera,torkopera,0L);
+
+ QFile inf(QString("%1/.opera-tork/opera6.ini").arg(getenv("HOME")));
+ if ( inf.open(IO_WriteOnly | IO_Append) ) {
+
+ QTextStream ts( &inf );
+
+ ts << "[Proxy]" << "\n";
+ ts << "HTTPS server=" << TorkConfig::konqHttpsProxy() << ":" << TorkConfig::konqHttpsProxyPort() << "\n";
+ ts << "HTTP server=" << TorkConfig::konqHttpProxy() << ":" << TorkConfig::konqHttpProxyPort() << "\n";
+ ts << "Use HTTP=1" << "\n";
+ ts << "Use HTTPS=1" << "\n";
+ ts << "Use Automatic Proxy Configuration=0" << "\n";
+
+ ts << "[Java]" << "\n";
+ ts << "Enabled=0" << "\n";
+ ts << "[Extensions]" << "\n";
+ ts << "Scripting=0" << "\n";
+ ts << "Plugins=0" << "\n";
+
+ ts << "[User Prefs]" << "\n";
+ ts << "Enable Cookies=0" << "\n";
+
+ inf.close();
+ KRun::runCommand( QString("%1 -personaldir %2 -newpage %3").arg(text).arg(torkopera).arg(url), text, text );
+
+ }
+
+
+}
+
+void torkView::privoxiedBash()
+{
+
+ QString location = getenv("HOME");
+ location += "/.tork";
+ QDir torkdir(location);
+ if (!torkdir.exists() && !torkdir.mkdir(location))
+ location = getenv("HOME");
+
+ QFile inf(QString("%1/privoxy_konsole_session").arg(location));
+ if (! inf.open(IO_WriteOnly) ) {
+ inf.close();
+ KMessageBox::information (this,"Couldn't create bash session file!");
+ return ;
+ }
+
+ QTextStream ts( &inf );
+/* QTextStream &ts = *(inf.textStream());*/
+
+ ts << QString("http_proxy=%1:%2").arg(TorkConfig::konqHttpProxy()).arg(TorkConfig::konqHttpProxyPort()) << "\n";
+ ts << QString("https_proxy=%1:%2").arg(TorkConfig::konqHttpsProxy()).arg(TorkConfig::konqHttpsProxyPort()) << "\n";
+ ts << "HTTP_PROXY=$http_proxy" << "\n";
+ ts << "HTTPS_PROXY=$https_proxy" << "\n";
+ ts << "export HTTP_PROXY HTTP_PROXY http_proxy https_proxy" << "\n";
+ ts << "echo Using $http_proxy and $https_proxy as a privacy proxy in this bash session." << "\n";
+ ts << "echo Using commands such as 'su' will cease use of the privacy proxy." << "\n";
+
+
+ inf.close();
+
+ KRun::runCommand( QString("konsole --caption 'Shell Using Privoxy for Http requests - Launched From TorK' --noclose -e bash --init-file %1").arg(inf.name()), "konsole", "konsole" );
+
+}
+
+void torkView::toggleParanoidMode(int id)
+{
+
+ switch(id)
+ {
+ case 0:
+ paranoidmodeicon->setPixmap(SmallIcon("tork_penguin"));
+ paranoidmodetext->setText(i18n("In Normal mode!"));
+ break;
+ case 1:
+ paranoidmodeicon->setPixmap(SmallIcon("tork_agent"));
+ paranoidmodetext->setText(i18n("In DNS FailSafe mode!"));
+ break;
+ case 2:
+ paranoidmodeicon->setPixmap(SmallIcon("gv"));
+ paranoidmodetext->setText(i18n("In System FailSafe mode!"));
+ break;
+ default:
+ return;
+ }
+
+ TorkConfig::setParanoidMode(id);
+
+}
+
+void torkView::toggleAnonymizerTork(bool state)
+{
+
+ welcomeitem->setEnabled(true);
+
+ disconnect(welcomeitem->icon, SIGNAL(leftClickedURL()), this, SIGNAL(startEverything()));
+ disconnect(welcomeitem->icon, SIGNAL(leftClickedURL()), this, SIGNAL(stopEverything()));
+
+ if (state){
+ connect(welcomeitem->icon, SIGNAL(leftClickedURL()), SIGNAL(stopEverything()));
+ welcomeheaderLabel->setText(i18n("Welcome to the Tor Network!"));
+ welcomeitem->setIcon("tork_stop");
+ welcomeitem->setDescriptionText("<qt>"+i18n("- <b>You are %1.</b><br>"
+ ).arg(torType[TorkConfig::quickConfigure()])+"</qt>");
+ welcomeitem->setPropertiesText("<qt>"+i18n(
+ "- The 'Tor Network' tab shows you the state of the Tor network, including your Tor Traffic. <br> "
+ "- You can use the 'Traffic Log' tab to view Tor and Non-Tor Traffic on your system.<br> "
+ "- You can use the 'Tor Log' tab to view warning messages from Tor itself. <br> "
+ "- Try out the services listed below. <br> "
+ )+"</qt>");
+
+
+ setHiddenServicesText();
+
+ welcomeitem->score->setEnabled(false);
+ for ( QValueList<HitWidget*>::Iterator it = menuItems.begin(); it != menuItems.end(); ++it ){
+ if (*it)
+ (*it)->setEnabled(true);
+ }
+
+ }else{
+ connect(welcomeitem->icon, SIGNAL(leftClickedURL()), SIGNAL(startEverything()));
+ welcomeitem->setIcon("tork_pressplay");
+ welcomeheaderLabel->setText(i18n("Press 'Play' to get started!"));
+ welcomeitem->setDescriptionText("<qt>"+i18n("- <b>Press 'Play' to connect to Tor. (You can also use the toolbar icons.)</b><br>"
+ )+"</qt>");
+ welcomeitem->setPropertiesText("<qt>"+i18n(
+ "- The 'Tor Network' tab shows you the state of the Tor network, including your Tor Traffic. <br> "
+ "- You can use the 'Traffic Log' tab to view Tor and Non-Tor Traffic on your system.<br> "
+ "- You can use the 'Tor Log' tab to view warning messages from Tor itself. <br> "
+ "- Once Tor is up and running you can use the services listed below. <br> "
+ )+"</qt>");
+
+ welcomeitem->score->setEnabled(true);
+ setHiddenServicesText();
+
+ for ( QValueList<HitWidget*>::Iterator it = menuItems.begin(); it != menuItems.end(); ++it ){
+ if (*it)
+ (*it)->setEnabled(false);
+ }
+
+
+ }
+}
+
+void torkView::setHiddenServicesText()
+{
+
+ QString activeHiddenServices;
+ QStringList hiddenServices = TorkConfig::hiddenServices();
+ for ( QStringList::Iterator it = hiddenServices.begin(); it != hiddenServices.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ if (!(*it).section("\n",-2,-2).isEmpty())
+ activeHiddenServices.append(i18n("<b>%1</b> (serving files from <i>%2</i>)").arg((*it).section("\n",-6,-6)).arg((*it).section("\n",-2,-2)));
+ else
+ activeHiddenServices.append(i18n("<b>%1</b> (redirecting to <i>%2</i>)").arg((*it).section("\n",-6,-6)).arg((*it).section("\n",-3,-3)));
+
+ }
+
+ if (!activeHiddenServices.isEmpty()){
+ hiddenservicesitem->setPropertiesText("<qt>"+i18n(
+ "- You are running the following hidden services:<br>&nbsp;&nbsp;&nbsp;&nbsp;%1<br>"
+ ).arg(activeHiddenServices)+"</qt>");
+ }else{
+ hiddenservicesitem->setPropertiesText("<qt>"+i18n(
+ "- Anonymous web sites/web services are known as 'hidden services'. <br>"
+ "- Their location and ownership are concealed by the operation of the Tor network.<br>"
+ )+"</qt>");
+ }
+
+}
+
+torkView::~torkView()
+{
+
+}
+
+#define MAXPROGDISPLAY 5
+
+void torkView::streamStatusUpdated(const QString &streamID, const QString &status,
+ const QString &circID, const QString &Target, const QString &info)
+{
+
+
+ QString tmpstatus = status.stripWhiteSpace();
+
+ streamItem* streamline;
+ QListViewItem* osdstreamline;
+ QListViewItem* torTrafficLine;
+
+ torTrafficLine=0L;
+
+ if (!(streamline = streams[streamID])){
+ if (!(tmpstatus == "CLOSED") && !(tmpstatus == "FAILED")){
+ m_osd->setShown(m_tormon);
+ m_osd->infoList->adjustColumn(1);
+ infoList->adjustColumn(2);
+
+ timeLastTorUse = QTime::currentTime();
+
+ QString cleanedFullTarget = Target;
+ cleanedFullTarget.replace(QRegExp("(\\.\\$[A-Z0-9]{40})\\."),".");
+ QString cleanedTarget = cleanedFullTarget.section(":",0,0);
+ QString cleanedPort = cleanedFullTarget.section(":",1,1);
+ addrLastTorUse = cleanedFullTarget;
+
+ if (TorkConfig::paranoidMode() > 0)
+ emit newIdentity();
+
+ // Find the program associated with the stream
+ QString program = "..";
+ QPixmap programicon;
+
+ if ((tmpstatus == "NEW")){
+ if (info.contains("PURPOSE=USER")){
+ QRegExp rx("(SOURCE_ADDR=127.0.0.1:[0-9]+ )");
+ rx.search(info);
+ QString port = rx.cap(0).section("SOURCE_ADDR=127.0.0.1:",-1)
+ .stripWhiteSpace();
+ portStream[streamID] = port;
+ }else{
+ QString purpose = info.section("PURPOSE=",-1,-1);
+ program = streamPurpose[purpose];
+ programicon = QPixmap(SmallIcon("tork_tor"));
+ }
+ }
+
+ // Assign the circuit and exit server to the stream
+ circuitItem* circuitline;
+ QString circuit = "Pending..";
+ QString exitserver;
+ QPixmap exitserverflag;
+ // Don't look for circuit if one hasn't been assigned yet
+ if (circID != "0") {
+ if ((circuitline = (circuitItem*)
+ circuitList->findItem(circID,0)) != 0){
+ QListViewItem* serverline;
+ if ((serverline = (QListViewItem*) circuitExits[circID]) != 0){
+ exitserver = serverline->text(1);
+ exitserverflag = *serverline->pixmap(1);
+ }
+ circuit = circuitline->text(2);
+ }
+ }
+
+ //Assign an icon to illustrate the type of stream
+ QPixmap icon = cachedStreamIcon[cleanedFullTarget];
+ if (icon.isNull()){
+
+ QString iconPath = locate("cache",
+ KMimeType::favIconForURL("http://"+cleanedTarget)
+ +".png");
+
+ if (!iconPath.isEmpty()){
+
+ icon.load( iconPath );
+ if (cleanedPort == "443"){
+ QPixmap overlay = KSystemTray::loadIcon( "tork_ssl" );
+
+ if ( !overlay.isNull() )
+ {
+ int x = icon.width() - overlay.width();
+ int y = icon.height() - overlay.height();
+ if ( icon.mask() )
+ {
+ QBitmap mask = *icon.mask();
+ bitBlt( &mask, x, y,
+ overlay.mask() ?
+ const_cast<QBitmap*>(overlay.mask()) : &overlay,
+ 0, 0, overlay.width(), overlay.height(),
+ overlay.mask() ? OrROP : SetROP );
+ icon.setMask(mask);
+ }
+ bitBlt( &icon, x, y, &overlay );
+ }
+ }
+
+ }else{
+ int i;
+ for (i = 0; _port_icon[i].port; ++i) {
+ portsandicons_t *pics = &_port_icon[i];
+ if (cleanedPort == pics->port){
+ icon = SmallIcon(pics->icon);
+ if ((!pics->secure) && (!pics->display)){
+ pics->display = DONT_DISPLAY_AGAIN;
+ if (pics->screaminglyinsecure)
+ emit showScreamingNotice(cleanedPort);
+ else
+ emit showSecurityNotice(cleanedPort);
+ }
+ }
+ }
+ }
+ cachedStreamIcon[cleanedFullTarget] = icon;
+ }
+
+ //Assign an icon to illustrate the stream status
+ QPixmap statusicon = streamStatusIcon[tmpstatus];
+
+ //Display the entries in the UI
+
+ //Add to the traffic log if necessary
+ if (TorkConfig::logTorTraffic()){
+ torTrafficLine = new QListViewItem(TorTraffic, streamID,
+ QDateTime::currentDateTime().
+ toString(Qt::ISODate).
+ replace("T"," "),
+ cleanedFullTarget,
+ circuit);
+ torTrafficLine->setPixmap( 2, icon );
+ }
+
+ // The stream in the 'Connections' Pane
+ streamline = new streamItem(streamList, streamID, program,
+ cleanedFullTarget, "",
+ "0 B/s", exitserver,
+ circuit);
+ streamline->setPixmap(1,programicon);
+ streamline->setPixmap(2,icon);
+ streamline->setPixmap(3,statusicon);
+ streamline->setPixmap(5,exitserverflag);
+ streamline->setDragEnabled(true);
+ streamline->setDropEnabled(true);
+
+ //The stream in the OSD display
+ osdstreamline = new QListViewItem(m_osd->infoList,streamID,
+ cleanedTarget,"","0 B/s", circuit);
+ osdstreamline->setPixmap(2,statusicon);
+ osdstreamline->setPixmap(1,icon);
+
+ // Cache for quick reference
+ streams[streamID] = streamline;
+ osdstreams[streamID] = osdstreamline;
+ logstreams[streamID] = torTrafficLine;
+
+
+ }
+
+ }else{
+
+ osdstreamline = osdstreams[streamID];
+
+ if (tmpstatus == "CLOSED"){
+ kdDebug() << "progcnt: " << progDisplayCounter << endl;
+ if ((streamline->text(1) != "..") &&
+ (progDisplayCounter > 0))
+ progDisplayCounter--;
+ streams.erase(streamID);
+ streamBwIn.erase(streamID);
+ streamBwOut.erase(streamID);
+ osdstreams.erase(streamID);
+ portStream.erase(streamID);
+ logstreams.erase(streamID);
+ if (osdstreamline) delete osdstreamline;
+ delete streamline;
+ return;
+ }
+
+ QPixmap statusicon = streamStatusIcon[status.stripWhiteSpace()];
+ streamline->setPixmap(3,statusicon);
+ osdstreamline->setPixmap(2,statusicon);
+
+
+ // If the stream does not have a verbose circuit description, add one
+ if ((streamline->text(6) == "Pending..")){
+
+ QString circuit = "Pending..";
+ QString exitserver;
+ QPixmap exitserverflag;
+
+ circuitItem* circuitline;
+ // Don't look for circuit if one hasn't been assigned yet
+ if (circID != "0") {
+ if ((circuitline = (circuitItem*) circuitList->findItem(circID,0)) != 0){
+ QListViewItem* serverline;
+ if ((serverline = (QListViewItem*) circuitExits[circID]) != 0){
+ exitserver = serverline->text(1);
+ exitserverflag = *serverline->pixmap(1);
+ }
+ circuit = circuitline->text(2);
+ }
+
+ if ((torTrafficLine = logstreams[streamID])){
+ torTrafficLine->setText(3,circuit);
+ }
+
+ streamline->setText(6, circuit);
+ streamline->setPixmap(5,exitserverflag);
+ streamline->setText(5,exitserver);
+
+ osdstreamline->setPixmap(4,exitserverflag);
+ osdstreamline->setText(4,exitserver);
+ }
+ }
+
+ if (tmpstatus == "SUCCEEDED"){
+ //HACK: this is too process intensive if there are many short-lived
+ // streams so we only look for the program if we aren't
+ // already displaying it in MAXPROGDISPLAY streams and there's
+ // less than MAXPROGDISPLAY * 3 streams active in total.
+ // There's also no point in looking up the program unless
+ // the connection is successful
+ if (streamline->text(1) == ".."){
+ if ((streamList->childCount() < (MAXPROGDISPLAY * 3))
+ && (progDisplayCounter < MAXPROGDISPLAY)) {
+ QString program = parseStreamPort(portStream[streamID]);
+ QPixmap programicon = streamProgram(program);
+ streamline->setText(1,program);
+ streamline->setPixmap(1,programicon);
+ progDisplayCounter++;
+ }
+ }
+ }
+ }
+
+
+}
+
+QString torkView::parseStreamPort(const QString &str_port)
+{
+
+ int m_port = str_port.toInt();
+
+ #define MAX_PROC_STR_LEN 32 /* /proc/1234/fd/1234 or socket:[12345] */
+ #define PROC_NET_TCP_PATH "/proc/net/tcp"
+ #define PROC_NET_UDP_PATH "/proc/net/udp"
+ char fdpath[MAX_PROC_STR_LEN];
+ char lbuf[MAX_PROC_STR_LEN];
+ struct dirent *pde;
+ DIR *pdir;
+
+ QString line;
+ QString inode;
+ bool foundIt = false;
+
+
+ QFile tcp("/proc/net/tcp") ;
+ tcp.open (IO_ReadOnly) ;
+ QTextStream input(&tcp) ;
+
+ while (!input.eof())
+ {
+ QString line = input.readLine() ;
+ QStringList bits = QStringList::split (QRegExp("[ :]+"), line) ;
+ int port = bits[2].toLong(0, 16) ;
+
+ if (port == m_port)
+ {
+ inode = bits[13];
+ break;
+ }
+ }
+
+ if (inode.isEmpty())
+ return QString();
+
+ QDir d = QDir( "/proc" );
+ QStringList dirs = d.entryList( QDir::Dirs );
+ QStringList::Iterator it;
+ for ( it = dirs.begin(); it != dirs.end(); ++it )
+ {
+
+ QDir fd = QDir( "/proc/" +*it+"/fd" );
+ if (!fd.exists())
+ continue;
+
+ QString path = "/proc/" +*it+"/fd";
+
+ if ((pdir = opendir((const char*)path)) == NULL)
+ continue;
+
+ while ((pde = readdir(pdir)) != NULL) {
+
+ snprintf(fdpath, MAX_PROC_STR_LEN, "/proc/%s/fd/%s", (const char*)*it, pde->d_name);
+ fdpath[MAX_PROC_STR_LEN - 1] = '\0';
+ int len = readlink(fdpath, lbuf, MAX_PROC_STR_LEN);
+
+ if (len < 0 || len > MAX_PROC_STR_LEN)
+ continue;
+
+ lbuf[len] = '\0';
+
+ if (QString(lbuf).contains(inode)){
+ foundIt = true;
+ QFile file( "/proc/"+*it+"/cmdline" );
+ file.open( IO_ReadOnly );
+ if ( !file.isOpen() )
+ continue;
+ QTextStream t( &file );
+ QString program = t.readLine();
+ program.replace('\0',' ');
+ program = program.section(" ",0,0).section("/",-1);
+ return program;
+
+ }
+ }
+ closedir(pdir);
+
+ if (foundIt) break;
+ }
+ return QString();
+}
+
+void torkView::circuitStatusUpdated(const QString &circuitID, const QString &status, const QString &server, const QString &exit)
+{
+
+ QString tmpstatus = status.lower().stripWhiteSpace();
+
+ circuitItem* circuitline;
+ if ((circuitline = (circuitItem*)circuitList->findItem(circuitID,0)) == 0){
+ circuitline = new circuitItem(circuitList, circuitID, "",server);
+ circuitline->setDragEnabled(true);
+ circuitline->setDropEnabled(true);
+ }else{
+ circuitline->setText(2,server);
+ }
+
+ for( uint index = 0; index < circuitIconList.count(); index++ ) {
+ if ( circuitIconList[index].contains(tmpstatus)) {
+ circuitline->setPixmap(1,QPixmap(SmallIcon("tork_"+circuitIconList[index].first())));
+ continue;
+ }
+ }
+
+ if (tmpstatus.contains("closed") || tmpstatus.contains("failed")){
+ delete circuitline;
+ circuitExits.erase(circuitID);
+ }else if (!exit.isEmpty()){
+ QListViewItem* serverline;
+ if ((serverline = (QListViewItem*) serverList->findItem(exit,2)) != 0){
+ circuitExits[circuitID] = serverline;
+ }
+ }
+}
+
+
+void torkView::ORStatusUpdated(const QString &ORID, const QString &status)
+{
+
+
+ QString tmpstatus = status.lower().stripWhiteSpace();
+
+ QListViewItem* ORline = ORList->findItem(ORID,1);
+ if (ORline == 0)
+ ORline = new QListViewItem(ORList, "", ORID);
+
+ if (tmpstatus.contains("closed") || tmpstatus.contains("failed")){
+ delete ORline;
+ if (entryGuards[ORID])
+ entryGuards.remove(ORID);
+ return;
+ }
+
+ if (entryGuards[ORID]){
+ guardStatusUpdated(ORID, status);
+ return;
+ }
+
+ for( uint index = 0; index < iconList.count(); index++ ) {
+ if ( iconList[index].contains(tmpstatus)) {
+ ORline->setPixmap(0,QPixmap(SmallIcon("tork_"+iconList[index].first())));
+ return;
+ }
+ }
+
+}
+
+void torkView::guardStatusUpdated(const QString &ORID, const QString &status)
+{
+
+ entryGuards[ORID] = status;
+
+ QString tmpstatus = status.lower().stripWhiteSpace();
+
+ QListViewItem* ORline = ORList->findItem(ORID,1);
+ if (ORline == 0)
+ ORline = new QListViewItem(ORList, "", ORID);
+
+ for( uint index = 0; index < iconList.count(); index++ ) {
+ if ( guardIconList[index].contains(tmpstatus)) {
+ ORline->setPixmap(0,QPixmap(SmallIcon("tork_guard_"+guardIconList[index].first())));
+ return;
+ }
+ }
+
+}
+
+void torkView::infoUpdated(const QString &type, const QString &summary, const QString &)
+{
+ static int id = 0;
+
+ uint total = 0;
+ for( uint index = 0; index < summary.length(); index += 120) {
+ total++;
+ }
+ uint count = 1;
+ QString tmpid;
+ for( uint index = 0; index < summary.length(); index += 120) {
+ id++;
+ tmpid = QString("00000000000%1").arg(id).right(10);
+ new QListViewItem(infoList, QDateTime::currentDateTime ().toString(Qt::ISODate).replace("T"," "),
+ tmpid, type, QString("(%1 of %2) %3").arg(count)
+ .arg(total)
+ .arg(summary.mid(index,120)));
+ count++;
+ }
+
+
+}
+void torkView::bwUpdated(const QString &in, const QString &out)
+{
+
+
+ static time_t time_of_last_bw = time(NULL);
+ static time_t time_of_last_cg = time(NULL);
+ //static time_t time_of_last_tn = time(NULL);
+ static time_t time_of_last_cbws = time(NULL);
+
+ time_t now = time(NULL);
+
+
+ //Tor Tx/Rx
+ torbtx += out.toInt();
+ torbrx += in.toInt();
+
+ if (time_of_last_bw + MAX_BW_RATE <= now){
+ int secs = now - time_of_last_bw;
+ time_of_last_bw = now;
+ reportBW(secs);
+ }
+
+
+ if (time_of_last_cg + MAX_CG_RATE < now){
+ emit signalCheckGuards();
+ time_of_last_cg = now;
+ }
+
+// if (time_of_last_tn + MAX_TN_RATE < now){
+// emit signalCheckTorNet();
+// time_of_last_tn = now;
+// }
+
+ if (time_of_last_cbws + MAX_CBWS_RATE < now){
+ emit signalCheckBWSettings();
+ time_of_last_cbws = now;
+ }
+
+}
+
+QPixmap torkView::streamProgram(const QString &program)
+{
+
+
+ QString prog = KGlobal::iconLoader()->iconPath(program, KIcon::Small, true);
+ if (prog.isEmpty())
+ return SmallIcon( "exec" );
+ else
+ return SmallIcon( program );
+
+}
+
+void torkView::streamBwUpdated(const QString &stream, const QString &in, const QString &out)
+{
+
+ //Tor Tx/Rx
+ streamBwIn[stream] += in.toInt();
+ streamBwOut[stream] += out.toInt();
+
+}
+
+void torkView::reportBW(int secs)
+{
+
+ if ((streamList->childCount() == 0) && m_osd->isShown())
+ m_osd->hide();
+
+ //Calculate Streams Tx/Rx
+
+ for ( QMap<QString, streamItem*>::Iterator stream = streams.begin(); stream != streams.end(); ++stream )
+ {
+
+ if (stream.data()){
+ stream.data()->calcBWRate(streamBwIn[stream.key().latin1()],
+ streamBwOut[stream.key().latin1()], secs);
+ QString sbw =
+ BytesPerSecToString(
+ stream.data()->mSpeedHistoryRx[stream.data()->mSpeedHistoryPtr] +
+ stream.data()->mSpeedHistoryTx[stream.data()->mSpeedHistoryPtr],0);
+ //Overlay here
+// QPixmap icon = stream.data()->pixmap(3);
+// QPixmap pm(*(stream.data()->pixmap(3)));
+// QPainter p;
+// p.begin(&pm);
+//
+// p.drawText(stream.data()->pixmap(3)->rect(),Qt::AlignCenter,sbw);
+// p.end();
+// stream.data()->setPixmap(3,pm);
+
+ stream.data()->setText(4,sbw);
+ QListViewItem* osdstreamline = osdstreams[stream.data()->text(0)];
+ osdstreamline->setText(3,sbw);
+ }
+ }
+
+ //Calculate System Tx/Rx
+ unsigned int sysbrx = 0;
+ unsigned int sysbtx = 0;
+ for ( QStringList::Iterator it = mSysDevPathList.begin(); it != mSysDevPathList.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ sysbrx += readInterfaceNumValue((*it),"rx_bytes");
+ sysbtx += readInterfaceNumValue((*it),"tx_bytes");
+
+ }
+
+ //Calculate Tor Tx/Rx
+ unsigned int btx = (torbtx - mBTx);
+ unsigned int brx = (torbrx - mBRx);
+ mBRx = torbrx;
+ mBTx = torbtx;
+
+
+
+ //Calculate Tor Tx/Rx
+ if (++mSpeedBufferPtr >= SPEED_BUFFER_SIZE)
+ mSpeedBufferPtr = 0;
+
+
+ mSpeedBufferTx[mSpeedBufferPtr] = ((btx )*(1000.0f/(secs * 1000)));
+ mSpeedBufferRx[mSpeedBufferPtr] = ((brx )*(1000.0f/(secs * 1000)));
+
+
+ if (++mSpeedHistoryPtr >= HISTORY_SIZE)
+ mSpeedHistoryPtr = 0;
+ mSpeedHistoryRx[mSpeedHistoryPtr] = calcSpeed(mSpeedBufferRx);
+ mSpeedHistoryTx[mSpeedHistoryPtr] = calcSpeed(mSpeedBufferTx);
+
+ mMaxSpeedAge--;
+
+ if (mSpeedHistoryTx[mSpeedHistoryPtr] > mMaxSpeed) {
+ mMaxSpeed = mSpeedHistoryTx[mSpeedHistoryPtr];
+ mMaxSpeedAge = HISTORY_SIZE;
+ }
+ if (mSpeedHistoryRx[mSpeedHistoryPtr] > mMaxSpeed) {
+ mMaxSpeed = mSpeedHistoryRx[mSpeedHistoryPtr];
+ mMaxSpeedAge = HISTORY_SIZE;
+ }
+ if (mMaxSpeedAge < 1)
+ calcMaxSpeed();
+
+
+ //Calculate Sys Tx/Rx
+
+ if (!mFirstUpdate) { // a primeira velocidade sempre eh absurda, para evitar isso temos o mFirstUpdate
+ if (++sys_mSpeedBufferPtr >= SPEED_BUFFER_SIZE)
+ sys_mSpeedBufferPtr = 0;
+
+ sys_mSpeedBufferTx[sys_mSpeedBufferPtr] = ((sysbtx - sysmBTx)*(1000.0f/(secs * 1000)));
+ sys_mSpeedBufferRx[sys_mSpeedBufferPtr] = ((sysbrx - sysmBRx)*(1000.0f/(secs * 1000)));
+
+ if (++sys_mSpeedHistoryPtr >= HISTORY_SIZE)
+ sys_mSpeedHistoryPtr = 0;
+ sys_mSpeedHistoryRx[sys_mSpeedHistoryPtr] = calcSpeed(sys_mSpeedBufferRx);
+ sys_mSpeedHistoryTx[sys_mSpeedHistoryPtr] = calcSpeed(sys_mSpeedBufferTx);
+
+ sys_mMaxSpeedAge--;
+
+ if (sys_mSpeedHistoryTx[sys_mSpeedHistoryPtr] > sys_mMaxSpeed) {
+ sys_mMaxSpeed = sys_mSpeedHistoryTx[sys_mSpeedHistoryPtr];
+ sys_mMaxSpeedAge = HISTORY_SIZE;
+ }
+ if (sys_mSpeedHistoryRx[sys_mSpeedHistoryPtr] > sys_mMaxSpeed) {
+ sys_mMaxSpeed = sys_mSpeedHistoryRx[sys_mSpeedHistoryPtr];
+ sys_mMaxSpeedAge = HISTORY_SIZE;
+ }
+ if (sys_mMaxSpeedAge < 1)
+ sys_calcMaxSpeed();
+ }
+
+ mFirstUpdate = false;
+
+ sysmBRx = sysbrx;
+ sysmBTx = sysbtx;
+
+ //Update Main Graphs
+ emit updateStats();
+
+ //Update ChartBar in OSD
+ float bitRateIn = brx;// * 8.0 / (secondselapsed / 1000.0);
+ float bitRateOut = btx;// * 8.0 / (secondselapsed / 1000.0);
+
+ int8_t upperIn = (int8_t) (100.0 * bitRateIn /mMaxSpeed);
+ if (upperIn < 0) upperIn = 0;
+ else if (upperIn > 100) upperIn = 100;
+ int8_t upperOut = (int8_t) (100.0 * bitRateOut / mMaxSpeed );
+ if (upperOut < 0) upperOut = 0;
+ else if (upperOut > 100) upperOut = 100;
+
+ QString kbsrx = BytesPerSecToString(mSpeedHistoryRx[mSpeedHistoryPtr]);
+ QString kbstx = BytesPerSecToString(mSpeedHistoryTx[mSpeedHistoryPtr]);
+
+ m_osd->m_graphIn->addPercentReading(upperIn, false);
+ m_osd->m_graphOut->addPercentReading(upperOut, false);
+ m_osd->m_graphIn->setLabel(QString("Dn: %1")
+ .arg(kbsrx));
+ m_osd->m_graphOut->setLabel(QString("Up: %1")
+ .arg(kbstx));
+
+ // Update Tray and StatusBar
+ emit updateTrayStats(BytesToString(mBRx),
+ BytesToString(mBTx),
+ kbsrx,
+ kbstx);
+}
+
+unsigned long torkView::readInterfaceNumValue(QString interface,
+ const char* name) {
+ // stdio functions appear to be more fast than QFile?
+ FILE* fp = fopen((interface+"/statistics/"+name).latin1(), "r");
+ if (!fp)
+ return 0;
+ long retval;
+ fscanf(fp, "%lu", &retval);
+ fclose(fp);
+ return retval;
+}
+
+
+void torkView::activeServersUpdated( const QStringList &servers)
+{
+ QListViewItem* tm;
+ QStringList tmpservers = servers;
+ for ( QStringList::Iterator it = tmpservers.begin(); it != tmpservers.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ if ( (tm = serverList->findItem((*it),1)) > 0){
+ tm->setPixmap(0,QPixmap(SmallIcon("tork_green")));
+ }else{
+ tm = new QListViewItem(serverList, (*it));
+ tm->setPixmap(0,QPixmap(SmallIcon("tork_green")));
+ }
+ }
+
+}
+
+void torkView::serverStatusUpdated(const QString &ip,const QString &fp,
+ const QString &server, const QString &statuses)
+{
+ QListViewItem* tm;
+
+ if (!(tm = torservers[fp])){
+ tm = new QListViewItem(serverList, "", (server), fp, statuses);
+ torservers[fp] = tm;
+ }
+
+ QString cc;
+ int country_id = 0;
+ GeoIP * gi = 0;
+ if (geoip_db)
+#ifndef EXTERNAL_GEOIP
+ gi = GeoIP_open(locate("data", "tork/geoip/GeoIP.dat").ascii(),0);
+#else
+ gi = GeoIP_new(GEOIP_STANDARD);
+#endif
+
+ if (gi){
+ country_id = GeoIP_id_by_name(gi, ip);
+ cc = GeoIP_country_code[country_id];
+ GeoIP_delete(gi);
+
+ if (!m_countryList.contains(country_id))
+ m_countryList << country_id;
+ }else
+ cc = "--";
+
+ QString ccode = QString("%1").arg(country_id);
+ tm->setText(4,ccode);
+ tm->setText(5,ip);
+
+/*
+ QRegExp rx("^[0-9]{1,3}\\.");
+ rx.search(ip);
+ QString tmp = rx.cap(0);
+ if (!m_subnet16List.contains(tmp))
+ m_subnet16List << tmp;
+*/
+ if (cc == "--")
+ tm->setPixmap(1,QPixmap(SmallIcon("help")));
+ else
+ tm->setPixmap(1,QPixmap(SmallIcon("tork_" + cc.lower())));
+
+ QString icontouse;
+ if ((statuses.contains("Stable")) && (statuses.contains("Running")) && (statuses.contains("Fast")))
+ icontouse = "tork_green";
+ else if ((statuses.contains("Fast")) && (statuses.contains("Running")))
+ icontouse = "tork_yellow";
+ else if ((statuses.contains("Running")) && (statuses.contains("Stable")))
+ icontouse = "tork_orange";
+ else if ((statuses.contains("Running")))
+ icontouse = "tork_little";
+ else // if ((statuses.contains("Valid")))
+ icontouse = "tork_red";
+
+ if ((statuses.contains("Exit")))
+ icontouse += "_exit";
+
+
+ // Update Exclude Nodes if Country is Excluded and this server is new to us
+
+ if (TorkConfig::excludeCountries().contains(ccode)){
+ if (!TorkConfig::excludeServersHistory().contains(QString("%1-%2-%3")
+ .arg(ccode).arg(fp).arg(server))){
+
+ QStringList existingServers = TorkConfig::excludeServersHistory();
+ existingServers.append(QString("%1-%2-%3").arg(ccode).arg(fp).arg(server));
+ TorkConfig::setExcludeServersHistory(existingServers);
+
+ QStringList permList;
+ permList = TorkConfig::excludeNodes();
+ QString node = "$"+getFPFromFPDigest(fp);
+ permList.append(node);
+
+ }
+ }
+
+
+ tm->setPixmap(0,QPixmap(SmallIcon(icontouse)));
+
+}
+
+void torkView::switchColors()
+{
+ // switch the foreground/background colors of the label
+/* QColor color = Settings::col_background();
+ Settings::setCol_background( Settings::col_foreground() );
+ Settings::setCol_foreground( color );
+*/
+ settingsChanged();
+}
+
+void torkView::settingsChanged()
+{
+/* sillyLabel->setPaletteBackgroundColor( Settings::col_background() );
+ sillyLabel->setPaletteForegroundColor( Settings::col_foreground() );
+
+ // i18n : internationalization
+ sillyLabel->setText( i18n("This project is %1 days old").arg(Settings::val_time()) );
+ emit signalChangeStatusbar( i18n("Settings changed") );*/
+}
+
+void torkView::displayError( const QString &caption, const QString &infol)
+{
+
+ if (!circuitList->recentDropEvent())
+ return;
+ QString info = infol;;
+ info.replace(QRegExp("(\\$[A-Z0-9]{40})(~|=)"),"");
+
+ delete m_pop;
+
+ KPassivePopup* pop;
+
+ QPoint pnt;
+ if (kmain->isActiveWindow()){
+ pop = new KPassivePopup( kmain );
+ pnt = kmain->pos() += kmain->m_view->pos() += kmain->m_view->circuitList->pos() +=
+ kmain->m_view->circuitList->getMousePos() += kmain->m_view->splitter3->pos() +=
+ kmain->m_view->splitter4->pos() += kmain->m_view->groupBox1->pos();
+ }else{
+ pop = new KPassivePopup( kmain->_tray );
+ pnt = kmain->_tray->pos();
+ }
+ pop->setView( caption,info );
+ pop->show(QPoint(pnt));
+
+ m_pop = pop;
+}
+
+void torkView::displayServer( const QString &caption, const QString &info)
+{
+
+
+ KPassivePopup* pop;
+
+ QPoint pnt;
+ if (kmain->isActiveWindow()){
+ pop = new KPassivePopup( serverList );
+ //pnt = kmain->pos() -= kmain->m_view->serverList->getMousePos() -= kmain->m_view->serverList->getMousePos() -= kmain->m_view->serverList->getMousePos();
+ }else{
+ pop = new KPassivePopup( kmain->_tray );
+ pnt = kmain->_tray->pos();
+ }
+ pop->setView( caption,info );
+ //pop->show(QPoint(pnt));
+ pop->show();
+
+
+}
+
+void torkView::showServerBW(const QString &fp )
+{
+
+ QString fl;
+ QString tmpFile;
+ fl = QString("http://www.noreply.org/tor-running-routers/%1/node-traf-%2.png")
+ .arg(fp.left(2)).arg(fp);
+ KIO::NetAccess::download( fl, tmpFile, 0L );
+ kapp->processEvents();
+ streamList-> setPaletteBackgroundPixmap( QPixmap(tmpFile) );
+}
+
+
+void torkView::hidePopup( )
+{
+
+ delete m_pop;
+
+}
+
+void torkView::populateMenu()
+{
+ Anonymizer->clear();
+ QFont font;
+
+ //Welcome
+ welcomeitem = new HitWidget(QString::null, QString::null);
+ welcomeheaderLabel = new QLabel(welcomeitem);
+ welcomeheaderLabel->setText(i18n("Press 'Play' to get started!"));
+ font.setBold( true );
+ welcomeheaderLabel->setFont( font );
+ welcomeitem->insertHeaderWidget(0,welcomeheaderLabel);
+
+ welcomeitem->setIcon("tork_pressplay");
+ welcomeitem->setDescriptionText("<qt>"+i18n("- <b>Press 'Play' to connect to Tor. (You can also use the toolbar icons.)</b>")+"</qt>");
+// item->icon->setURL("konqueror");
+ welcomeitem->setPropertiesText("<qt>"+i18n(
+ "- The 'Tor Network' tab shows you the state of the Tor network, including your Tor Traffic. <br> "
+ "- You can use the 'Traffic Log' tab to view Tor and Non-Tor Traffic on your system.<br> "
+ "- You can use the 'Tor Log' tab to view warning messages from Tor itself. <br> "
+ "- Once Tor is up and running you can use the services listed below. <br> "
+ )+"</qt>");
+
+ KURLLabel *buttonStart = new KURLLabel(welcomeitem);
+ buttonStart->setPixmap(SmallIcon("info"));
+ welcomeitem->insertHitWidget(0,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(aboutTor()));
+
+ buttonStart = new KURLLabel(welcomeitem);
+ buttonStart->setText(i18n("What You Need To Know When Using TorK!"));
+ welcomeitem->insertHitWidget(1,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(aboutTor()));
+
+ paranoidmodeicon = new KURLLabel(welcomeitem);
+ welcomeitem->insertHitWidget(2,paranoidmodeicon);
+ connect(paranoidmodeicon, SIGNAL(leftClickedURL()), SIGNAL(aboutParanoidMode()));
+
+ paranoidmodetext = new KURLLabel(welcomeitem);
+ welcomeitem->insertHitWidget(3,paranoidmodetext);
+ connect(paranoidmodetext, SIGNAL(leftClickedURL()), SIGNAL(aboutParanoidMode()));
+
+
+ paranoidmodeicon->setPixmap(SmallIcon("tork_penguin"));
+ paranoidmodetext->setText(i18n("In Normal mode!"));
+
+ QStringList qconf;
+ qconf << "Clnt/Exit" << "Clnt/Relay" << "Exit" << "Relay" << "Client" << "Custom" << "Remote" << "Local";
+ welcomeitem->score->setHidden(false);
+ welcomeitem->score->insertStringList(qconf);
+ welcomeitem->score->setPalette(QPalette(Qt::white,Qt::white));
+
+ welcomeitem->score->setCurrentItem(TorkConfig::quickConfigure());
+
+ connect(welcomeitem->score, SIGNAL(activated(int)), SLOT(changeQuickConfigure(int)));
+
+ Anonymizer->insertItem(welcomeitem);
+ connect(welcomeitem->icon, SIGNAL(leftClickedURL()), SIGNAL(startEverything()));
+
+
+ QLabel *headerLabel;
+
+ //Firefox
+ firefoxitem = 0L;
+#ifndef LIVECD
+ if (TorkConfig::availablePrograms().contains("firefox")){
+
+ firefoxitem = new HitWidget(QString::null, QString::null);
+
+ headerLabel = new QLabel(firefoxitem);
+ headerLabel->setText(i18n("Anonymous Browsing (with Firefox)"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ firefoxitem->insertHeaderWidget(0,headerLabel);
+
+ firefoxitem->setIcon("tork_firefox");
+ firefoxitem->setDescriptionText("<qt>"+i18n("<b>Click the icon to launch an anonymous browsing session in Firefox. </b><br>"
+ )+"</qt>");
+ firefoxitem->setPropertiesText("<qt>"+i18n(
+ "- TorK will make a copy of your normal Firefox settings and modify them for anonymous browsing. <br>"
+ "- Firefox will use Privoxy in combination with Tor to anonymize your browsing. <br>"
+ "- No other Firefox sessions will be anonymous!<br>"
+ )+"</qt>");
+ firefoxitem->icon->setURL("firefox");
+
+ //QComboBox* countries = new QComboBox( FALSE, "this" );
+ //firefoxitem->insertWidget(1,countries);
+
+ buttonStart = new KURLLabel(firefoxitem);
+ buttonStart->setPixmap(SmallIcon("info"));
+ firefoxitem->insertHitWidget(0,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SLOT(downloadTorButton()));
+
+ buttonStart = new KURLLabel(firefoxitem);
+ buttonStart->setText(i18n("Install TorButton First (Recommended)"));
+ firefoxitem->insertHitWidget(1,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SLOT(downloadTorButton()));
+
+ Anonymizer->insertItem(firefoxitem);
+ connect(firefoxitem->icon, SIGNAL(leftClickedURL()), SLOT(anonymousFirefox()));
+ }
+ //Kopete
+#endif
+
+ //Anonymous Mail
+ mixminionitem = new HitWidget(QString::null, QString::null);
+ headerLabel = new QLabel(mixminionitem);
+ headerLabel->setText(i18n("Anonymous Email"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ mixminionitem->insertHeaderWidget(0,headerLabel);
+
+ mixminionitem->setIcon("tork_mail");
+ mixminionitem->setDescriptionText("<qt>"+i18n("<b>Click the icon to compose and send an anonymous email.</b><br>"
+ )+"</qt>");
+ mixminionitem->setPropertiesText("<qt>"+i18n(
+ "- The email will be routed through the anonymizing mixminion network. <br>"
+ "- Delivery of anonymous email can take a while, sometimes up to 24 hours! <br>"
+ "- If you don't have mixminion already, click the link below to install it. <br>"
+ "- Visit the mixminion homepage to find out more. <br>"
+ )+"</qt>");
+
+
+// QStringList qconf;
+// qconf << "Simple" << "KMail";
+//
+// QFont f( sshitem->score->font().rawName(),
+// sshitem->score->font().pointSize() - 1 );
+// mixminionitem->score->setFont( f );
+// mixminionitem->score->setHidden(false);
+// mixminionitem->score->insertStringList(shellsAvailable);
+// mixminionitem->score->setPalette(QPalette(Qt::white,Qt::white));
+// connect(mixminionitem->score, SIGNAL(activated(int)),mixminionitem,
+// SLOT(changeTerminalUrl(int)));
+
+
+ buttonStart = new KURLLabel(mixminionitem);
+ buttonStart->setPixmap(SmallIcon("info"));
+ mixminionitem->insertHitWidget(0,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SLOT(downloadMixminion()));
+
+ buttonStart = new KURLLabel(mixminionitem);
+ buttonStart->setText(i18n("Install Mixminion"));
+ mixminionitem->insertHitWidget(1,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SLOT(downloadMixminion()));
+
+ buttonStart = new KURLLabel(mixminionitem);
+ buttonStart->setPixmap(SmallIcon("konqueror"));
+ mixminionitem->insertHitWidget(2,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(mixminionHome()));
+
+ buttonStart = new KURLLabel(mixminionitem);
+ buttonStart->setText(i18n("Visit the Mixminion Project page."));
+ mixminionitem->insertHitWidget(3,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(mixminionHome()));
+
+ Anonymizer->insertItem(mixminionitem);
+ connect(mixminionitem->icon, SIGNAL(leftClickedURL()), SLOT(sendAnonymousEmail()));
+
+ konqitem=0L;
+ //Konqueror
+#ifndef LIVECD
+ if (TorkConfig::availablePrograms().contains("konqueror")){
+ konqitem = new HitWidget(QString::null, QString::null);
+ headerLabel = new QLabel(konqitem);
+ headerLabel->setText(i18n("Anonymous Browsing (with Konqueror)"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ konqitem->insertHeaderWidget(0,headerLabel);
+
+ konqitem->setIcon("tork_konqueror_play");
+
+ if (TorkConfig::kDEUsesTor())
+ konqitem->icon->pixmap()->fill(Qt::red);
+
+ konqitem->setDescriptionText("<qt>"+i18n("<b>Click the icon to launch an anonymous browsing session. </b><br>"
+ )+"</qt>");
+ konqitem->setPropertiesText("<qt>"+i18n(
+ "- This will also make any other Konqueror sessions you use anonymous. <br>"
+ "- Konqueror windows that have anonymous browsing enabled are a funny green colour.<br>"
+ "- Konqueror uses Privoxy in combination with Tor to anonymize your browsing. <br>"
+ "- You can toggle this setting at any time using the Konqueror icon in the toolbar or the miniview.<br>"
+ )+"</qt>");
+
+ konqitem->icon->setURL("konqueror");
+
+ buttonStart = new KURLLabel(konqitem);
+ buttonStart->setPixmap(SmallIcon("configure"));
+ konqitem->insertHitWidget(0,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(showMyKonqueror()));
+
+ buttonStart = new KURLLabel(konqitem);
+ buttonStart->setText(i18n("Configure Anonymous Konqueror"));
+ konqitem->insertHitWidget(1,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(showMyKonqueror()));
+
+ configurePriv = new KURLLabel(konqitem);
+ configurePriv->setPixmap(SmallIcon("configure"));
+ konqitem->insertHitWidget(2,configurePriv);
+ connect(configurePriv, SIGNAL(leftClickedURL()), SIGNAL(configurePrivoxy()));
+
+ configurePrivText = new KURLLabel(konqitem);
+ configurePrivText->setText(i18n("Configure Privoxy"));
+ konqitem->insertHitWidget(3,configurePrivText);
+ connect(configurePrivText, SIGNAL(leftClickedURL()), SIGNAL(configurePrivoxy()));
+
+ Anonymizer->insertItem(konqitem);
+ connect(konqitem->icon, SIGNAL(leftClickedURL()), SIGNAL(konqWithTor()));
+ }
+
+#endif
+
+
+ operaitem = 0L;
+#ifndef LIVECD
+
+ if (TorkConfig::availablePrograms().contains("opera")){
+
+ operaitem = new HitWidget(QString::null, QString::null);
+ headerLabel = new QLabel(operaitem);
+ headerLabel->setText(i18n("Anonymous Browsing (with Opera)"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ operaitem->insertHeaderWidget(0,headerLabel);
+
+ operaitem->setIcon("tork_opera");
+ operaitem->setDescriptionText("<qt>"+i18n("<b>Click the icon to launch an anonymous browsing session in Opera. </b><br>"
+ )+"</qt>");
+ operaitem->setPropertiesText("<qt>"+i18n(
+ "- TorK will make a copy of your normal Opera settings and modify them for anonymous browsing. <br>"
+ "- Opera will use Privoxy in combination with Tor to anonymize your browsing. <br>"
+ "- No other Opera sessions will be anonymous!<br>"
+ )+"</qt>");
+ operaitem->icon->setURL("opera");
+ Anonymizer->insertItem(operaitem);
+ connect(operaitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(anonymizedOpera(const QString&)));
+ }
+#endif
+
+
+ hiddenservicesitem = 0L;
+ //Hidden Services
+ hiddenservicesitem = new HitWidget(QString::null, QString::null);
+
+ headerLabel = new QLabel(hiddenservicesitem);
+ headerLabel->setText(i18n("Anonymous Websites and Web Services"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ hiddenservicesitem->insertHeaderWidget(0,headerLabel);
+
+ hiddenservicesitem->setIcon("tork_agent");
+ hiddenservicesitem->setDescriptionText("<qt>"+i18n("<b>Click the icon to create an anonymous web site or manage existing ones.</b><br>"
+ )+"</qt>");
+
+ setHiddenServicesText();
+
+ buttonStart = new KURLLabel(hiddenservicesitem);
+ buttonStart->setPixmap(SmallIcon("konqueror"));
+ hiddenservicesitem->insertHitWidget(0,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(hiddenServices()));
+
+ buttonStart = new KURLLabel(hiddenservicesitem);
+ buttonStart->setText(i18n("Search Hidden Services"));
+ hiddenservicesitem->insertHitWidget(1,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(hiddenServices()));
+
+ Anonymizer->insertItem(hiddenservicesitem);
+ connect(hiddenservicesitem->icon, SIGNAL(leftClickedURL()), SIGNAL(showMyHiddenServices()));
+
+
+ //Kopete
+
+ kopeteitem = 0L;
+#ifndef LIVECD
+
+ if (TorkConfig::availablePrograms().contains("kopete")){
+ kopeteitem = new HitWidget(QString::null, QString::null);
+
+ headerLabel = new QLabel(kopeteitem);
+ headerLabel->setText(i18n("Anonymous Instant Messaging/IRC (with Kopete)"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ kopeteitem->insertHeaderWidget(0,headerLabel);
+
+ kopeteitem->setIcon("kopete");
+ kopeteitem->setDescriptionText("<qt>"+i18n("<b> Click to start an anonymized Kopete session.</b><br>"
+ )+"</qt>");
+ kopeteitem->setPropertiesText("<qt>"+i18n(
+ "- You won't be anonymous if you use your real name!<br>"
+ )+"</qt>");
+ kopeteitem->icon->setURL("kopete --caption 'Anonymous IM Session - Launched From TorK'");
+ Anonymizer->insertItem(kopeteitem);
+ connect(kopeteitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&)));
+ }
+#endif
+ //Gaim
+ gaimitem = 0L;
+
+#ifndef LIVECD
+
+ if (TorkConfig::availablePrograms().contains("gaim")){
+ gaimitem = new HitWidget(QString::null, QString::null);
+ headerLabel = new QLabel(gaimitem);
+ headerLabel->setText(i18n("Anonymous Instant Messaging/IRC (with Gaim)"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ gaimitem->insertHeaderWidget(0,headerLabel);
+
+ gaimitem->setIcon("gaim");
+ gaimitem->setDescriptionText("<qt>"+i18n("<b> Click to start an anonymized Gaim session.</b><br>"
+ )+"</qt>");
+ gaimitem->setPropertiesText("<qt>"+i18n(
+ "- You won't be anonymous if you use your real name!<br>"
+ )+"</qt>");
+ gaimitem->icon->setURL("gaim");
+ Anonymizer->insertItem(gaimitem);
+ connect(gaimitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&)));
+ }
+#endif
+ //Pidgin
+
+ pidginitem = 0L;
+
+#ifndef LIVECD
+
+ if (TorkConfig::availablePrograms().contains("pidgin")){
+ pidginitem = new HitWidget(QString::null, QString::null);
+ headerLabel = new QLabel(pidginitem);
+ headerLabel->setText(i18n("Anonymous Instant Messaging/IRC (with Pidgin)"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ pidginitem->insertHeaderWidget(0,headerLabel);
+
+ pidginitem->setIcon("pidgin");
+ pidginitem->setDescriptionText("<qt>"+i18n("<b> Click to start an anonymized Pidgin session.</b><br>"
+ )+"</qt>");
+ pidginitem->setPropertiesText("<qt>"+i18n(
+ "- You won't be anonymous if you use your real name!<br>"
+ )+"</qt>");
+ pidginitem->icon->setURL("pidgin");
+ Anonymizer->insertItem(pidginitem);
+ connect(pidginitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&)));
+ }
+#endif
+ //Gaim
+ konversationitem = 0L;
+
+#ifndef LIVECD
+
+ if (TorkConfig::availablePrograms().contains("konversation")){
+
+ konversationitem = new HitWidget(QString::null, QString::null);
+
+ headerLabel = new QLabel(konversationitem);
+ headerLabel->setText(i18n("Anonymous Instant Messaging/IRC (with Konversation)"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ konversationitem->insertHeaderWidget(0,headerLabel);
+
+ konversationitem->setIcon("konversation");
+ konversationitem->setDescriptionText("<qt>"+i18n("<b> Click to start an anonymized Konversation session.</b><br>"
+ )+"</qt>");
+ konversationitem->setPropertiesText("<qt>"+i18n(
+ "- You won't be anonymous if you use your real name!<br>"
+ )+"</qt>");
+ konversationitem->icon->setURL("konversation");
+ Anonymizer->insertItem(konversationitem);
+ connect(konversationitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&)));
+ }
+#endif
+ //KSIRC
+ ksircitem =0L;
+
+#ifndef LIVECD
+ if (TorkConfig::availablePrograms().contains("ksirc")){
+
+ ksircitem = new HitWidget(QString::null, QString::null);
+
+ headerLabel = new QLabel(ksircitem);
+ headerLabel->setText(i18n("Anonymous IRC (with KSirc)"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ ksircitem->insertHeaderWidget(0,headerLabel);
+
+ ksircitem->setIcon("ksirc");
+ ksircitem->setDescriptionText("<qt>"+i18n("<b> Click to start an anonymous KSirc IRC session.</b><br>"
+ )+"</qt>");
+ ksircitem->setPropertiesText("<qt>"+i18n(
+ "- Leaking DNS requests is not fatal but something to keep an eye on. Use the traffic-log.<br>"
+ )+"</qt>");
+
+ ksircitem->icon->setURL("ksirc --caption 'Anonymous IRC Shell - Launched From TorK'");
+ Anonymizer->insertItem(ksircitem);
+ connect(ksircitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&)));
+ }
+
+#endif
+ //SSH
+
+ QStringList shellCandidates;
+ QStringList shellsAvailable;
+ shellCandidates << "konsole" << "yakuake" << "xterm" << "rxvt" << "gnome-terminal";
+
+ for ( QStringList::Iterator it = shellCandidates.begin(); it != shellCandidates.end(); it++ )
+ {
+ if (TorkConfig::availablePrograms().contains(*it))
+ shellsAvailable << (*it);
+ }
+
+ QStringList hkpShellsAvailable = shellsAvailable;
+
+ if (TorkConfig::availablePrograms().contains("x3270"))
+ shellsAvailable << "x3270";
+
+ sshitem = 0L;
+
+#ifndef LIVECD
+ if (!shellsAvailable.isEmpty()){
+
+ sshitem = new HitWidget(QString::null, QString::null);
+
+ headerLabel = new QLabel(sshitem);
+ headerLabel->setText(i18n("Anonymous SSH Session"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ sshitem->insertHeaderWidget(0,headerLabel);
+
+ sshitem->setIcon("tork_konsolessh");
+ sshitem->setDescriptionText("<qt>"+i18n("<b>Click the icon to start a Konsole terminal session.</b><br>"
+ )+"</qt>");
+ sshitem->setPropertiesText("<qt>"+i18n(
+ "- Use <b>ssh</b> within the session to connect securely and anonymously. "
+ "e.g. <b> ssh shell.sf.net</b><br>"
+ "- Use the traffic-log tab to ensure you are not leaking DNS requests.<br>"
+ )+"</qt>");
+
+ sshitem->icon->setURL("konsole --caption 'Anonymous SSH Shell - Launched From TorK'");
+
+ buttonStart = new KURLLabel(sshitem);
+ buttonStart->setPixmap(SmallIcon("help"));
+ sshitem->insertHitWidget(0,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(aboutTorify()));
+
+ buttonStart = new KURLLabel(sshitem);
+ buttonStart->setText(i18n("How can I be sure this is working?"));
+ sshitem->insertHitWidget(1,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(aboutTorify()));
+
+ sshitem->shellTitles["konsole"] = " --caption 'Anonymous SSH Shell - Launched From TorK'";
+ sshitem->shellTitles["yakuake"] = " --caption 'Anonymous SSH Shell - Launched From TorK'";
+ sshitem->shellTitles["xterm"] = " -title 'Anonymous SSH Shell - Launched From TorK'";
+ sshitem->shellTitles["rxvt"] = " -title 'Anonymous SSH Shell - Launched From TorK'";
+ sshitem->shellTitles["gnome-terminal"] = " --title 'Anonymous SSH Shell - Launched From TorK'";
+
+ QFont f( sshitem->score->font().rawName(), sshitem->score->font().pointSize() - 1 );
+ sshitem->score->setFont( f );
+ sshitem->score->setHidden(false);
+ sshitem->score->insertStringList(shellsAvailable);
+ sshitem->score->setPalette(QPalette(Qt::white,Qt::white));
+ connect(sshitem->score, SIGNAL(activated(int)),sshitem, SLOT(changeTerminalUrl(int)));
+
+ Anonymizer->insertItem(sshitem);
+ connect(sshitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&)));
+ }
+#endif
+ //Telnet
+ telnetitem =0L;
+
+#ifndef LIVECD
+ if (!shellsAvailable.isEmpty()){
+
+ telnetitem = new HitWidget(QString::null, QString::null);
+
+ headerLabel = new QLabel(telnetitem);
+ headerLabel->setText(i18n("Anonymous Telnet Session"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ telnetitem->insertHeaderWidget(0,headerLabel);
+
+ telnetitem->setIcon("tork_konsole");
+ telnetitem->setDescriptionText("<qt>"+i18n("<b> This will start a Konsole terminal session.</b><br>"
+ )+"</qt>");
+ telnetitem->setPropertiesText("<qt>"+i18n(
+ "- Use <b>telnet</b> within the session to connect anonymously. "
+ "e.g. <b> telnet shell.sf.net 23</b><br>"
+ "- Telnet passwords are sent in clear-text - so do be careful 007!.<br>"
+ )+"</qt>");
+ telnetitem->icon->setURL("konsole --caption 'Anonymous Telnet Session - Launched From TorK'");
+ buttonStart = new KURLLabel(telnetitem);
+ buttonStart->setPixmap(SmallIcon("help"));
+ telnetitem->insertHitWidget(0,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(riskySession()));
+
+ buttonStart = new KURLLabel(telnetitem);
+ buttonStart->setText(i18n("Why is anonymous telnet risky?"));
+ telnetitem->insertHitWidget(1,buttonStart);
+ connect(buttonStart, SIGNAL(leftClickedURL()), SIGNAL(riskySession()));
+
+ telnetitem->shellTitles["konsole"] = " --caption 'Anonymous Telnet Session - Launched From TorK'";
+ telnetitem->shellTitles["yakuake"] = " --caption 'Anonymous Telnet Session - Launched From TorK'";
+ telnetitem->shellTitles["xterm"] = " -title 'Anonymous Telnet Session - Launched From TorK'";
+ telnetitem->shellTitles["rxvt"] = " -title 'Anonymous Telnet Session - Launched From TorK'";
+ telnetitem->shellTitles["gnome-terminal"] = " --title 'Anonymous Telnet Session - Launched From TorK'";
+
+ QFont f( telnetitem->score->font().rawName(), telnetitem->score->font().pointSize() - 1 );
+ telnetitem->score->setFont( f );
+ telnetitem->score->setHidden(false);
+ telnetitem->score->insertStringList(shellsAvailable);
+ telnetitem->score->setPalette(QPalette(Qt::white,Qt::white));
+ connect(telnetitem->score, SIGNAL(activated(int)),telnetitem, SLOT(changeTerminalUrl(int)));
+
+ Anonymizer->insertItem(telnetitem);
+ connect(telnetitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&)));
+ }
+ //GPG
+#endif
+
+ gpgitem = 0L;
+
+#ifndef LIVECD
+ if ((TorkConfig::availablePrograms().contains("gpg")) && !shellsAvailable.isEmpty()){
+
+ gpgitem = new HitWidget(QString::null, QString::null);
+
+ headerLabel = new QLabel(gpgitem);
+ headerLabel->setText(i18n("Anonymously Refresh GPG Keys"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ gpgitem->insertHeaderWidget(0,headerLabel);
+
+ gpgitem->setIcon("tork_kgpg");
+ gpgitem->setDescriptionText("<qt>"+i18n("<b>This will refresh your GPG keys anonymously.</b><br>"
+ "</qt>"));
+ gpgitem->setPropertiesText("<qt>"+i18n(
+ "- To use the hidden service for GPG keys, add these lines to %1/.gnupg/gpg.conf:<br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp; keyserver x-hkp://yod73zr3y6wnm2sw.onion<br>"
+ "&nbsp;&nbsp;&nbsp;&nbsp; keyserver x-hkp://d3ettcpzlta6azsm.onion<br>"
+ "</qt>").arg(getenv("HOME")));
+
+ gpgitem->icon->setURL("konsole --caption 'Anonymous GPG Keys Refresh - Launched From TorK' --noclose -e gpg --refresh-keys");
+
+ gpgitem->shellTitles["konsole"] = " --caption 'Anonymous GPG Keys Refresh - Launched From TorK' --noclose -e gpg --refresh-keys";
+ gpgitem->shellTitles["yakuake"] = " --caption 'Anonymous GPG Keys Refresh - Launched From TorK' --noclose -e gpg --refresh-keys";
+ gpgitem->shellTitles["xterm"] = " -title 'Anonymous GPG Keys Refresh - Launched From TorK' -e gpg --refresh-keys";
+ gpgitem->shellTitles["rxvt"] = " -title 'Anonymous GPG Keys Refresh - Launched From TorK' -e gpg --refresh-keys";
+ gpgitem->shellTitles["gnome-terminal"] = " --title 'Anonymous GPG Keys Refresh - Launched From TorK' -e gpg --refresh-keys";
+
+ QFont f( gpgitem->score->font().rawName(), gpgitem->score->font().pointSize() - 1 );
+ gpgitem->score->setFont( f );
+
+ gpgitem->score->setHidden(false);
+ gpgitem->score->insertStringList(hkpShellsAvailable);
+ gpgitem->score->setPalette(QPalette(Qt::white,Qt::white));
+ connect(gpgitem->score, SIGNAL(activated(int)),gpgitem, SLOT(changeTerminalUrl(int)));
+
+ Anonymizer->insertItem(gpgitem);
+ connect(gpgitem->icon, SIGNAL(leftClickedURL(const QString&)), SLOT(torify(const QString&)));
+ }
+#endif
+ //All Purpose Shell
+ allpurposeitem = 0L;
+
+#ifndef LIVECD
+
+ if (!shellsAvailable.isEmpty()){
+ allpurposeitem = new HitWidget(QString::null, QString::null);
+ headerLabel = new QLabel(allpurposeitem);
+ headerLabel->setText(i18n("Anonymous Shell for Command-Line Programs using HTTP/HTTPS"));
+ font.setBold( true );
+ headerLabel->setFont( font );
+ allpurposeitem->insertHeaderWidget(0,headerLabel);
+
+ allpurposeitem->setIcon("tork_konsole");
+ allpurposeitem->setDescriptionText("<qt>"+i18n("<b>Click to start a Konsole session.</b><br>"
+ )+"</qt>");
+ allpurposeitem->setDescriptionText("<qt>"+i18n("- Your http(s) requests will be routed through a privacy proxy and Tor.<br>"
+ "- Suitable for such programs as <b>wget</b>, <b>slapt-get</b> and <b>lynx</b>. <br>"
+ )+"</qt>");
+
+// QFont f( allpurposeitem->score->font().rawName(), 8 );
+// allpurposeitem->score->setFont( f );
+// allpurposeitem->score->setHidden(false);
+// allpurposeitem->score->insertStringList(shellsAvailable);
+// allpurposeitem->score->setPalette(QPalette(Qt::white,Qt::white));
+
+
+ Anonymizer->insertItem(allpurposeitem);
+ connect(allpurposeitem->icon, SIGNAL(leftClickedURL()), SLOT(privoxiedBash()));
+ }
+#endif
+
+}
+
+circuitItem::circuitItem( DndListView *parent, const QString &id, const QString &status, const QString &server )
+ : QListViewItem( parent, id, status, server)
+{
+}
+
+
+streamItem::streamItem( DndListView *parent, const QString &id, const QString &program, const QString &target, const QString &status, const QString &bw, const QString &exit, const QString &circuit )
+ : QListViewItem( parent, id, program, target, status, bw, exit, circuit)
+{
+/* setDragEnabled(true);
+ setDropEnabled(true);*/
+ memset(mSpeedHistoryRx, 0, sizeof(double)*HISTORY_SIZE);
+ memset(mSpeedHistoryTx, 0, sizeof(double)*HISTORY_SIZE);
+ memset(mSpeedBufferRx, 0, sizeof(double)*SPEED_BUFFER_SIZE);
+ memset(mSpeedBufferTx, 0, sizeof(double)*SPEED_BUFFER_SIZE);
+ mMaxSpeedAge = 0;
+ mMaxSpeed = 0.0;
+ mSpeedBufferPtr = mSpeedHistoryPtr = 0;
+ mBRx = mBTx = 0;
+
+}
+
+
+#include "torkview.moc"
+
diff --git a/src/torkview.h b/src/torkview.h
new file mode 100644
index 0000000..a13a29a
--- /dev/null
+++ b/src/torkview.h
@@ -0,0 +1,529 @@
+/***************************************************************************
+ ** $Id: torkview.h,v 1.59 2009/10/20 20:16:00 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#ifndef _TORKVIEW_H_
+#define _TORKVIEW_H_
+
+#include <qwidget.h>
+
+#include "torkview_base.h"
+#include "hitwidget.h"
+#include "kwidgetlistbox.h"
+#include "kerrylabel.h"
+#include "dndlistview.h"
+
+#include <qlistview.h>
+#include <qdragobject.h>
+#include <qiconview.h>
+#include <qdatetime.h>
+#include <kpassivepopup.h>
+#include "newstreamosd.h"
+
+class QPainter;
+class KURL;
+class QListViewItem;
+class QDragEnterEvent;
+class QDragDropEvent;
+class KPassivePopup;
+class StreamOSD;
+class HitWidget;
+class streamItem;
+
+/**
+ * This is the main view class for tork. Most of the non-menu,
+ * non-toolbar, and non-statusbar (e.g., non frame) GUI code should go
+ * here.
+ *
+ * @short Main view
+ * @author Robert Hogan <robert@roberthogan.net>
+ * @version 0.1
+ */
+class torkView : public torkview_base
+{
+ Q_OBJECT
+
+ enum {
+ HISTORY_SIZE = 300, // Speed history buffer size
+ SPEED_BUFFER_SIZE = 10 // Speed normalization buffer size
+ };
+
+public:
+ /**
+ * Default constructor
+ */
+ torkView(QWidget *parent);
+
+ /**
+ * Destructor
+ */
+ virtual ~torkView();
+
+ void hidePopup();
+ bool getShowTormon() {return m_tormon;}
+ void setShowTormon(bool tormon) { m_tormon = tormon;}
+ void infoUpdated(const QString &type, const QString &summary,
+ const QString &data);
+ QStringList subnet16List(){ return m_subnet16List; }
+ QValueList<int> countryList(){ return m_countryList; }
+ StreamOSD* m_osd;
+ StreamOSD* m_nontorosd;
+ void toggleAnonymizerTork(bool state);
+ HitWidget* welcomeitem;
+ HitWidget* hiddenservicesitem;
+ HitWidget* mixminionitem;
+ HitWidget* sshitem;
+ HitWidget* kopeteitem;
+ HitWidget* gaimitem;
+ HitWidget* pidginitem;
+ HitWidget* konversationitem;
+ HitWidget* gpgitem;
+ HitWidget* konqitem;
+ HitWidget* telnetitem;
+ HitWidget* allpurposeitem;
+ HitWidget* ksircitem;
+ HitWidget* operaitem;
+ HitWidget* firefoxitem;
+ QValueList<HitWidget*> menuItems;
+
+ KURLLabel *configurePriv;
+ KURLLabel *configurePrivText;
+
+ // Rx e Tx to bytes and packets
+ unsigned long mBRx, mBTx, sysmBRx,sysmBTx;
+ // Statistics
+ unsigned long mTotalBytesRx, mTotalBytesTx;
+ // Speed buffers
+ double mSpeedBufferRx[SPEED_BUFFER_SIZE],
+ mSpeedBufferTx[SPEED_BUFFER_SIZE];
+ double sys_mSpeedBufferRx[SPEED_BUFFER_SIZE],
+ sys_mSpeedBufferTx[SPEED_BUFFER_SIZE];
+ // pointer to current speed buffer position
+ int mSpeedBufferPtr;
+ int sys_mSpeedBufferPtr;
+
+ // History buffer TODO: Make it configurable!
+ double mSpeedHistoryRx[HISTORY_SIZE];
+ double mSpeedHistoryTx[HISTORY_SIZE];
+ double sys_mSpeedHistoryRx[HISTORY_SIZE];
+ double sys_mSpeedHistoryTx[HISTORY_SIZE];
+
+ int mSpeedHistoryPtr;
+ double mMaxSpeed;
+ int mMaxSpeedAge;
+ int sys_mSpeedHistoryPtr;
+ double sys_mMaxSpeed;
+ int sys_mMaxSpeedAge;
+
+ const double* speedHistoryRx() const { return mSpeedHistoryRx; }
+ const double* speedHistoryTx() const { return mSpeedHistoryTx; }
+ int historyBufferSize() const { return HISTORY_SIZE; }
+ const int* historyPointer() const { return &mSpeedHistoryPtr; }
+ const double* maxSpeed() const { return &mMaxSpeed; }
+
+ const double* sys_speedHistoryRx()
+ const { return sys_mSpeedHistoryRx; }
+ const double* sys_speedHistoryTx()
+ const { return sys_mSpeedHistoryTx; }
+ int sys_historyBufferSize() const { return HISTORY_SIZE; }
+ const int* sys_historyPointer()
+ const { return &sys_mSpeedHistoryPtr; }
+ const double* sys_maxSpeed() const { return &sys_mMaxSpeed; }
+
+ // calc tha max. speed stored in the history buffer
+ inline void calcMaxSpeed();
+ inline void sys_calcMaxSpeed();
+ // calc the speed using a speed buffer
+ inline double calcSpeed(const double* buffer) const;
+
+ /// RX Speed in bytes per second
+ inline double byteSpeedRx() const;
+ /// TX Speed in bytes per second
+ inline double byteSpeedTx() const;
+
+ /// RX Speed in bytes per second
+ inline double sys_byteSpeedRx() const;
+ /// TX Speed in bytes per second
+ inline double sys_byteSpeedTx() const;
+
+ static inline QString byteFormat( double num,
+ const char* ksufix = " KB",
+ const char* msufix = " MB");
+
+ void resetBWHistory();
+ void updateChart();
+ QStringList m_subnet16List;
+ QValueList<int> m_countryList;
+ void clearStreamMaps();
+
+ QTime timeLastTorUse;
+ QTime timeTorWasLastUsed(){return timeLastTorUse;};
+ QString addrLastTorUse;
+ QString addrTorWasLastUsed(){return addrLastTorUse;};
+
+ void setGeoIPAvailable(bool set){geoip_db = set;};
+
+signals:
+
+ /**
+ * Use this signal to change the content of the caption
+ */
+ void signalChangeCaption(const QString& text);
+ void showSecurityNotice(const QString& cleanedPort);
+ void showScreamingNotice(const QString& cleanedPort);
+ void showMyKonqueror();
+ void riskySession();
+ void aboutTorify();
+ void aboutTor();
+ void configurePrivoxy();
+ void aboutParanoidMode();
+ void showMyHiddenServices();
+ void startEverything();
+ void stopEverything();
+ void updateStats();
+ void mixminionHome();
+ void processWarning(const QString& , const QString& );
+ void signalCheckGuards();
+ void signalCheckTorNet();
+ void signalCheckBWSettings();
+ void updateTrayStats(const QString &,const QString &,
+ const QString &,const QString &);
+
+public slots:
+ void toggleParanoidMode(int);
+ void torify(const QString &);
+ void sendAnonymousEmail();
+ void anonymousOpera();
+ void anonymousFirefox();
+ void anonymizedOpera(const QString &);
+ void anonymizedFirefox(const QString &);
+ void showServerBW(const QString&);
+private slots:
+ void switchColors();
+ void settingsChanged();
+ void streamStatusUpdated(const QString &, const QString &,
+ const QString &, const QString &,
+ const QString &);
+ void circuitStatusUpdated(const QString &, const QString &,
+ const QString &, const QString &);
+ void ORStatusUpdated(const QString &ORID, const QString &status);
+ void guardStatusUpdated(const QString &ORID, const QString &status);
+ void bwUpdated(const QString &in, const QString &out);
+ void streamBwUpdated(const QString &stream, const QString &in,
+ const QString &out);
+ QPixmap streamProgram(const QString &port);
+ void activeServersUpdated(const QStringList &servers);
+ void displayError(const QString &,const QString &);
+ void displayServer(const QString &,const QString &);
+ void serverStatusUpdated(const QString &, const QString &,
+ const QString &,const QString &);
+ void privoxiedBash();
+ void downloadMixminion();
+ void downloadTorButton();
+ void reportBW(int secs);
+ void changeQuickConfigure(int no);
+
+private:
+
+ unsigned long readInterfaceNumValue(QString interface,
+ const char* name);
+ void setHiddenServicesText();
+ QString parseStreamPort(const QString &);
+ void populateMenu();
+
+ bool geoip_db;
+
+ KPassivePopup* m_pop;
+ bool m_tormon;
+ QStringList mSysDevPathList;
+ bool mFirstUpdate;
+ bool checkInterface();
+ bool gotEth0;
+ KURLLabel *paranoidmodeicon;
+ KURLLabel *paranoidmodetext;
+ QStringList greenonion;
+ QStringList redonion;
+ QStringList yellowonion;
+ QStringList orangeonion;
+ QStringList littleonion;
+ QStringList todelete;
+ QValueList<QStringList> iconList;
+ QValueList<QString> torType;
+
+
+ QStringList guard;
+ QStringList redguard;
+ QStringList detachedguard;
+ QStringList littleguard;
+ QValueList<QStringList> guardIconList;
+ QValueList<QStringList> circuitIconList;
+
+ typedef QMap<QString, QString> stringmap;
+ stringmap entryGuards;
+ stringmap streamPurpose;
+ stringmap portStream;
+
+ typedef QMap<QString, streamItem*> streamlist;
+ streamlist streams;
+ typedef QMap<QString, QListViewItem*> osdstreamlist;
+ osdstreamlist osdstreams;
+ osdstreamlist logstreams;
+ osdstreamlist torservers;
+ osdstreamlist circuitExits;
+ typedef QMap<QString, QPixmap> stringToPixmap;
+ stringToPixmap streamStatusIcon;
+ stringToPixmap cachedStreamIcon;
+
+ typedef QMap<QString, int> streamBw;
+ streamBw streamBwIn;
+ streamBw streamBwOut;
+
+
+ QLabel *welcomeheaderLabel;
+
+ unsigned int torbtx;
+ unsigned int torbrx;
+ unsigned int progDisplayCounter;
+};
+
+void torkView::calcMaxSpeed() {
+ double max = 0.0;
+ int ptr = mSpeedHistoryPtr;
+ for (int i = 0; i < HISTORY_SIZE; ++i) {
+ if (mSpeedHistoryRx[i] > max) {
+ max = mSpeedHistoryRx[i];
+ ptr = i;
+ }
+ if (mSpeedHistoryTx[i] > max) {
+ max = mSpeedHistoryTx[i];
+ ptr = i;
+ }
+ }
+ mMaxSpeed = max;
+ mMaxSpeedAge = (mSpeedHistoryPtr > ptr) ? (mSpeedHistoryPtr - ptr)
+ : (mSpeedHistoryPtr + HISTORY_SIZE - ptr);
+}
+
+
+void torkView::sys_calcMaxSpeed() {
+ double max = 0.0;
+ int ptr = sys_mSpeedHistoryPtr;
+ for (int i = 0; i < HISTORY_SIZE; ++i) {
+ if (sys_mSpeedHistoryRx[i] > max) {
+ max = sys_mSpeedHistoryRx[i];
+ ptr = i;
+ }
+ if (sys_mSpeedHistoryTx[i] > max) {
+ max = sys_mSpeedHistoryTx[i];
+ ptr = i;
+ }
+ }
+ sys_mMaxSpeed = max;
+ sys_mMaxSpeedAge = (sys_mSpeedHistoryPtr > ptr) ?
+ (sys_mSpeedHistoryPtr - ptr) :
+ (sys_mSpeedHistoryPtr + HISTORY_SIZE - ptr);
+}
+
+
+double torkView::calcSpeed(const double* buffer) const {
+ double total = 0.0;
+ for (int i = 0; i < SPEED_BUFFER_SIZE; ++i)
+ total += buffer[i];
+ return total/SPEED_BUFFER_SIZE;
+}
+
+double torkView::byteSpeedRx() const {
+ return mSpeedHistoryRx[mSpeedHistoryPtr];
+}
+
+double torkView::byteSpeedTx() const {
+ return mSpeedHistoryTx[mSpeedHistoryPtr];
+}
+
+double torkView::sys_byteSpeedRx() const {
+ return sys_mSpeedHistoryRx[sys_mSpeedHistoryPtr];
+}
+
+double torkView::sys_byteSpeedTx() const {
+ return sys_mSpeedHistoryTx[sys_mSpeedHistoryPtr];
+}
+
+QString torkView::byteFormat( double num, const char* ksufix,
+ const char* msufix ) {
+ const double ONE_KB = 1024.0;
+ const double ONE_MB = ONE_KB*ONE_KB;
+ if ( num >= ONE_MB ) // MB
+ return QString::number( num/(ONE_MB), 'f', 1 ) + msufix;
+ else // Kb
+ return QString::number( num/ONE_KB, 'f', 1 ) + ksufix;
+}
+
+class streamItem : public QObject, public QListViewItem
+{
+Q_OBJECT
+
+public:
+ streamItem( DndListView *parent, const QString &id,
+ const QString &program, const QString &target,
+ const QString &status, const QString &bw,
+ const QString &exit, const QString &circuit );
+ streamItem();
+
+ enum {
+ HISTORY_SIZE = 300, // Speed history buffer size
+ SPEED_BUFFER_SIZE = 10 // Speed normalization buffer size
+ };
+
+ // Rx e Tx to bytes and packets
+ unsigned long mBRx, mBTx;
+ // Statistics
+ unsigned long mTotalBytesRx, mTotalBytesTx;
+ // Speed buffers
+ double mSpeedBufferRx[SPEED_BUFFER_SIZE], mSpeedBufferTx[SPEED_BUFFER_SIZE];
+ // pointer to current speed buffer position
+ int mSpeedBufferPtr;
+
+ // History buffer TODO: Make it configurable!
+ double mSpeedHistoryRx[HISTORY_SIZE];
+ double mSpeedHistoryTx[HISTORY_SIZE];
+
+ int mSpeedHistoryPtr;
+ double mMaxSpeed;
+ int mMaxSpeedAge;
+
+ const double* speedHistoryRx() const { return mSpeedHistoryRx; }
+ const double* speedHistoryTx() const { return mSpeedHistoryTx; }
+ int historyBufferSize() const { return HISTORY_SIZE; }
+ const int* historyPointer() const { return &mSpeedHistoryPtr; }
+ const double* maxSpeed() const { return &mMaxSpeed; }
+
+ // calc tha max. speed stored in the history buffer
+ inline void calcMaxSpeed();
+
+ // calc the speed using a speed buffer
+ inline double calcSpeed(const double* buffer) const;
+
+ /// RX Speed in bytes per second
+ inline double byteSpeedRx() const;
+ /// TX Speed in bytes per second
+ inline double byteSpeedTx() const;
+
+ inline void calcBWRate(int torbrx, int torbtx, int secs);
+
+private:
+
+
+ bool dragging;
+
+};
+
+
+
+
+void streamItem::calcBWRate(int torbrx, int torbtx, int secs) {
+
+ //Calculate Stream Tx/Rx
+ unsigned int btx = (torbtx - mBTx);
+ unsigned int brx = (torbrx - mBRx);
+ mBRx = torbrx;
+ mBTx = torbtx;
+
+ if (++mSpeedBufferPtr >= SPEED_BUFFER_SIZE)
+ mSpeedBufferPtr = 0;
+
+ mSpeedBufferTx[mSpeedBufferPtr] = ((btx )*(1000.0f/(secs * 1000)));
+ mSpeedBufferRx[mSpeedBufferPtr] = ((brx )*(1000.0f/(secs * 1000)));
+
+
+ if (++mSpeedHistoryPtr >= HISTORY_SIZE)
+ mSpeedHistoryPtr = 0;
+ mSpeedHistoryRx[mSpeedHistoryPtr] = calcSpeed(mSpeedBufferRx);
+ mSpeedHistoryTx[mSpeedHistoryPtr] = calcSpeed(mSpeedBufferTx);
+
+ mMaxSpeedAge--;
+
+ if (mSpeedHistoryTx[mSpeedHistoryPtr] > mMaxSpeed) {
+ mMaxSpeed = mSpeedHistoryTx[mSpeedHistoryPtr];
+ mMaxSpeedAge = HISTORY_SIZE;
+ }
+ if (mSpeedHistoryRx[mSpeedHistoryPtr] > mMaxSpeed) {
+ mMaxSpeed = mSpeedHistoryRx[mSpeedHistoryPtr];
+ mMaxSpeedAge = HISTORY_SIZE;
+ }
+ if (mMaxSpeedAge < 1)
+ calcMaxSpeed();
+
+}
+
+void streamItem::calcMaxSpeed() {
+ double max = 0.0;
+ int ptr = mSpeedHistoryPtr;
+ for (int i = 0; i < HISTORY_SIZE; ++i) {
+ if (mSpeedHistoryRx[i] > max) {
+ max = mSpeedHistoryRx[i];
+ ptr = i;
+ }
+ if (mSpeedHistoryTx[i] > max) {
+ max = mSpeedHistoryTx[i];
+ ptr = i;
+ }
+ }
+ mMaxSpeed = max;
+ mMaxSpeedAge = (mSpeedHistoryPtr > ptr) ? (mSpeedHistoryPtr - ptr)
+ : (mSpeedHistoryPtr + HISTORY_SIZE - ptr);
+}
+
+
+
+double streamItem::calcSpeed(const double* buffer) const {
+ double total = 0.0;
+ for (int i = 0; i < SPEED_BUFFER_SIZE; ++i)
+ total += buffer[i];
+ return total/SPEED_BUFFER_SIZE;
+}
+
+double streamItem::byteSpeedRx() const {
+ return mSpeedHistoryRx[mSpeedHistoryPtr];
+}
+
+double streamItem::byteSpeedTx() const {
+ return mSpeedHistoryTx[mSpeedHistoryPtr];
+}
+
+
+class circuitItem : public QObject, public QListViewItem
+{
+Q_OBJECT
+
+public:
+ circuitItem( DndListView *parent, const QString &id,
+ const QString &status, const QString &server );
+
+// bool acceptDrop( const QMimeSource *mime ) const;
+// void dropped ( QDropEvent * e );
+// void dragEntered( );
+
+
+};
+
+
+
+#endif // _TORKVIEW_H_
diff --git a/src/torkview_base.ui b/src/torkview_base.ui
new file mode 100644
index 0000000..c2c5288
--- /dev/null
+++ b/src/torkview_base.ui
@@ -0,0 +1,1005 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>torkview_base</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>torkview_base</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>753</width>
+ <height>540</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>tork_base</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QFrame" row="0" column="0">
+ <property name="name">
+ <cstring>frame4</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>730</width>
+ <height>78</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>199</x>
+ <y>63</y>
+ <width>521</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>199</width>
+ <height>79</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image1</pixmap>
+ </property>
+ </widget>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>frame5</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>199</x>
+ <y>0</y>
+ <width>515</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <property name="paletteBackgroundColor">
+ <color>
+ <red>0</red>
+ <green>154</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>711</x>
+ <y>-6</y>
+ <width>20</width>
+ <height>90</height>
+ </rect>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="pixmap">
+ <pixmap>image2</pixmap>
+ </property>
+ </widget>
+ <widget class="QFrame">
+ <property name="name">
+ <cstring>ChartFrame</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>198</x>
+ <y>8</y>
+ <width>515</width>
+ <height>60</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>28</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>Box</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ </widget>
+ </widget>
+ <widget class="QTabWidget" row="1" column="0">
+ <property name="name">
+ <cstring>TorkTabs</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>690</width>
+ <height>0</height>
+ </size>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Anonymize</cstring>
+ </property>
+ <attribute name="title">
+ <string>Anonymize</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KWidgetListbox" row="0" column="0">
+ <property name="name">
+ <cstring>Anonymizer</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>500</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>StrongFocus</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TorNetwork</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Tor Network</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSplitter" row="0" column="0">
+ <property name="name">
+ <cstring>splitter5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>Network</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Network</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="DndListView" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>serverList</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="KListViewSearchLine" row="0" column="1">
+ <property name="name">
+ <cstring>serverFilter</cstring>
+ </property>
+ </widget>
+ <widget class="QToolButton" row="0" column="0">
+ <property name="name">
+ <cstring>clearButton</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QSplitter">
+ <property name="name">
+ <cstring>splitter4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Connections</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="DndListView" row="0" column="0">
+ <property name="name">
+ <cstring>streamList</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QSplitter">
+ <property name="name">
+ <cstring>splitter3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Circuits</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="DndListView" row="0" column="0">
+ <property name="name">
+ <cstring>circuitList</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Routers/Entry Guards</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="DndListView">
+ <property name="name">
+ <cstring>ORList</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </widget>
+ </widget>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TorLog</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Tor Log</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView" row="0" column="0" rowspan="1" colspan="3">
+ <column>
+ <property name="text">
+ <string>Time</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>id</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Severity</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Summary</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>infoList</cstring>
+ </property>
+ <property name="resizePolicy">
+ <enum>Manual</enum>
+ </property>
+ <property name="hScrollBarMode">
+ <enum>Auto</enum>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="showSortIndicator">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>NoColumn</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="2">
+ <property name="name">
+ <cstring>clearInfo</cstring>
+ </property>
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>370</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="1" column="1">
+ <property name="name">
+ <cstring>ShowHostNames</cstring>
+ </property>
+ <property name="text">
+ <string>Show Host Names in Log Entries</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TrafficLog</cstring>
+ </property>
+ <attribute name="title">
+ <string>Traffic Log</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QSplitter" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>splitter4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox5</cstring>
+ </property>
+ <property name="title">
+ <string>Tor Traffic</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView" row="0" column="0" rowspan="1" colspan="2">
+ <column>
+ <property name="text">
+ <string>StreamID</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Time</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Host/Port</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Circuit</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>TorTraffic</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Single</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="showSortIndicator">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>clearTorTraffic</cstring>
+ </property>
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>240</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox6</cstring>
+ </property>
+ <property name="title">
+ <string>Non-Tor Traffic (Not 100% Reliable)</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="1" column="3">
+ <property name="name">
+ <cstring>clearNonTorTraffic</cstring>
+ </property>
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="0" column="0" rowspan="1" colspan="4">
+ <column>
+ <property name="text">
+ <string>Time</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Host/Port</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Program</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Inode</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>NonTorTraffic</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="showSortIndicator">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="1" column="1">
+ <property name="name">
+ <cstring>NonTorTrafficMaxEntries</cstring>
+ </property>
+ <property name="suffix">
+ <string> entries</string>
+ </property>
+ <property name="maxValue">
+ <number>2000</number>
+ </property>
+ <property name="minValue">
+ <number>200</number>
+ </property>
+ <property name="lineStep">
+ <number>100</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="midLineWidth">
+ <number>1</number>
+ </property>
+ <property name="text">
+ <string>Clear after every:</string>
+ </property>
+ </widget>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>spacer2_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </widget>
+ <widget class="QCheckBox" row="1" column="1">
+ <property name="name">
+ <cstring>kcfg_LogNonTorTraffic</cstring>
+ </property>
+ <property name="text">
+ <string>Enable Logging of Non-Tor Traffic</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>kcfg_LogTorTraffic</cstring>
+ </property>
+ <property name="text">
+ <string>Enable Logging of Tor Traffic</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>DndListView</class>
+ <header location="local">dndlistview.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image3</pixmap>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <slot access="public" specifier="">contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </customwidget>
+ <customwidget>
+ <class>KWidgetListbox</class>
+ <header location="local">kwidgetlistbox.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image1</pixmap>
+ <signal>selected(int)</signal>
+ <signal>doubleClicked(int, int, int, const QPoint&amp;)</signal>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="6499">789cedd8cb4ec2400085e13d4f31811d31da52063a312e002f8828b033312e4a2f200a2a3745e3bb9bff98f8129df3afbe0d04328b4e4feae67e7c6bea2795cd36d93ea5269d276b53cf76cbe5e1e1f1ecbb52b58dd084a1695a13568f2ad563939a5a10381745b0263ad78c6298c0308eb3a88053d848e3a8e9600a9bb6ddb61666b0a5c15ccc0816b01d139cc1588373e852824f706a092ec416c1673126f8223a824b3125f82a160457300d08be8921c177b141702d5a821b3126b81533823b3127b8875940f0438c087e8afa77e041d467c12f51831d3127d8150b823d980704cfc506c10bd112bc141dc12b714ab02fea37c06b515f0c076241f0061621c1a11811bc152dc13bb1457024b6098e4547702226a423eae7c7fc61f0fb9f3f0c7efff387c14fab257f4f7d999f5f5ecce6ba4df8957c8bc5e2f965b9d27dd0afec5bbdbdaf375b5de1fdcabedd6efff179d05b17bf72afd3e9747be717977a33e657f6f5fbd7839ba15e66fa957e77a3d17852fd39adfc02a2b1b9c2</data>
+ </image>
+ <image name="image1">
+ <data format="XPM.GZ" length="61153">789cedbd4793eb3cb2f7b9bf9fa2e372f7c604df92a18b8959a8bcf77e621600ad488a46a40c3931df7d20fc13285fe79ce754f7ea36a2bbcfaf4802894c20330142d2fffe5fff7abc3cfbd7fffadfffd5b4ac9dfafff21336ffd7ff0a16b359f77fff3fffd7fffb5fff3df0bc7f39debf06ee68fcafe17fff1ffff5df66f22fff5fc696fc8fe458f360c346aa59de6f449a47925dcd63c9579a2dc94bcdf6867bc503b4c7ee34cbfaf98e6659bfdf6896f5fb03cdb27e73ad59d62ffaabd8d97037d1ec6e387aa9cf936c696652de9566bee1554b3c847c2cd42ce5638666f47fa259cac71ccd523ef341b3948f979aa57c6ca559ca175b9aa57c71aed997fa3c271ec15eab8566c873a059cad33c69863c579a21cfa566298f79ad59ca13ee6b96f294bb9aa5becc956629dffc5e73b0e1fa96784cf67bd42ce5e1be66298fb1af59cae39f6896f2f05eb39427bad02ce5f1c79aa53cab2dcd529ea6d61cc9f6943dc703a9cf85d29705f9e223cd529ef040b394677ea759cac32e354b79d852b394c7d8d62ce5314ccda1ecdf0b4bf99a67c5906fadeb1b487b771db10dfdcd5acd52de75ac59cabb7ad28cf175a859cae78f344b79c27bcd529e56e9df46fb6b35be1db4df0c35c37e9666d97ed76b96faa9cf34cbf6f9a966a91fdfd02cdbe785e281f42761a959eaa79d6896f3b76835cbf9bb5e6996f2b7b666e8eb58b3943757fd73495fae66d8b7d32ce58ff7344bf99773cd529fb192df85fcc6bd66293f6b34c3ff30cd52fefa46b39c4ffd4b7d98df5a1ec8dfcf344bf9176bcd52fe6545ecc13e95a959de5fa79ae5fd79a919fd1d6996fd9de79a657feb4bcd986fca5f79e8af116a96fde3679aa57de203cdb2bffe8566d9dfc550b3b4df4af707fd5f3f6a96ed576abc33ea4fa559f62779b92efbc302cdf2795fe98741feb0d02ce50b52cdf01f8e66cc8f81668cffa966f8f76dcdb2bd85be7f28c74bafeee79077f9a459ca9bb89ae14f6acdb2be508d1f4ef3c7d62cfb532c34235f88344b7b442ff723de7b9ae57899359a65ff3a355ef850dedf297df9e49f1f354bf9fb0bcd982f9966297fa2f2051ff21773cd52fe3ad68cfce552b3943f186b96e3835d6b96f227fb9aa5fc69af59ca93df6b96f22c957efda1ac7fa9e24180fe640f9ae5f3d35ab37c3e50fd0bc81f0c34cbfe749666393f827dcdb23d3ed12ce54f95bf08305e6673cd521fbdba3fa4f979a159cab356f331843c4da959ca53199aa53d5b47b31cefeb5433fcff5cb36c2fd1f743bee9b56629df54b7077d66f79a657beba966d9def2e53ae2cbb666cc27e5ef228aa76a7c46e8dff44633fc51a619f968a959b6e71f6b96f3397a795e8e1723d62cdb672fd7616f954f44d4df4ab3ecefec51b36c2f9b6b96ed6524ff600bf2f6b166595fb8ab19f1ee4033f24347b3d4d7f25133f2e16bc5902ff434cbe7134bb3942fe59aa57cc548b3b47fbfa319f912e9733080fed34eb3ec4f34d22cdb4f7dcd18ffb166391ea25ab394c7986a86ff7fd62ce723cf140f657be944b394b7dcd62cf5b17cd02ced5b31cdf05fba3f23d99f15f937513de6ef9166f467a059f66779a359ead79c6ac6fc5a6a96fd2bb6344b7d335331ec13e8e7315f923dcd88ef5cb39c8fdda9e29194674ef9fa6004793ba6595e4fb735cbf65663cdb087a119ebbf17c67ac3d52cf51d0c344b7dfb5b9aa57e8ba166e483ad62f437b635c33e4adf23d8a327ff3d1893fe0dcdb23f7daa19f954ae19f3add28cf1b1a719f9ea4ab3942f5a281ea2fe5dcdc8974f148fb07e7bd62cefef285f1b507e3fbfd18cf8e96996f24c5feec7fa28d58cf5d09166e433b566f8a34431fc7170ac19f369ad59d617ef6b46fcd0cf43fe29ad2f0736e45dde6a86ff5c6ac67ae95e33fca79a6f36fc89d16b96fdf3879aa5fea35633faa3fc930dfdd65a1ec8b752fa7268bc9e69c6f89c6b96fa5d6c6946be5f6996fd375eae233f3c578cf117ebf64672fccd1f344b795ad51f17ed8733cde8efb366ac774f354b7bae8f344b7998ea8f0bffbde83463bdf8721df98fab19e3438d2f17f2973b9aa13f25bf0779a78566a9aff90bc3df3f6a96f2f350b3d4e7f452b3b46739d18cfc755733ec7ba818f3cbd4cf633cf20bc5a45f353f19e46b1e3563beec6996f2e5379aa57cd15233f217159f281f9fe69a657b95af19f9b2a919f5a9f8ca20df9af2eb0127f91e34233e379a313f669aa5bd162bcdd08f928fa37d76a1598ef742d787f9dda8f1cb214fa2fc39e5c3cb52b36cbfef344b7b995b9aa53c9dd2af8ff167349a65fd61ae19f9c8b966f80735be7dc8d3a8f946f96d34d78c78aefc29e5bbf9b566c4d34633f69b8e35633da6eb43fc9f3d6846feb0d68c785f6bc678d3f2617e47979a31fed4f321ad87ee3523be0d34633f68a859d69f6e6996f665cabfa9fcf95c33d6a37b9a65ff625d1ff5afd62cf5d9a9f94ff96a9f69863d8f35c3dfabf11aa17d73a659b6ef3f6986ff56f94344f905d967b845f53f6886ff7a548cfad3b566f97cbcab19e33bd20c7f3ed40c7f7aa719eb11ae98e61ff99321e587eb4633e6fbae66e83f510cf90c5b33f6932ccdd80f78b92ec75fe86a86ff7db98efd883bcd583f2c14d378a2f9391c429eb5ba3e843c8b47cd723c56079ae18f6e354b79a273cd98cf378ad15ea0f439827d8bb166f88b6dcdd87f5a6ac67ecbb162c413bfd60cfdd3feca708cfad9b666ecb78f35a3bf4f8ae9799a4f430bcfcf679a91bf469a914f559ab1beaa35637f774733f2b9b166391ea297e7a53cb11a0f16fa67da9a917f5c6b463e48f9c8d0867cf94c33de1fec6846febcd28cf17ba919f1f34c31da0faf35c31f3c6846fb4a5e07fae82f3563bdd16946bc39d42cc747b5af59ea675669863f54fda1fc26a4f5e6d0257ddf6ac6fe61aa19eb9113cdd82f54f389f28f851a5f1eea8bc79ab1fe7cb92efd9be96896ede58566f85b35df285f58a9f1c4505f77a719ef6b1e3463bfc1d12cdb5b2d35c3df1f6ac6787ab91fe359d983c15e3ed38cf500c5cb21a7f5b4a919ed679ad1bf5bcdc84ff714a37e634733f693d5fcf7495fbd629a5faaff01fab36e35235e5c6b863fb735cbfe996abe06343e2bcdd85ff43463bed3fa751892bed47808f13cef34c3ff28ff46f1a5237f38daa2f1b8d68cf93a550c7d704333da277d8c683d1f3e6ac6feb4ba4efed1a07c4bb833ecd75f69c6fd8ac95f2d289f1f917f080e34cbe7fd43cd789efce388e6af41fe7444f3cba4f13ca2f961523e31a2f11caafa683c1964bf11d99f93bf1d91bd19e57b23b28741f9d188f4cd687c8c48df3eb53f26fd45d4dfb1d217d9774cfa3229ff1f937e0c8a3763d20fa7f13ea6fe8734ffc7d47f93f2d931f5df504cfdf7697c8da9ff098dc731f5dfa4fe8fa9ff4c31f5df277f3aa6fe9b64af31f5dfa0f137a6fe1b24af45fd3768fe59d47f83e6b7a5faafee57fd27fb5ad47f93f46d29fbd3face52f6a7f168a9fe533e6351ff39c53b8bfa6f923e2cd57f1aaf16f5df207b5bd47f83e69ba5fa4fe3dda2fe9bb43eb354ff69bd6353ff4df2e736f5df247ddaaaff94dfdbd47f93dab355ff697cdbd47f93fa6f2bfbd378b6d5f8a7f963abf14ff1c956fd27ff67abfe533e6753ff4df28736f5dfa4f960abf14ffab3a9ff9cfc8badfa4ffd7154ff291e39aaff341e1cea3f23fd39d4ff96ece150ff0df53cf59f91bc8eea3fcd0747f59fece750ffa7341f1cd57f8a670ef5dfa7f1e3a8f1afda57fda77cc851fd57ed53ff43d51feabf49fa7095ff247fe052ffa7a41f57f59ff24997facf68bcb8d47f46fbbbae1aff144f5db57f43fecda5fe738a972ef5dfa0f1e652ff338a5f2ef59fd17c7195ffa3f8e5aafed37c74d5f8a77cdd55fe8fc6ababfa4ffdf1d4fca7fe7b6afed3f8f554bca078e851ff7dd29fa7fa4ffaf2a8ff3ee5539e9aff641f4fd99ffae7a9f14ff980a7f219f477b079e32be3f519b183f32ceb9c98de27f59067280c8af515e41d7a6c84fd51f897913acfd1613c6cc221e229e6df48ddbfc67c1a7b7c847c16fdb3b6389ddf41ff2c715de65b2dfcad2d24427e88f1608beb52fe25e287a3ce97ac313f1de15f71be01e3d955e73552cc6fd7f3717d09fd78eafcc51af1cc1bf8b45ec6fcf4bc6084f781580f32c132ff5980f916ed87b71eb183f7e53dc60717e983cc3fd60531ed97ac305e7d755e6301fb055bb4bf9b3f11d3f981c53931bd8f8fa1ffd08b46b2fe06f133daa2fdd3c58498a1fd0ef94f24ee97f9cf4ab6b779db43ebc73db0178d65beb394e3633050e707960171087b0417602622fc86e7329f128b61da4f5b19c4f47e37bb04abf751b99cef83917a1f15a0fd111b8c65fe534aff36186f3426c713076f8aecff2d58dc8ffc55ea7b20c613ed173c80d5fbacc99a98f6f7d9ad66a9ffc94a33ce8b2560d71de37dee3358b4273997f179600fe8bc1083fc361b8e65fd35e475843c987f0131ed772d7262dabf299760f53ea192f36520ac8ff56c8ff65db51fbd86fe5d911fe27d385d67a3b19c4f13e8d753f54d02628bf66b0f886d5c9fc17e6c30a0f7152d31edcff74fc4b43f3a91f371c0953cab4633f637f7c16c3c96e36126fdab18fdb49fdba17d7fcc317ed6bb60cbc2fd4b19df07817a5f307b26f6b03fb3b489693f7425f38f41b8c5913f1733f06084f552db1007683fc4f80c993596cfb772fe0c22b5ff9c8e89e93c433f24a6f9cbe4781a0ed4fe737a40acc65fab19fab488697fb40fc1c331e45b7330b3c7383f23fb3f1c0e68fd3d37885daccfaa5362aa7f7e0156fb610dea1b0d687f62ea12fb686f85f6477a3f8a819933c6fb71399f869bf41def6f1c627abf9d5f82557b1dea1b33c792fdafe5f81d5a0386f5e164494cfba555484cefb77bc8670de97dec72ad59f62fd80233d782bf91e361b37b82fbf908acae67b82ed22df8b7664c4cefe7fa476207fe9e6560e65972fc2ce5fc19ba030bfeb51a13fb907ffa0456f65b8c35cbf15be79a315f38b185fe6419b17a9fe58345fb581fc29edec019c11f34c4b47e6e1660513fde47a13d4f3c0f7f85f1b17157b2bef28138407c2e67c4e148de3fe9c042df523f13464cef2b03aa6f68917e97c4f47ea93f26a6fd8f16fde30317f1248dc1a2bf529ee25931f4bd86fd386316ceab42fffec0413c68e79ab19eebc14307cf4f1262daff590fc116f99f0ef2fa8c5bf08fd2df0d03610ff8a719b10bfd67379ab19f9b127bd047b126a6f73b21fa1b88fa65fb4b99ef0dc38187785042bfe190ec53c8783e8c8603e413a54b4cfd8f4a30f32d29df44d63fdaecff227f1812d37e413f2226fd272131f577794e4cfb27dd183c1ec1ff752bb06a2f91f9c368203488e72de208e327e6e0319d67caa47e46c3a10bf9928e38803ea673300b2cd95e22f397d16818a2bd468e9fd178a301d91f39df47969017efc751bf35122b58e97fe4fc18394386f130ed8823e46b810b1e0dd1de1afd712cdf42be7705669105ff28c7cfc81d6d8de4f5729f784cfd592bc6f30bd8c3dbf4508e8f1d62babf77886d8a470fc42ef2cf899cef2326d247d9bf49483cc6fd71496c5938ffc6c0e310f16825f7ff465c680cf29c2926ffc0886df8ab54fa8fcdee0ef2977e4c6c61fe270f9ae5fdadcc8f4681989f52de2224f6c7386f08fd0623daef0e6b62cf96fd992d8919bd0fdb065b74fe3194f363148e18eeef1f8843b4cfa01f31da30ff1339dec75b236ec33f4af9c603e18fa4fdb2123cf2717d6a120736f6fbe5f81f0fc5fc93f517f760319e30be3b621feb8f680a7607b6f4ef1d070b8562fd21e3a3309645f51f8085c472fec62bf04602a94f192fc6c2db40be490416fa813e7be210eb9be8196cd3fbf1ae053b36fc4326c7ffd81e913f99421ff698e49db6c443f044c68bf1663e207e71e2688cf5879c5f6377a301799d98db36f211e8d313e104e781ef15c37f2cd11f11ed6dbc9fdd01dbf43e7085eb5c48847cb3506c63bf1afaf6372344da1bfaf3c72eda6f326286f622e8d3b703e4635d0ce68e83f75fd2df8c836160cbfeae72b045e3d9b7c1dc75906fa0fd7018388847682f14f2607d47d7c72ef2eda941cc507f047d8636e5b773e94f36bb83d4fe2178ec213f5a58c43ef2df56e6c7965820235ec6c7c43efa13f9606780f8564b7f26962b1e9e8fd78a21ef52ae47ada1d030d61f47c43e8d973be210fd5da2bdd1307290afe460313f917fd3f551085e1d80457d38bfb8208e50df42c6534b4c0007efd7af89c50896ed6d81458f909fe0796b44f69a5d81c5f895f64a1f8943ca0fd01f4b6808e7bf71bf2ddac3f9f68ad8222e896df012f2dbe279ac0fa4ffb19c91e3c8f1356989a9bfbd0d1e07187ffd80588c0069ef39d8a2f5575183b9ef48f95b395f2c77e4a2fe24005ba49f05f4e3097965ff97896257dabfad885d478ef7b624f61c393faa11588c00d99ff88698e25f7b454cf17e714f6c59f2fe24560c7912e8d7e301f4d5caf96a31b14090edd7c7c41cfd5b627c8ae514ea4f0f892dc81378c4b6033e2176f0fc02f2f291e3c2bf17c49e83fcfd9298a1bfed8c98839b0b621ffa9b34c411ec37817dc46a93b8261e8223cc27ee503c8dd03f2efa2ffbbbc0fdfec875918f3e127be0e69c58b50f7bf9aafe1923f6a1ef98ae5b2e8d47e83f10f563fd7645ecbb727e37ea7a40fa4814637ce4d07720fc25f667313e0397fa53ed8179087d2da04f117fa9bd33e210f535117144ed858a21cf04e32f54fd9bcc8847e072ac98fc49416ce17a057b846206e1fc8b4dec61fd1b617e842e9d1f68a1ff48e8433e3f3f058fb720effc847840f2f5c41cf139447b91b030e22de4896c1ff165f1401c51fc803f8a360b44d9fe80d8c5fc68e9ba3b22fd603e4562c106a6fad9103c873d234ef7d72131e9b796e3c3de1ad3fdf50eb18dfeadf6c1c2c34879c32db0e3433f5d00e611f90be9df6d917d405fcd943872a5ff9c1f8385be703e64424cfea66fc0c25d63bd6611537eb51c100718efe139d8a5f7e9614f4cebff06f26d96cbc89718f188ec1769c6f9c890780c4eaec116adcf62cdc86f6647c41ef2b994ea13f2e2f3030be200e32fa1f6ad10fa0e9fc10e9dffe243b0bf45f34ffa37115e4634fece34cbf1300f882df8afca2276d1bfa907b642e82f7b228e6cf85bae18f22cd1bf91189f18ff321edb63612f9c0f3c251e81eb43621bedcf7dcdd80f588145fb88372dd8dea27cf94431d9ff8898e67788fe6edc0bec27fd916d89fad1fe01b183f1956460315e115f208f650fa14f7e03f607341ed09e6810faadf7893dd467c03eb6188ff02ff7603123301e4e8869fc4c0c62d103d91f8fd8c67a61622ab6715ec7d78c789082fd21daaf219f23ec89feee117b24af49cc707fd51207e85f8efa1d6b00ffd1a1ffcea66c783d06abf62ac8eb8e39cd5ff4c715fdc575b9feb285b7c4f80b6ab06dd3fcc67812d9b28b7cdd20f6c195431ce2f9aad38cf50dfc01db245072fced12dbe010e38fb9749eab92f9a7cdc7912be3f914f39f8b1180f630fe7c6b80f6b323620ffd4fef8903e4032bf827317be19fa7cfc40eea5be68ab17e98a5c42e78d5117be85f5480c58202fb73e84f20e4c57a1ff33d10f2e1f3034be221e40d4ab0a80fe7c3e87e6f84f55d85fe86d616d537201eb99007e325143300fbd7dbc4b41e595d1333d41f54c41cf29632dfb023914e61bf688bd8427b6bf437b207f017d38c98ec1d62be469e4ff692f1d6d912f5c9fbcb67621bf52df7c136c37a71b5260e505f29f34d6760591ede5f34c4f47ce411bb36f2cf086c73ccbfe08c38a4fec8f8ec0c2dc745fecf8919fadf5e80c508c1fb0e8338827e2be9df1d912e7bd8dfac8919fa972460757fd8813d0febb952eadb195b1cfd2902b0d020ce0fa66091cee3ba1c7f8e65f9682f3e078b19887c709f38c0fec672ac18f96f526a867e12e210cf9754bfd038f211ba2e3486fc0ef6b0bc01d6e3a5f4378e6d310ffb8bb7c41cf21537c4246ff9a419f115fdb7ed10f2cda04fdb19603e16727c3a8e15e2fe39f4ebd8b45e5c5e818543c47890f34d048380e4b9228e3cc4bf102ce201d67f0e78d323d9bf13b0e752ffa02f4f3c8ff767db606151ec4f17c4f47cb54b6c43de42e6438e18cd1ece07c29ecc1ea0be790656f73733cd52be869e17cb15e443329f72b83df470be17e3970b89715de6d78e2fae633d986946fb09f118d717e8af185e58ef8618ef3ea3f5e90cf70bff81e76717c4c22149fd63be84a247525f859cef4ea4aecfce891df0dc050b0bc2be053143fe519c1173d457ae897db4bfa6fa1cca57820730f3b17f17ef807ddf43fd525e774bb48ff5e303d809507ffcac18f577fb6097f2919994c71dd81eea6b9660a1017c1ee94931f557c6277768330fefcf50dfd0a1f8b0a0eb4223f83c6fae18f5470cec310bf145dad31dd98c419e88d847fd650616f6c37ed81e31ad2fd21171847c60760776b73cf8e700ecd17ed04a8e5f77ecf8944fa1bf637780f6a6687fb36181fde680d841be90dc1333f8d36a40ccd1dfba230e102f52e8df123d96f5872bb01761ff28a4f65840fb7772febac25f7838ff8bf66d67cb93f5970760a151e84b8e47d7b143e82f3b063bd45e8cfe89d53ff6e322e8d3f1230fe311edbbb6585149fb79e0cd0bf10d73d4effa11ea0f604f2fd862f27a0e7b3391a0e1fde49298f6fbe63b60212fe6fb21b158a04a79b6c02c44fcc9e57c75b963439ef49ad8a5fcff8998a1be790b16231ce743d17f1e0cf07c2ef321d7771c86f74d18afbe180178bf0cfdfae27e9c9fc07c08443a043ed78cfdb11e2c9e87ff7d2266686f7545ccc1c91c2ceac7f844ff42d13fec273b6031fef0fe85138f11bf5674bfb088b4ffc224f6d0fe624acc115fe247621ff27723e210cf338cc73018a23f11c673a4e2cbcc27f698f417f9313163385f3e25f661ff05e48fc488433e7b484cebf9da25f610ef7239debc2d87a3fdf20eac9e6f1c6217fd998f893d709a10fbb87f35250ea0dfe016cc7c3abf22e7a73750cfe7727e79623d8afe15a760757d2afd833772d5fa18cf8fbc01ee9fdd838331437f20cf58d487fd47f447ace7901fb5a7c4948f3426586840cef7f580788c78b99e83c5f202f16a42cc28bf531c61bf797d0dd6f2c8f9ea592262c03f2fc162c4e1fb303ce208fb0bf33db09227847e2c3ea6f51fdd1f580ceb0b391f3cdb151a96d73b620eff5edd12fba8af21f6b6108f675bc403b43f93fe4c289ff61f178760210ff265837888fb8b9298e4f1315e1c211fce97c87c4b2c262c8c87850b16f5a1bf43626a3fb58887682f7fd60cfb6d118f10ff9a9166bc2fc9c122dce2fb28606f6fe3d1e5f519585d8fa5bff298d27f6d833ddaaff1313f58e030c44fe99f3cee3a1cf9e53158dc8ff9b74b3c064f0f15237e2c22620bd7eb19b10b8ea0ffcd7634e215c69f2fe693d4ef14f3cb171693fdcda43ff284bfe3727e04980f81bf85785cca7cd80b853cf0d719b1dabf89883dc4ebf69298f61fd7b06fc81cccb712f32b12331ccf97c416e2f7d427a6fd91d50d71007d71ccaf28f0206f2aaf33e12f707d6e813dda1f4ef7893d8a873e31a3f87f411ce2f94cc60b36707d8ef7f1a86f203c10f6a7f689697cce4c62da4fa8a6c4b4df5178c4d45e556bc6fe924dccc1b99cbf6c283c189e3f22a6fdb3a623a6fa0a5333fcb54f4cf5a50be200f123368869ff7385fe0d5980f1cc6fc19b031ab27f727eb091969713fbe0d9ae66ec1758c40138af1553bc91e3858dbd01f4bbda210e313ea68f9a715e881147584f77d7e04d91fe2d01fbf47e718df6c701e7b2bd1cfab1c4f8c2f9959e58c9fb4c4cf256b0bfc568ffa5a6fbd910ebef601bec07580f64d23f33b1fae19037208e707fb102b32df427de221e43be059e77c40886ff813e37fb5b78bf0afd3981cfd11ec6df26bc211f6cc0a27ee833261e227ed43eb145f3af27b6216fb006fb43c4a342c62326660bf6270a4e3c42be913bc4b41f52ed28467bc939b103794b30f342ec27a4259851fcc802e211ed0f3c10bb783e5c827dca1f8247e208f9de1ae39505c2e0b23e8c07ee391cfb3b31b10f7d17d08708bfe84f71486c235fca7788697fa4bf27e688bfe11358d807e775313ec5f0c3fdf36d627abe8d8919780dfdf97cc421bf4b2c22b41cdff01fbe1f72ec57d9c41131fc891f8cc19d494cf72fe03f0246fb4d996217ebf5d92d31e7389f89f114a8e7e7181f623642dee505b18b78525e1173acdfbb8638447ce3b04fc83dd88f3f113362d8370c2c8efb9f896de27be2085c409f919007fefe82d8a3fd118fd8c7fe4208fb463ec37e4b10828331dea777097184f1914bffc6b78487c1fac223a6f696bbc4b43f530d3563ffd8210e713dbb560cf9eb8098dae377e020f271de0f3c101117e703f688238ce7720a16f2c8faeb153147fb654c1c613e959e62d4df19e070cbc7f7f7c87c810f95be56a7c4143f932bcd385f7f401ce2fe588e373ef23cac5f73d43fda7858291fea1bf12dca27d0bf5140ebc5f50e381ca0bf35f43f16f303fe8013d3fe493d270e70bdba24a6fda96a8b38027362513fd6a7d087a5ee5fee10d3fd4b06161a473eb8473cc6fa6d72446c411f89dcffe1b698b190bf02f32d3c9fdc12537e391d11abfa0e896df8a314f73b22a2c05f2f883d9207fa77d4f305f4ed72dadf581c13533ed786c4b47fd4cf895df8fb995c7f89d949fb0953c523dc3f3920a6f95bcbf92d662fe5c7d98a784ced999a711e2a2476a9fe1d620fd7338c2f2ef489fda59ed886ff294e885de4bb01ecc38311e66f3c008763d2978c275c7877dc5f5e137bd80fe97d62f277937d621f5c4bffc403a12f399e7dc81f84968ffd3c3c1f8af10779f17c28e4c37ef98c98d17e8ead18f33fdf25e6585fcf0e89033c1f53fd3ead27a247620ff95a007d87c100f126088869bf3a87fd2231feb0bf3421b6697e36c424efbc23f690cf9627c40cf255cfc43ef2e5c92931f92f1fed47423ff8fe5aa93f7f4b04589c47392056fddd230e693f2553ece3fc105ddf1429afcc47fc8d3f43fcb6c17c1ce0bce71531c58bea8298da4b2f8969bf64ee81fd2de48bfd21f100fe7025f5eb0f05e3bcfb1df110fe2995f9973fe262c52ce7a34b1cd27e52a6d8c77e9001f647688fb7e020f0e1ff1b70e880e7e89f88e6a86fb54d1cf9f0cf3d58c883e71370e804525f13693fdfda14a9af2370e80658cfc87cd8b78507c7fec99838c47e4d968345fd783f7a030e683eb10158d5574a7fe53bbe857c363b24b6915fa60531adf7725733ce57ee2aa6f6a02f47a4df783fd01307c82719fae3841eec9f49ffeebb3eeddfc467c443ccd7c588780ccef78949de32252679eab566e4afa662b45755c42ed6cf9363c53efc3dc6bf2be493fa8d307e3c311ef0fd9218af9e6a2fbe578cfb7de8db0b02e4db7c0a16f5613d8dfe31319ef07ec0251e537d97c416f2d328060b8785fc04fde5a245ec674d89e97a7f40cc713dc4f8e0eaf906faf1857db13e4a881db437db2766580f17c79a919fee11fbf017510816f93af6cb313f36e9aef4ef2dee0f84be112f0e88a9bef92e31ad57bba162ccdf00fad8a4b358ef487f25aa0f61bf12fa0c55fd554aeca1bea5a959fa97be261665c36bd41f8afaa5fe2bd83b52f2851c1c8e39f65f4b623f80fd64ff82cdd7a7c29fcf88235caf1d70b085e727e78a31dfc32bb0aaaf93f123188462c2487d49ff11087f06f9cb0b62da0f6a0f8803d49f9ac421c6e3ea8c3802070d3818a07e4ecf8bf6b0be95f60f46fe90f6b756c436b87a2466686fde100790673e528cebad4b1c61fc4d20cf685364fd8c784cfb353eb1857c6c4d1c6e05d06f4b1c8033e96f83b14ff6498f8869ff679683458dc89f38f118f3b160c4b45eab70bf25d667f83e8a6b706861bef031b11040b627fd45606f0e5ccbfe72e211ea4b57c45680f1774b6ce37e7f07bc798129f98e98d6cb1dc687b32972be1d8243b1e291f35f8e77e16c46b0673321a6fd8800f2bb21e547f1367114e2bc23d80b543ebc20f6707d0dfd78e1001c1e138b0821f52be3b198bc03da9f91f948c08321f683ca15b183f1b55c10b310e7932a628eeb013d2f122c7c7f9e8c0fc219d0fec67c414cfb11dd80d8877d438c3f3ff4e0af138c173f1a848897e040f417e7ab436207f6c9b78949ffb31bc5b0f772a419f73f127bb0c7f49ed8477b26270ef0fc1afe2110fa447e26e36b10aaf6a643628fe3fcf10931c7fa71ba240e427cffe89c38843c2bd83f0cc7b85e607e47aabe926b46feef1233628398da5b9f11d378f3a19f480884f9181153fe97c9f12c66ab8de7d37362aa2fcd3523dfbc240e30beba397853e4780dc1d128c47a52cebf70a0e49f75c434bedb23cd383fb5260e608f6c171c6e21dff46f8943c4b306f20fd5f3494e1c80cb8898f6337a06de14a9af7db09017eb33a9df7024ec8bf70f0558dc8fcfd7ec128f205f81fe8c457b184fdb60212ff6e76e1423bf5e5d128f439c1792f131b4d47e4487ebd6a6487ba13d2bb242ec87caf915da627d8d7cfd8a7818221fab89ad10f313fab1a301fc6742d723ba9ecbf11b3ae110f978696ac6fa5a5d1f81678ac7586f84ea7e9bda5b82a311fcdffa86d80ae1ff71bf2bf481fd16463c46ffaa13620bfa592e35e3fc4143eca0bebe2476619f65ab19f900f4e92a79fc8ed8c6f529f4e989fe21be599ab11fa8ae7b90677aac19ebc51e1c51bc6307c454ff02fa67425fd81f3a22b6507fb4560cfdcd27c436ae2fd4fd0ed61713551f833ea68d66bc8f86bc2c72c0b1f4bf22fd1ae2f96c424ceb95994d4cf517bb9ab1df1328867cb327cdd84f3e2576a9fe4e33be5f8f11731a1f18af3c1ac3ff25181fbe6aafb134e3bcf28a98eacf6dcd88dfad62b247a719fe7e49ec51fdbb9a313e4f897dea0f5d8f9c08eb73f8b340c99366c4d47e7aa619f2ae89a9bdd4d58ce73d62062e1e1543dec8d58c7c618bd8873c5d4d1ca0bf89aa2f88f0fd5c3e58cc377c1f7a4aece27a24f77fc34dbcc1fbd92d6292276f35c31f6e1373bade6bc6f7b3ec138734deee14a3bd909e17e311fac47c8c74fd1631d5575d69c6fb9621b14fdc1307e06e873882befc041cd9887fc113b1037f9acbf9106da9faea5a337e0fc221a6fab39166f8df4c31fa377d20a6fec6a76051b0be9c12933cfebd62c447df25f6707f2afd9fc87ea8bdea5a33fcf58098d6b7dd057853647f39b1837c227088bd08fb23723e4543d15fc47f8798ea9fed10537e50cd8823f02a510c790bba3fda423c5e5e2a8e703eb1d58cf5cc39f100f24cb68987b8bfa834e33ccd113103c7e8ef48c5ffd22026f9a68166c833538cf6f30958c93b5b6bc6fa60a918f275cfc423b2e73eb10b7fb12279947c2de419abf6db73cdd85fedc1aafdd4d68c7c8511d37e58bbad18f2ac3ccdd89f7289495ffd0df198eebfd58ccf474c893df277604bb48fcf5333626a3f5b130f71bdc915a3bdb5a919fe2e251ee1fe95a318d74d83d8c2f3be474cfeaec2fcb0557bd503f108fb6feb2d621bf525679af1fe5dc667e1bde9fef980788cf56b63135bc807b256319eef2a62071c2e88398ddf67623fc2f94b557f00f94bcc7f57d48ffd8309b12852de4bcd58cfdbc41cf3d7dfd58cf176a019bf2fb726a6f6a7a85f780fec974d07c4d4feea9cd8c6fdc923b1034ef7885de2a166f817f5bc47cf9f68c6e7fb213f53f7678fc474bdbed38ccf873f11335c4f4e35cbebdc21f6697cec69c6fad8d48c7c6e451ce0f902cf73d17f9c370989693f713924a6f6fa3d620e4e8e35637ea03e3f72317ee239315d5f1b9ae57cb96a897d5cf7af8803c81b2c34e3bcd5843804c7f00fc1e60e79fd8198fa17ad34237f7d61ac8f52e290f479a819fb7f7bc411aecf305ec4ddd8df280f897decafc501b1aa3f26a6fafc5c33e4ed35e33c5aa659ce8f28228ee8f94c33ce8f41ff423a9a9f03e200f2643362aaaf2e8823ec4754e79ab1bf186bc6fbe047cdf8bd2a4331d6f7cd4ab31c7fdc520cf9d8a1e608f6360d9399dcf4cdc00ccdc88ccd4496d89c9aa999fda3929b33b310f5fdb3a77f554ab392ff5f7f7bd7dc6cccf6c35f17e6d25c996bb3337b73626e53d9a1b22bca9e28fbba1c887248e54896632a27544e4539932595e5dcbc302fcd2badc56bf3c6bc35ef7eaf6fef2c722fa47da09a12f3d17cfa871a7b36b7cc8139fc37d92313728ee4ff8fbfbdcb326dd3f9302a5cd3334c736d180633b8b6046cf1d61abf678bd357b6480d5f9640b411aa916d44462c46c66f6ae3ad458cc4981aa9b2ad91d148fcc362e486981f46f16fb387981b46295bfa563ea336e64623b4f5f6ef77466b2c8ca5b132d64627f4fed9cc786d8bc34f6d71f2de16ca1a62de4dc478098dde98684d6e1b3bc6ee3fb2c89eb1af668871601c1a47ff405bc21ec6f1bf717e6c74bd6b9cc8ff3f35deebfb6d3937cec55c7dfff48571695c099b5c1b3742c71f6df1f9ccf83d5b6ccab968f7d6b833eeb5ff5f1b0fc6a3f15b1ee7b5458c67634bcf90c41818f93fd0d6c4181aa37f5bfc786711d332bef75b0bc332ecf7d146e8c6113a720dcf38167afc9b88a1bc94ff620b14831b7366328374993266168cffa94598cf02650f168a4435fe635d1db2844dd93fcd06446119cbd9ec772dc28a0f3ee97d7d25ab8cf7e3e38cd56c6eb8ac11b17df49711e3a32d4e4429cd116bd9822db53e57226a9d1adf67221f2db25636153574acff636d4ed836db61bfe92f3f3cbdc7f6d9013b94e5881dbfb976f2b94544941eb1d36f6d57b23376feeeaf6376212c12b14b9103cd5fc58b7f12313ed84215336757ec9a7c4e2cec7f63b6bfe3b7de58e456f93d76c7ee45bcfb338dc6ec813d0a8ffce7b61072b267b645d65045fb7f3664a32f2c9209fddc7f6b915d3666d6db7bd888d9e683f0240e73455678fc771143db425b43cc3b51441e17328f72e0d88cb9080b9cfd994538573384fbe69fce903bbe79a11bfda93578cc1376c8a7efac210b4ff8c66f966cf251cfc8b536b1fd57f9a0902b3592374f9f19962946af58b2673c17fafebb88f1c116422251842e9ef98c175aa725afc428ffe5aae40b8bd4ece3caeafb72c1e7fc8f3301de7c6689375669f9e293276b5a8f647c2946f9f7b324e12bbe7ef3978277bc171649f9846f0badfe55c478638d4a95cdf68cc83a8fd90ddf51ab12762362cbb73ef62b8bb03bbefb8b1ce67d39e77bc62f3cfa076becf3834f2c20cabbbf7c965fd42f33c328f9b7393a9bf0637ef23adf12f1b5e0a7d22267fc5ce8f16f23c6075b884c4b147e64dcf00b7ea95625bce057fcfa9f5884fbbc7bd5a39cdff05b7ec7efbf2c0ffc913ff1e74faf6d7eda7bc847efdb15f6187fb086c56dee7cb048f289dcaf2c62966255f1ddf8191a3bdc7debdbb8e79b4664c642d94cd8f3f4ef22c66b5b286bc8f2c85a3e13ab12edb77c2ef29e5ff8ad4f2d52abdd20dff7835ff995df2b7ef8d62a7ef4e18ed84ffca99f8a7f65fcd0cf5f5dfb98a1d42f11cb9f9917e6c5773b047ee197e69beb7e25d688c222ecd2af458c39fbbb88f17666c016c6233f127324e7813f577ecb6ffcd6e0fe675ef87b8bc4fe12bb13c21eab9fb187d4f8fac5267cdfeff4df7b6e89ff9df8dbfe8ebf2bfeb5e7effb072f33e5f339f2268738f40fc528ffba97e7fe11db1699b2fe8b91f8c7628598fa27fea97f2674ff9711e3ad2d608d4d3173311aced59ea368efc298ff6a77e9a34598e15f62f7e4a7e687d6edc1c719e2e7fe9ef8df2bffdabfe1b6bfebdffa77febdfff0eaa94fe388f16afd6b3cf19c6f7fbd2ef51ffd27ffd9781de546fe963fd8e4bffed0af84eeff32627cb485b0c6dc9c1b817161def823e5b7fc31ef7eb572ff6811df32a4cff2ed9fb587d4bf433a72f55fbcc0e44eb0395b292678106c8e64bc8e24bcf954ee371611736ec1ae8ccfe6125a9b997d101bb7affe9606c9c6227e134ccd50e8faaf23c627b690c53fe35d90eafdad079f7f9f197e669120c3ae43a03d79300b8aa00caa7f54ea601ee81c3790b616ab41c58b60c9ed6015ac832ee88349b01decbcb647b01b7cbee27c6711519eb961de7ed54bbf08f68383577f390c0e99b3c9b6fcb931179afeeb88f1628b176b083de6466e16c1d14b24098ecdc9f739e9078b6ca2887c820db45e4e82d3bf2a67c1b9aeeb42d8fa52d355701ddc04b7c15d701f3c048fc1939fbdb2c773b0f585dcf5878c77334be6fe573b62a360100c5f2289711a8cfc81191b6930368e8575ff3e627cb0058a712b4683a5de396d5640c6c59f5984dd0536766e03476bc6fd4b8b78a1a9ea0a8d90698f95853cf4c36073582b8cc3247cb3720fd3f06bb93f5a24133abafbea8da7310ef370f62a472ecd66e3b58c342cc4dc9aff48c478670b618d6453786e30bde31887a51801dfae9fde5bc4988494b9eb5dbfc3b0fe3b8b84f350fbadb07da5f345b80c57e13aecc23e9c84dbafed11ec86dfed01d5420beffec697c631bffae23d4010ee84bb2fcfb051b867ae0de1dfe5fe6ffe1311e3a32d8cdb4d1199b6c5988a24e1be68cffdb25f9f58243c080f71e5253f0d8f7ece226f66c17178129e8667e17978115ebeb972f545fcf8c622a29c87d75faddff97978c3b71585b7e11d2c12de870f46fe1311e38d356e75c9591b3e1a9e7eefb4660bf3db15c97b8bf05abda7fa775bc44fc3a7f039dc0a07e1301c6dd624babd5fefe07c6a11ce78c0bbcfdf2a865668878e5a2fb33474d97c6311639b2dfcb35fdbe2d711e3edccd8d842964ed45e849edfa8d81e99e6ee77ef49de5b2432ccfdff9045f63767a9e489a6307ab5828f7ee33d599444d3288db2288f66e2bf45443bc1e628aa3e9d3d995146753467f4ae992f991d3572d5be14f9682bd69b3f10315ecf0c58c3e8cc67ff8c9551ab637b142dc47cfc7d8bc4d132bcfdf75a245a45eb48d41df5d124da8e76a2dd68eff7e747b41f1d449f78c0e8283ade8c7d7e1e9d7cb606334ea3d3e84c9d9430cea2735824ba882e8d0b916dfd40c4786b8b8d3550a2abe89af72adb8a6efcb32f73c20f166177d1ad7acff56fb4c85d741f3d448fd153f41c6d4583976b7cccf7bf9615ef52be2e1b9b187934fcec8d091bb2281ae9bd17371a4796e16ece5245d7c68dd0fd0f448c8fb6d8cc10e1b5361f5c54ebf638b28d9befc6dc3b8b1891a3aefcfbbcd6e6a46b2c5c78cc621efbb1deab89c3f8cb375e71fceb7729d111db33c671124f3f66fcec344e63114da86f0be32ece8d2bb13eb88c67dce3473f11313eda0285e7e14358aa9d94b8e0db7fe0b5aed895ba12a65a53e5df5924aee2fab5e6e279dcc46dbc8897f12a5ec75ddceb2b1fde16923da278fb57f690cfef18b55fc4bbe6c1c73ac2c778cfa73c52dcc56011f321de67bdd0fb0f448ccfacc15a916b59c64e7ca0f2dff89007dfedc8bfb5487ca4725fe123f47a243efe4b8b9cc4a7ef3477169fc717f1657c155fc737af66c9a7fb20c15e1cbe7bfe2ebe8f1fe2c7f8297e16ffd56fe8e3cdbbf9b378f892e7be9a257d3c8a7594123ab2c822b6b83bff9988f1de16ac3537e58277b1a32ce29ff0f72731beb388fbf26636f6543f3701296109a7e22741127eadff244ae2f844dd1dce932499fafd5b8d2669922579324b8aa44caa577faf930f9952d224af56957e9f2c9265b24ad64997f4d4e2445f5dcbf7bc7db2fd49ceff9cec24bbea649fb1c3569bfd78e6247be640acac7f24627cb0852cc6053f4ff6d5a9147e991cfcbed74a0e7d9dcd2747af34759c9ce8729a9c25e75fd944e8e922b914f7bcdc7ffcd1bb2457c9757293dc2677c97df2903cbeb9f6943cbf96f075344fb6924132fcd8eacb1df2893c197dcc818d93204ec6ecb545c41cf107896516c6edcf440c58c37c55123bb18545ae1287761b63f3caf47e3fd74adcd7e7183f3f212235e34dcdcf2d323592c5afbcfd944df9d49f06d3701a4de369327d3f87b6a67a7f2a78f52e31aea7d9e7adbeb5887936cd3f9cd1caccfde96c5a9888ed77666f5e4b8b34d3d23f141afe9188c1ded922b1fdcaaf84d70aa615ad1163b132e9bf7b8ff8d622d3376be1e9fc4b9d36d3f60b8b2ca6cb6fadb19aaea7ddb49f4ea6dbd39de9ee746fba3f3d981ebe9d27c2e624c754cfd4e9f1f4cb3de8b716999e4ecfa6e7d38b777dbd9d5e4eaf700a4d68a40ff7c922d7229b79fea188f1ce16281b8b24963f804598e3b3efde23beb3c88df9666c4de79fcf13a19ddb2f2c7237bdffc61e0fd3c7e9d3f479ba351d4c87d3d1743cb5a6f6d499ba532f35e337ef2c93a7cd0ae4c592c9f2ebd8f56e8e64e6e0fd19adcd5e163f490d53e6c54661ec288ba46c63919f8918b0c68b2dfc4aac3e2f42cb3f4cf98b458cbbefcea9bfb548ea9bc7efef4883e4e9272c12f7699846699c26e9344dd32ccdd3595aa4655aa5753a4f9bb44d17e99bf9c5a72f31245d25d1ef5bc478f48fde9ed1da44fc749d76b4461c2a8bf09db417b9cff3cf448cd7d6d8d8c2b8d89ccae0b9b0c8843ebbf0a716d9fefc94681ca73be94eb4ff671649775f3495eea5fbe9417a981ea5c7e9497a9a9ea5e7e9457a995ea5d7e94d7a9bdea5f7e943fa987eb0fea6f87dfafcb53d3e5a84ed867be956f8269736ce0c5b78659935b01369115759c43ffb9988f1d11a9f5be4f7bd563a30bf799bf2a71679658f613a4ac7a995daa993baa9979e6e5494b18c677e1664611665719664d32ccdb22ccf66ef9fcf8aecdb55ea87397264f659a54ea2d2df9eb25a642e882e81cf601123da5884b53f1331dedb6253c4faf0865f65f3575e6be7bbb7886f2d9235e617abe6bfb148d6668b6c99add2e36c9d75599f4db2ed6c27dbcdf6b2fdec203bcc8eb2e3ec243bcdceb2f3ec22bbccaededb24bbce6efec42238a3f57e9d98dd2687d853caeee4c9dfd716f99188f1de169b22567821bbcaeea545e28d45be3f53fdce220f9fef65ff8d45b2c7ec297bceb6b241364cbd6c948d332bb3332773336f134a73968b699d07799847799c27f9344ff3ec6d1d79fe9d3d3eb3885905837cf6762ce6455e467297882fe3042bc48d45d895b0c88f448cf7b640d958647a2db3df5866bfdeef5b24afbe3b81fd4f2c1207799dcff3261be46dbec897f92a5fe75ddee7937c3bdfc977f3bd7c3f3fc80ff3a3fc383fc94ff3b3fc3cbfc82ff3ab973a92d35f9dbdf86811b69b5fe737e61bbf95dfe6a521471c1be577bcdcecc61b517e2f72adf66722c67b5b6c8af0595ef898dfcb35bbb0887ff2b277f81b1679f8ee7cfb3fb148fe983fe5cfe971be950ff2613ecac7b9950d733b3d990e732777736f66ce8c199bf1993f0b66e12c9ac5b364369da5333d4f66f957bbcfb3d9ac48d8f44edfa92dc04e665510bffdf4447ecb3a78323699d5b088dfcce6ec2ab17f26627cb4c6a6f885e9cd1ab248c22e3f7e32f26b8bcc5ae347bd56dccf16b3e56c350d66eb5937eb6793d9b6b48737dbc9b767bbb3bdd9feec6076383b9a1dcf4e66a7b3b3d9f9ec627639bb9a5dcf6eb49e6f3fcf7c853dee36fbfc899e23b357a7d3f85568b3777324766111e374f6008b3067f6c885457e2662bcb785196e8a31372cff42ee348afff253ffdb73a66f2d621c7c37a3fedc22b3a7d9f36c6b36c807b3e16c341be7939935b3674edecfdc99576c3e62cd0a5ef84550844554c445524c8bb4c88abc981585da5b29cacfe37a1214af7629e59daf77f02e8a79fce68de48b45ccdda2311f609194b32ba1e71f8918ef6d81c24abf2e5a6591622166e46f5b84dd15cb9fb388df17ab625d74d9bae88b49b12de68995dc143bc56eb157ec1707c56171541c1727c56971569c1717c56571555c1737c56d7157dc170f05edac144fc527ab91e2397eb7f3e2bf3d19745e6c1503feaa3fafe648590c37717d639162b4b1c8cf448cf7b630e5ef56186d746998b4ab95f8e577d9d3c7f7ecc537efb9ffd422715058855d38d341e1165e6996466e97ace4a55f06655846655c26e5b44ccbaccccb59599465599575392f9bb22d17e5b2a493f9e5fab396caae7cb33f993cf9fe1b79c7e5e4e5cdba2c4eec921fcbfd63238245ca6d7e2534fd2311e3bd2d50cc41b953eeaa7788e59ef947671aa379f6e5fbad3fb548d696fbe54179581e95c7e549792aed71569e9717e5659a8a817a555e9737e56d7957de970fe563f9543e975be5a01c96a3725c5a259d052f9d4f2de296fa0d0e9f7e7cafc286812d56bc2f16b9cbeaca840f376e2bc3c0f7bf3c54ecc5223f6d0bee4557d1150f2aaebfdb24aefcef3fbff6c122675fdfffa716a9822aaca22aae926a2a9619417a52a55556e5b375ea55b3aaa8caaaaaeadc2926d5bc6aaab65a54cb6a55adabaeeaab49b55ded503dbbbfb248f5c9de8f7154edc799f1b2033cac0eaa43bc69874536738497d5917f685cfc4cc4786d0b5823ba627df8382dd5792dbe531db36fbf0fe3bd45be5bb5ffb1454eaad3eaac3aaf2eaacbeaaabaae6eaadbeaaeba4fdd995d3d548fd553f55c6d55836a588daa71655576e5546ee5d5666dd4ace6b5ffbd456abd575c879fc9cbbb78efd55b6a5647d98381cff33dd7f1e6d4efe62c4a9df0c0bcf89988f1d6167eb129227bedeb976f9bb9e2ddf7df33f0de2275ea7ff969e43fb5489dd5793dab8bbaacabbaae1eea79dd8858d2ceec7c52b7f5a25ed6ab7a5d77755f4feaed7aa7deadf7eafdfaa03eac8feae3faa43efd3b8b18c7f559addf2eb0229ad71738856adcd49772fd1c97bbf5d58b457ec64b295b9045dafababe7939f760fce253d01f2c72cbbfcc7fffd82277f57dfd503fd64ff573bea8b7eac174989ee4f66ca71ed6a37a5c5bb55d3bb55b7b9b57aa7336e7737f1eccc379348fe7c97c3aa7d330f34fdf1cfeda226638cfe7fafd29db9d17f312ef7f58599fbd58c42ccc8b9fb2c55b6bf805ebcd22bae4a68aebc5e2936ffcfad622ec6efe6373240ee6f57c5e17f366dece17e9d17c395fe58bf93ab5e7ddbc9f4fe6dbf39df9ee7c6fbe3f3f981f0a3b1c89ff1ecf4fe6a7f3b3f9f9fc627ef9bb16997f3a8afcb3389b5feb93e8fbf39bf92ded6d17f33b58647e3f7f300722bafc40c4786f8b4d31e6fe617d15ea6f64f2b70cff2bfd7e6e1133993f7ef5cd6e7fbe429c3fcd9fe75bf3c17c5837f3d17c5c1e656296d45b736b6e4f83b93377e75e633646c31adef84dd0844dd4c44dd24c9bb4c91a7ac7decc7e6591e6f35570de944da5bf6fe73c1a4daff06925b19e3f80459a3aba365a6591bf8b18ef6db129ac0c1ff54ebc18efcd9cdef4ff81459a467fe7c85f5ba4699b45b36c56cdbae9aaa2e99b495d177db33deb9b9d66b7d96bf69b83e6b0396a8e9b93e6b4396bce9b8be6b2b96aae9b9be656edc93777bfb4c8e79fedabc2dde641bdb732f2eca1a1d11656cdd3c61e46da3c375bb0c8df470c650b650d595a9f350315d79b2763e7fdb7eefc8645865f7d6bd09f5b245a35a366dc588ddd388ddb789bc34b6269cc5bbf0d9add366ca3366e9376daa66dd68a90df166dd9566dddcedba6d5a7b47e6d91f6f3b31da7edb25da94f62722f76dbf5e6bb628ca3b63326b048db4797621cff48c478670b3943cc822dda898aebfcf4ed4edbef5984855feda4fc93bddf76bbdd6977ebc776afdd6f0fdac3f6a83d6e4fdad3f6ac3d9f8eda8bf6b2bd6aafdb9bf6b6bd13b6b86f1fdac7f6a97d6e5f7d93d06f58e4f3ddd4d3c868872d7d8a9e5d71bf1d6fde98f0656bf11d6991a8b5d982953f1331deda02c53f2c77a20b15455ae7eb4f147f6d1119493ef502ffec8d55ebb6dec25c180bb6e00b7f112cc299b5881671f5301d2d92c574912eb245be982d8a45b9a816f562be68166d7df72716592c3efd76b6b45d4eafd437dd144be36021c71a1b2d56722d12f39dc5daaf8df94f448cf7b6e0db7cdb6893037d0a2531d245677e73f6ff6b8b8875d4a796fca76f7517fd62b2d85eec2c76177bede162bf3a5f1c2c0e17478be3c5c9e27471b6385f5c2c2e17578bebc5cde27671b7b86fdf9cbbfe0d8b3c189fed159d458688e5c81d878bc7c5d3429e7be08bc5162ce20f16033e133afd8988a1adb1b1058a296a5f0c5fa248f8f0fd27debeb2487d1b4f7fd222d96c315a8c17d6c25e380b77e12dcdd2581ad5c5922df9d25f06cb70192de365b29c2ed365b6cc97efdeb2ffda22cbe2d36ce4954558b12c979529d72d86df2e65a695f88365ed33bff88988f1de1a9be21ffaa7865e8b2c459cff555cffe2fbb5e265137e724afdc522cbf6abb3215363f9e929d3e572b95aae97ddb25f4e96dbcb9de5ee726fb9bf3c581e8ad68e96c7cb93e5e9f26c79bebc585e7e78f6eab396927e76abefb8fe74dd952e6f94458cd3e5edf20edffb60244d098b98ebe5bde9298bfc5dc4786b0ba3dd94e460f9f0b2c7b87c34f37ffa8d67cb27a3fb78ef527f57437cb7dcfadc22cbc152e748e19bef6b5a0e97a3e578692deda5b37497deca5c192b66262bbef257c12a5c45ab78957c66cdd5f4b3f723ab74a5dffbaef2cf3e9f609ea7fe4a7d8a7d128d56057dde3d8c47588db0d5aae44674f5f711e3bd2d44467d6816e1c3aa523e8b19abfafbef277e6f91d57cd5ac5a3cbd5aac3ec9b7983edde6f7ab9518b9d56afda674cbab957e67b19a98d9ac7cabdbb89f3dadb6573babddd5de6a7f75b03a5c1dad8e5727abd3d5d9eafc9d1d2ef4bf2e5757abeb69f6d292fcf7cd4acf91d5ddeab35ca4ca9ad5039d7e785e3d2aebf060f5048b98abd53313bafffb88f1da1ae1218ac8ee2e565bea4d552c78f5ed1bf64f2c325ce96fb9598d3f9e377dfbc9815f9595b5f984261b7c71d55e392b77e5adcdb5f1d9f535134b87df6c69ed273beb4fbe59c008d6e13ac27751f3ed759c8ca7a79bd5c83a31afd48a7dfec083e8eaef23c6cbcc50c52ccc7e3d55e7e6cc789d8ac5d86f7c4ff86b8bacb375ae3f2d77c43fe9e3cbc9e85f6a69b62e605376fcfa1339bff974b916f37b5dffe6dd73235b371fcfd21a17c96153e1bdeeba5d2dd68bcda75e591a0dfd06ebc3f5b2d9328b9fb6058a7fc816eb957abb6e4cd66b73efbbcf8d7c6a916eddb350edc04c2f3fdb81f9f5e733494b93bc546bfff5767410ecfede73e2c99df56e38dbec08aef7d6fbbfbe7f569ad5faa0a93e7ebfd6665eac0fa5a544eebb5ad0cefc787d84b75546b43e369839f8695b98834de1ddfac4bc563e8b9f0a0bfdd6375a2b8bac4fd767ebf3f5457da66609eb3eff942f8fc3ab5fe8f4727de59f2d9fd8f6ebcc627dfdcbe76ed6b79bcf57adeff81ef69f844dbe9d27fe6a7d8d4f4fb5abf7df09bcd94fe4fe5ac697f03619af1fd4a987a8a6dcb7593ffab518cd7f1d31deda42da23583f5154df641077eb6723ffbd6fe1c7efc1acb7a44506eb61316477649130d9feea9b37d7a3f5786df1fbb5bd76d6eedaeb4c598cb525fe2e35e33fce8b8ebdffcc6c1c753cc8a7476ff5daf9b1d7059d7ec7d145c5e0e51b67d67b5d1ce45dc2f6a91551c4bfa75dba567bf0e7c2227ab7e4a57459f3d4e144e05e37eb0a9c8b4fecf046ad46bad2b0c4aae107670695821bf5159d76d8f8acfdfadabcfd9def285716e9aaaeeee65dd3b562bd74a266c9f4c678fcd5f3dd62f9147dfa76829dd7e9a739e966f4ee47fbddb25b85591776ef3ee7e12f92dde4db6f0e91e5f56e84dc2d31dfb5651c15e3ae33642c3382fa62a5be63bee87ac4f56ed26d9b9ed0f94fda42dac33f0c1feaa9fee4e1e65b05e6bff815888f16d9e976bbbd6ebf3bf08ff52f991c7487bfac21ed8e8ac1a7eff2cfb3a63bfe5d395e15b718ac7fb9d7f0c6224759951aef7343961683ca84e765bd6fb5abcde7e0d84977d250ee1be7dd293758f993b6d814e33839983fd0fea28ceadd99e1ffee2f879045cebb8beeb2bbeaaebb9bee5648ac569937bffed5a4ee6ef568beffccdfa6dc854ed3987ffe8b1941771ffcfad74b5e5be4703a9bdfbeff958576d40ec52a5deed0adef568bee417ac2fbee518eddcdbb91babee2572f16f96711e3ad3536f6e057eba766f032437c831bbfdecf7a6d11bfef9ebae76eab1b74c36ed48d3b4bcd92fab6fbf644e4a6f0a869c42cf924d33682a6e99c5f3dffbe8851ecfee11c39e8bceee8c3d811b317ab747ecdc48ab937e55f4f7b03bd43ee6b1cffd4ccd8d86253c4aac15b3dab6fa691dfdfb4e047bfdecf7a6b91ab76bdd5d5c29df2deef833eec23354bfaf857df94cf4efba49f9a9f9c3d60bc7be8d35fef3fbfb3e3519f750fbffa9ee2b716e97361917773c4e8b207bcc5ddcc9666489f5368e38c7c72d4cfcc1bb3f8095b286b488b9cfbbc2f547e2466c848c4aad1effeae98b208fc565ff6555ff7f3bee9db7ed12fb19fd2af7ef50db5fca85ff79dff4916c0bdecc1f864edff7d69c7c9987f73fe5896d767e60efbbcefdfc711914359b44a2fd3ae9fe01b5a4556aaa2a4db6f1b5678f873b6d814ffd0b8eb77f4efbc8919d2ef1ab7bf3f436091cd3e55bfb7deeaf74574bfea0ffac3fea83fee4ffad3feac3fef2fbe3fcbbdc98efacbeaf0b3f7956c775acc8b3ffd8d98fe6a7af5f1172ede95d7bf8e72d4a7c222ef32edfeda3810abf44d3c0d2b3395dfe4c68ac0d6bf7a23f77d5f5be4cf23c6fbb2f90ebc72879b2fbf5f18de27077f32435e2c2266c9537f63b26ededf0a9bdcf5f7dd4dffd03ff64ffd73bf65fadf977ed00ffbd1a757c6bdd5dbbf7afedd334eeff6def7f74ccc57ff36266cc25fff45fed59f049350fe2b9ac49384fe3ae5f49f493ac926f964362944995129a954546a2aea5ff337a5f950dac962b29cac741beb4937e9ffacf7b0c8c62657ed6432d99eec8875c9555f4f76277b93fdc9413f9f1cca72f43fe53f535e2cb2f15c1b9b8879b22be209ef8693e3c989982d87c236a7ff53fe534559e4c526fd4dbf2f623ceb06fdede46c722e627d2db2e2ff29ffa1f26211d8e4aaed9e44267cd1d5627d7229ec325f9fade69b62f2ff29ff89f2da22b049b4eaf7ba7361956761979dae5e9fae4f4df63fe53f55de5ae4c52a9bb922d6285557adb74ce37fca7faefcf7fff77ffed7ff0f3d2668ef</data>
+ </image>
+ <image name="image2">
+ <data format="XPM.GZ" length="3000">789cedd64b53da601886e13dbf2263764ee735212187e97481e7b3e009b5d30509c423d603a8d8e97feff7dc684747375d7503f7ea7a26f3114185b959efa8b5e5cdced5ee87dde179e99567dd3b6fb6371a0cc6df7f7cfb559b09032fcdbd24f1ea335f6a33eda1577a7e10e47914c956e1f0af1f7194a75103f7709ec75186cfe430cb7a5185ef7099157188afe47a9945718ee7e528c8c2b8c0d772dc48d3c6e47c5f4e78e0539c2adcc795c2bb725a287c8e2b85efe52c507805270a6fe242e105dc577820e7b1c27bb8abf0112e157e92bbb1c23f715fe163b94814dec2dc005ec5a5c2b15c060aefe350e1135c57b88153850f300762deefb2a7f036ee2bbc26f76285039c283cc6a9c23bb8507811f304b88b79e012f715bec095c237723f50781dd7151ee148e167dc50b8857903f112ce154e306f082e70a1f025e605c1b7981bc68798077ec095c24db90a154e715de1651c291ce258e10dcc2f38ce70a6701be70ad77157e10e2e14ce71a9708479c165df303f00e6efafe231f9fff036f3ad6bc5749feed37dba4ff7ffb8971f77eb59ffd3bdb2d37fbafeccceedc22e3fec5736f874bfb69f7663b7ef77bbb37b1bdac81edeeef6e8eee5c9c6f66ccd77fbbc2db8ab176dc9965f7777edbcadd8aaadd9badddac66477e79edaa66dd9b6ed58cb9ad6e673edda766dcff6edc09d3db243dbb0cee4fb991ddb895b037787858556b7c9e76e6c0d77c2d8ad89a59659eedbe4fb917bb61d7742c1daf1ed655f74f7d072e786afabef4fbe5fb83b6bba67abeb04ad2ffbb2dbdad6b1e8757dd9dd756f37f6df5f6b7f0026022757</data>
+ </image>
+ <image name="image3">
+ <data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>clearInfo</sender>
+ <signal>clicked()</signal>
+ <receiver>torkview_base</receiver>
+ <slot>clearInfo_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>clearTorTraffic</sender>
+ <signal>clicked()</signal>
+ <receiver>torkview_base</receiver>
+ <slot>clearTorTraffic_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>clearNonTorTraffic</sender>
+ <signal>clicked()</signal>
+ <receiver>torkview_base</receiver>
+ <slot>clearNonTorTraffic_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>NonTorTrafficMaxEntries</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>NonTorTrafficMaxEntries_valueChanged(int)</slot>
+ </connection>
+ <connection>
+ <sender>streamList</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>streamList_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>circuitList</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>circuitList_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>serverList</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>serverList_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>streamList</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>stopDisplayingBubble(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>circuitList</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>stopDisplayingBubble(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>serverList</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>stopDisplayingBubble(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_LogNonTorTraffic</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>kcfg_LogNonTorTraffic_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_LogTorTraffic</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>kcfg_LogTorTraffic_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>ShowHostNames</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>ShowHostNames_toggled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>infoList</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>infoList_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>TorTraffic</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>TorTraffic_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>NonTorTraffic</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>torkview_base</receiver>
+ <slot>NonTorTraffic_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">torkview_base.ui.h</include>
+</includes>
+<signals>
+ <signal>closeStream(const QString &amp;)</signal>
+ <signal>closeCircuit(const QString &amp;)</signal>
+ <signal>closeAllCircuits( QListView* &amp;)</signal>
+ <signal>copyOldConfig( )</signal>
+ <signal>attachStreams(bool)</signal>
+ <signal>newIdentity()</signal>
+ <signal>konqWithTor()</signal>
+ <signal>networkList()</signal>
+ <signal>hiddenServices()</signal>
+ <signal>toggleTorTraffic(bool)</signal>
+ <signal>toggleNonTorTraffic(bool)</signal>
+ <signal>updateExcludeNodes()</signal>
+ <signal>updateEntryNodes()</signal>
+ <signal>updateExitNodes()</signal>
+ <signal>clearNodes()</signal>
+ <signal>updateStrictExitNodes(bool)</signal>
+ <signal>safeLogging(bool)</signal>
+ <signal>resolveAddress(const QString &amp;)</signal>
+</signals>
+<slots>
+ <slot>stopDisplayingBubble( QListViewItem *, const QPoint &amp;, int )</slot>
+ <slot>streamList_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotAttachStreams()</slot>
+ <slot>slotCloseStream()</slot>
+ <slot>circuitList_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotCloseCircuit()</slot>
+ <slot>serverList_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotClearNodes()</slot>
+ <slot>slotAddToFamily()</slot>
+ <slot>slotAddPermExcludeCountry()</slot>
+ <slot>slotAddPermExcludeNodes()</slot>
+ <slot>slotAddSessionExcludeCountry()</slot>
+ <slot>slotAddSessionExcludeNodes()</slot>
+ <slot>slotAddPermExitNodes()</slot>
+ <slot>slotAddPermStrictExitNodes()</slot>
+ <slot>slotAddSessionExitNodes()</slot>
+ <slot>slotAddSessionStrictExitNodes()</slot>
+ <slot>slotAddPermEntryNodes()</slot>
+ <slot>slotAddSessionEntryNodes()</slot>
+ <slot>addExcludeNodes( bool perm, QStringList ccs )</slot>
+ <slot>clearInfo_clicked()</slot>
+ <slot>clearTorTraffic_clicked()</slot>
+ <slot>clearNonTorTraffic_clicked()</slot>
+ <slot>NonTorTrafficMaxEntries_valueChanged( int newval )</slot>
+ <slot>useNewIdentity_clicked( int, int )</slot>
+ <slot>useKonqWithTor_clicked( int, int )</slot>
+ <slot>viewNetworkList_clicked( int, int )</slot>
+ <slot>viewHiddenServices_clicked( int, int )</slot>
+ <slot>kcfg_LogNonTorTraffic_toggled( bool state )</slot>
+ <slot>kcfg_LogTorTraffic_toggled( bool state )</slot>
+ <slot>ShowHostNames_toggled( bool safe )</slot>
+ <slot>copyLogLines( )</slot>
+ <slot>selectAllLogLines( )</slot>
+ <slot>infoList_contextMenuRequested( QListViewItem *, const QPoint &amp;, int )</slot>
+ <slot>TorTraffic_contextMenuRequested( QListViewItem *, const QPoint &amp;, int )</slot>
+ <slot>queryHostName( )</slot>
+ <slot>resolvedAddress( const QString &amp; )</slot>
+ <slot>NonTorTraffic_contextMenuRequested( QListViewItem *, const QPoint &amp;, int )</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+ <function access="private" specifier="non virtual" returnType="QStringList">selectByCountry()</function>
+ <function access="private" specifier="non virtual">addEntryNodes( bool perm )</function>
+ <function access="private" specifier="non virtual">addExitNodes( bool perm, bool strict )</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kwidgetlistbox.h</includehint>
+ <includehint>dndlistview.h</includehint>
+ <includehint>dndlistview.h</includehint>
+ <includehint>dndlistview.h</includehint>
+ <includehint>dndlistview.h</includehint>
+</includehints>
+</UI>
diff --git a/src/torkview_base.ui.h b/src/torkview_base.ui.h
new file mode 100644
index 0000000..b1bca7b
--- /dev/null
+++ b/src/torkview_base.ui.h
@@ -0,0 +1,643 @@
+/***************************************************************************
+ * $Id: torkview_base.ui.h,v 1.48 2009/06/20 09:29:15 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <kdebug.h>
+#include <qclipboard.h>
+
+#include <kapplication.h>
+#include <kiconloader.h>
+#include <kstandarddirs.h>
+#include "torkconfig.h"
+#include "tork.h"
+#include "crypto.h"
+
+#ifndef EXTERNAL_GEOIP
+# include "GeoIP-1.4.0/libGeoIP/GeoIP.h"
+#else
+# include <GeoIP.h>
+#endif
+
+bool m_LeaveStreamsUnattached;
+
+typedef QMap<QString, QListViewItem*> ResolveMap;
+ResolveMap resolveMap;
+typedef QMap<QListViewItem*, int > ResolveColMap;
+ResolveColMap resolveColMap;
+
+void torkview_base::init()
+{
+
+ serverFilter->setListView((KListView *)serverList);
+ QValueList<int> tmp;
+ tmp << 1;
+ serverFilter->setSearchColumns(tmp);
+
+ clearButton->setIconSet(SmallIconSet("locationbar_erase"));
+ connect(clearButton, SIGNAL( clicked() ),
+ serverFilter, SLOT(clear()) );
+
+ serverList->addColumn( kapp->iconLoader()->loadIconSet("tork_torsmall",
+ KIcon::Small),"", 24 );
+ serverList->addColumn( "Server" );
+ serverList->addColumn( "FP" );
+ serverList->addColumn( "conditions" );
+ serverList->addColumn( "countrycode" );
+ serverList->addColumn( "ip" );
+
+ serverList->setSelectionMode( QListView::Extended );
+ serverList->setColumnWidthMode(2, QListView::Manual);
+ serverList->hideColumn(2);
+ serverList->setColumnWidthMode(3, QListView::Manual);
+ serverList->hideColumn(3);
+ serverList->setColumnWidthMode(4, QListView::Manual);
+ serverList->hideColumn(4);
+ serverList->setColumnWidthMode(5, QListView::Manual);
+ serverList->hideColumn(5);
+ serverList->header()->setResizeEnabled(FALSE, 1);
+ serverList->setResizeMode( QListView::NoColumn );
+ serverList->setHScrollBarMode(QScrollView::AlwaysOff);
+
+ streamList->addColumn( "ID" );
+ streamList->addColumn( tr2i18n("Source") );
+ streamList->addColumn( tr2i18n("Host/Port") );
+ streamList->addColumn( kapp->iconLoader()->loadIconSet("tork_torsmall", KIcon::Small),"", 24 );
+ streamList->addColumn( tr2i18n("Speed") );
+ streamList->addColumn( tr2i18n("Exit") );
+ streamList->addColumn( tr2i18n("Circuit") );
+
+ streamList->setSelectionMode( QListView::Extended );
+ streamList->setColumnWidthMode(0, QListView::Manual);
+ streamList->hideColumn(0);
+ streamList->header()->setResizeEnabled(FALSE, 0);
+ streamList->setResizeMode( QListView::NoColumn );
+
+
+ circuitList->addColumn( tr2i18n( "ID" ) );
+ circuitList->addColumn( kapp->iconLoader()->loadIconSet("tork_torsmall", KIcon::Small),"", 24 );
+ circuitList->addColumn( tr2i18n( "Path" ) );
+ circuitList->setSelectionMode( QListView::Extended );
+ circuitList->setColumnWidthMode(0, QListView::Manual);
+ circuitList->hideColumn(0);
+ circuitList->header()->setResizeEnabled(FALSE, 0);
+ circuitList->setResizeMode( QListView::LastColumn );
+
+
+ ORList->addColumn( kapp->iconLoader()->loadIconSet("tork_torsmall", KIcon::Small),"", 24 );
+ ORList->addColumn( tr2i18n( "Server" ) );
+ ORList->setSelectionMode( QListView::Extended );
+ ORList->setColumnWidthMode(0, QListView::Manual);
+ ORList->setResizeMode( QListView::LastColumn );
+
+ TorTraffic->setColumnWidthMode(0, QListView::Manual);
+ TorTraffic->hideColumn(0);
+ TorTraffic->header()->setResizeEnabled(FALSE, 0);
+ TorTraffic->setResizeMode( QListView::NoColumn );
+ TorTraffic->setSorting ( 1, true);
+ NonTorTraffic->setSorting ( 0, true);
+
+ m_LeaveStreamsUnattached = false;
+
+ infoList->setColumnWidthMode(1, QListView::Manual);
+ infoList->hideColumn(1);
+ infoList->header()->setResizeEnabled(FALSE, 1);
+ infoList->setSorting ( 0, true);
+
+ kcfg_LogNonTorTraffic->setChecked(TorkConfig::logNonTorTraffic());
+ kcfg_LogTorTraffic->setChecked(TorkConfig::logTorTraffic());
+ kcfg_LogNonTorTraffic_toggled(TorkConfig::logNonTorTraffic());
+ kcfg_LogTorTraffic_toggled(TorkConfig::logTorTraffic());
+
+ NonTorTrafficMaxEntries->setValue(TorkConfig::nonTorTrafficMaxEntries());
+
+}
+
+void torkview_base::stopDisplayingBubble(QListViewItem*,const QPoint&,int)
+{
+ TorkConfig::setDisplayBubble(false);
+}
+
+void torkview_base::streamList_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( streamList );
+
+ menu->clear();
+
+ if (streamList->childCount() > 0)
+ menu->insertItem( "Close Connection", this,SLOT(slotCloseStream()) );
+ if (!m_LeaveStreamsUnattached)
+ menu->insertItem( "Let Me Drag Connections To Circuits Myself", this,SLOT(slotAttachStreams()) );
+ else
+ menu->insertItem( "Attach Connections To Circuits Automatically", this,SLOT(slotAttachStreams()) );
+
+ menu->popup( point );
+
+}
+
+
+void torkview_base::slotAttachStreams( )
+{
+
+ m_LeaveStreamsUnattached = !m_LeaveStreamsUnattached;
+ emit attachStreams(m_LeaveStreamsUnattached);
+}
+void torkview_base::slotCloseStream( )
+{
+ kdDebug() << "deleting entry" << endl;
+
+ QListViewItemIterator it(streamList, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (streamList->isSelected( it.current()))
+ emit closeStream(it.current()->text(0));
+ ++it;
+ }
+
+
+}
+
+void torkview_base::circuitList_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ if (circuitList->childCount() == 0)
+ return;
+
+ QPopupMenu *menu = new QPopupMenu( circuitList );
+
+ menu->clear();
+ menu->insertItem( "Close Circuit", this,SLOT(slotCloseCircuit()) );
+ menu->popup( point );
+
+}
+
+
+void torkview_base::slotCloseCircuit( )
+{
+ kdDebug() << "deleting entry" << endl;
+
+ QListViewItemIterator it(circuitList, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (circuitList->isSelected( it.current()))
+ emit closeCircuit(it.current()->text(0));
+ ++it;
+ }
+
+
+}
+
+void torkview_base::serverList_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ if (serverList->childCount() == 0)
+ return;
+
+ QPopupMenu *menu = new QPopupMenu( serverList );
+ QPopupMenu *m_ThisSession = new KPopupMenu( this );
+ QPopupMenu *m_ThisPerm = new KPopupMenu( this );
+
+ menu->clear();
+ menu->insertItem( i18n("For This Session Only"), m_ThisSession );
+ menu->insertItem( i18n("From Now On"), m_ThisPerm );
+ menu->insertItem( "Add to My Family", this, SLOT(slotAddToFamily()) );
+
+ m_ThisSession->insertItem( i18n("Always Use Server As An Exit"), this,
+ SLOT(slotAddSessionStrictExitNodes()) );
+ m_ThisSession->insertItem( i18n("Try To Use Server As an Exit"), this, SLOT(slotAddSessionExitNodes()) );
+ m_ThisSession->insertItem( i18n("Never Use Server At All"), this, SLOT(slotAddSessionExcludeNodes()) );
+ m_ThisSession->insertItem( i18n("Never Use Country At All"), this, SLOT(slotAddSessionExcludeCountry()) );
+
+ m_ThisPerm->insertItem( i18n("Always Use Server As An Exit"), this, SLOT(slotAddPermStrictExitNodes()) );
+ m_ThisPerm->insertItem( i18n("Try To Use Server As an Exit"), this, SLOT(slotAddPermExitNodes()) );
+ m_ThisPerm->insertItem( i18n("Never Use Server At All"), this, SLOT(slotAddPermExcludeNodes()) );
+ m_ThisPerm->insertItem( i18n("Never Use Country At All"), this, SLOT(slotAddPermExcludeCountry()) );
+
+ menu->insertSeparator();
+ menu->insertItem( "Reset Session Settings", this, SLOT(slotClearNodes()) );
+ menu->popup( point );
+
+}
+
+void torkview_base::slotClearNodes( )
+{
+ emit clearNodes();
+}
+
+void torkview_base::slotAddToFamily( )
+{
+ QStringList currentList;
+ currentList = TorkConfig::myFamily();
+
+ QListViewItemIterator it(serverList, QListViewItemIterator::Selected | QListViewItemIterator::Visible);
+ while ( it.current() ) {
+ if (!TorkConfig::myFamily().contains(QString("%1-%2-%3")
+ .arg((*it)->text(4)).arg((*it)->text(2)).arg((*it)->text(1)))){
+ QStringList existingServers = TorkConfig::myFamily();
+ existingServers.append(QString("%1-%2-%3")
+ .arg((*it)->text(4)).arg((*it)->text(2)).arg((*it)->text(1)));
+ TorkConfig::setMyFamily(existingServers);
+ }
+ ++it;
+ }
+ TorkConfig::writeConfig();
+}
+
+void torkview_base::slotAddPermExcludeCountry( )
+{
+ QStringList selectedCountries = selectByCountry();
+
+ QStringList newCountries = TorkConfig::excludeCountries();
+ for ( QStringList::Iterator it = selectedCountries.begin(); it != selectedCountries.end(); ++it )
+ {
+ if ((!TorkConfig::excludeCountries().contains(*it)) &&
+ (!newCountries.contains(*it)))
+ newCountries.append(*it);
+ }
+ TorkConfig::setExcludeCountries(newCountries);
+
+ addExcludeNodes(true,TorkConfig::excludeCountries());
+}
+
+void torkview_base::slotAddPermExcludeNodes( )
+{
+ addExcludeNodes(true, QStringList());
+}
+
+QStringList torkview_base::selectByCountry( )
+{
+
+ QStringList selectCountries;
+
+ QListViewItemIterator it(serverList, QListViewItemIterator::Selected | QListViewItemIterator::Visible);
+ while ( it.current() ) {
+ QString cc = (*it)->text(4);
+ selectCountries.append(cc);
+ ++it;
+ }
+ return selectCountries;
+}
+
+void torkview_base::slotAddSessionExcludeCountry( )
+{
+
+ addExcludeNodes(false, selectByCountry());
+}
+
+void torkview_base::slotAddSessionExcludeNodes( )
+{
+ addExcludeNodes(false, QStringList());
+}
+
+void torkview_base::slotAddPermExitNodes( )
+{
+ addExitNodes(true, false);
+}
+
+void torkview_base::slotAddPermStrictExitNodes( )
+{
+ addExitNodes(true, true);
+}
+
+void torkview_base::slotAddSessionExitNodes( )
+{
+ addExitNodes(false, false);
+}
+
+void torkview_base::slotAddSessionStrictExitNodes( )
+{
+ addExitNodes(false, true);
+}
+
+void torkview_base::slotAddPermEntryNodes( )
+{
+ addEntryNodes(true);
+}
+
+void torkview_base::slotAddSessionEntryNodes( )
+{
+ addEntryNodes(false);
+}
+
+void torkview_base::addExcludeNodes(bool perm, QStringList ccs )
+{
+
+ QStringList currentList;
+ currentList = TorkConfig::currentExcludeNodes();
+ QStringList permList;
+ permList = TorkConfig::excludeNodes();
+ QListViewItemIterator::IteratorFlag filter;
+
+ if (ccs.isEmpty())
+ filter = QListViewItemIterator::IteratorFlag(QListViewItemIterator::Selected | QListViewItemIterator::Visible);
+ else
+ filter = QListViewItemIterator::IteratorFlag();
+
+ QListViewItemIterator it(serverList, filter);
+
+ while ( it.current() ) {
+ if (!ccs.isEmpty()){
+ if (!ccs.contains((*it)->text(4))){
+ ++it;
+ continue;
+ }
+ }
+
+ QString node = "$"+getFPFromFPDigest((*it)->text(2));
+ currentList.append(node);
+ if (perm){
+ permList.append(node);
+ if (!TorkConfig::excludeServersHistory().contains(QString("%1-%2-%3")
+ .arg((*it)->text(4)).arg((*it)->text(2)).arg((*it)->text(1)))){
+ QStringList existingServers = TorkConfig::excludeServersHistory();
+ existingServers.append(QString("%1-%2-%3")
+ .arg((*it)->text(4)).arg((*it)->text(2)).arg((*it)->text(1)));
+ TorkConfig::setExcludeServersHistory(existingServers);
+ }
+
+ }
+ //kdDebug() << getFPFromFPDigest((*it)->text(2)) << endl;
+ ++it;
+ }
+ TorkConfig::setCurrentExcludeNodes(currentList);
+ TorkConfig::setExcludeNodes(permList);
+
+ QListView* tmp = dynamic_cast<QListView*>(circuitList);
+ emit closeAllCircuits(tmp);
+ emit updateExcludeNodes();
+
+ emit copyOldConfig();
+
+}
+
+void torkview_base::addEntryNodes( bool perm )
+{
+
+ QStringList currentList;
+ currentList = TorkConfig::currentEntryNodes();
+ QStringList permList;
+ permList = TorkConfig::entryNodes();
+
+ QListViewItemIterator it(serverList, QListViewItemIterator::Selected | QListViewItemIterator::Visible);
+ while ( it.current() ) {
+ QString node = "$"+getFPFromFPDigest((*it)->text(2));
+ currentList.append(node);
+ if (perm)
+ permList.append(node);
+ //kdDebug() << getFPFromFPDigest((*it)->text(2)) << endl;
+ ++it;
+ }
+ TorkConfig::setCurrentEntryNodes(currentList);
+ TorkConfig::setEntryNodes(permList);
+ emit copyOldConfig();
+ QListView* tmp = dynamic_cast<QListView*>(circuitList);
+ emit closeAllCircuits(tmp);
+ emit updateEntryNodes();
+
+}
+
+void torkview_base::addExitNodes(bool perm , bool strict)
+{
+
+ QStringList currentList;
+ currentList = TorkConfig::currentExitNodes();
+ QStringList permList;
+ permList = TorkConfig::exitNodes();
+
+ QListViewItemIterator it(serverList, QListViewItemIterator::Selected | QListViewItemIterator::Visible);
+ while ( it.current() ) {
+ QString node = "$"+getFPFromFPDigest((*it)->text(2));
+ currentList.append(node);
+ if (perm){
+ permList.append(node);
+ if (!TorkConfig::includeServersHistory().contains(QString("%1-%2-%3")
+ .arg((*it)->text(4)).arg((*it)->text(2)).arg((*it)->text(1)))){
+ QStringList existingServers = TorkConfig::includeServersHistory();
+ existingServers.append(QString("%1-%2-%3")
+ .arg((*it)->text(4)).arg((*it)->text(2)).arg((*it)->text(1)));
+ TorkConfig::setIncludeServersHistory(existingServers);
+ }
+
+ }
+ //kdDebug() << getFPFromFPDigest((*it)->text(2)) << endl;
+ ++it;
+ }
+ TorkConfig::setCurrentExitNodes(currentList);
+ TorkConfig::setExitNodes(permList);
+ if (perm)
+ TorkConfig::setStrictExitNodes(strict);
+
+ QListView* tmp = dynamic_cast<QListView*>(circuitList);
+ emit closeAllCircuits(tmp);
+
+ emit updateExitNodes();
+ emit updateStrictExitNodes(strict);
+ emit copyOldConfig();
+
+}
+void torkview_base::clearInfo_clicked()
+{
+ infoList->clear();
+}
+
+
+void torkview_base::clearTorTraffic_clicked()
+{
+ TorTraffic->clear();
+}
+
+
+void torkview_base::clearNonTorTraffic_clicked()
+{
+
+ NonTorTraffic->clear();
+
+}
+
+void torkview_base::NonTorTrafficMaxEntries_valueChanged( int newval)
+{
+ TorkConfig::setNonTorTrafficMaxEntries(newval);
+ TorkConfig::writeConfig();
+}
+
+
+void torkview_base::useNewIdentity_clicked( int, int )
+{
+
+ emit newIdentity();
+}
+
+
+void torkview_base::useKonqWithTor_clicked( int, int )
+{
+
+ emit konqWithTor();
+}
+
+
+void torkview_base::viewNetworkList_clicked( int, int )
+{
+
+ emit networkList();
+}
+
+
+void torkview_base::viewHiddenServices_clicked( int, int )
+{
+
+ emit hiddenServices();
+}
+
+
+void torkview_base::kcfg_LogNonTorTraffic_toggled( bool state)
+{
+ TorkConfig::setLogNonTorTraffic(state);
+ NonTorTraffic->setEnabled(state);
+ emit toggleNonTorTraffic( state );
+}
+
+
+void torkview_base::kcfg_LogTorTraffic_toggled( bool state)
+{
+ TorkConfig::setLogTorTraffic(state);
+/* TorkConfig::writeConfig();*/
+ TorTraffic->setEnabled(state);
+ emit toggleTorTraffic( state );
+}
+
+
+void torkview_base::ShowHostNames_toggled( bool safe)
+{
+ emit safeLogging(!safe);
+}
+
+void torkview_base::copyLogLines()
+{
+ QClipboard *cb = QApplication::clipboard();
+ QString logLines;
+
+ QListViewItemIterator it(infoList, QListViewItemIterator::Selected | QListViewItemIterator::Visible);
+ while ( it.current() ) {
+ // Copy text into the clipboard
+ logLines.append((*it)->text(0));
+ logLines.append("\t");
+ logLines.append((*it)->text(2));
+ logLines.append("\t");
+ logLines.append((*it)->text(3));
+ logLines.append("\n");
+
+ ++it;
+ }
+
+ cb->setText( logLines, QClipboard::Clipboard );
+
+}
+
+void torkview_base::selectAllLogLines()
+{
+ QListViewItemIterator it(infoList);
+ while ( it.current() ) {
+ (*it)->setSelected(true);
+ ++it;
+ }
+ infoList->repaint();
+}
+
+void torkview_base::infoList_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+ QPopupMenu *menu = new QPopupMenu( infoList );
+
+ menu->clear();
+ menu->insertItem( SmallIconSet("copy"), "Copy", this, SLOT(copyLogLines()) );
+ menu->insertSeparator();
+ menu->insertItem( "Select All", this, SLOT(selectAllLogLines()) );
+ menu->popup( point );
+
+}
+
+
+void torkview_base::TorTraffic_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( TorTraffic );
+
+ menu->clear();
+ menu->insertItem( SmallIconSet("help"), "Resolve Hostname/Address", this, SLOT(queryHostName()) );
+ menu->popup( point );
+
+}
+
+void torkview_base::queryHostName()
+{
+ QRegExp rx("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}");
+ QRegExp rx2("[^:]+");
+
+ QListView *tmpList;
+ QString addressToResolve;
+ QString addressToMatch;
+
+ if (TorTraffic->hasFocus()) {
+ tmpList = TorTraffic;
+ }else{
+ tmpList = NonTorTraffic;
+ }
+
+ int col = (tmpList == TorTraffic) ? 2 : 1;
+ rx.search(tmpList->selectedItem()->text(col));
+ QString tmp = rx.cap(0);
+ rx2.search(tmpList->selectedItem()->text(col));
+ QString tmp2 = rx2.cap(0);
+
+ if (!tmp.isEmpty()){
+ addressToMatch = QString("REVERSE[%1]").arg(tmp);
+ addressToResolve = tmp;
+ }else{
+ addressToResolve = tmp2;
+ addressToMatch = tmp2;
+ }
+
+ resolveMap[addressToMatch] = tmpList->selectedItem();
+ resolveColMap[tmpList->selectedItem()] = col;
+
+ emit resolveAddress(addressToResolve);
+}
+
+void torkview_base::resolvedAddress(const QString &info)
+{
+ QString type = info.section(" ",0,0);
+ QString address = info.section(" ",1,1);
+
+ if (resolveMap[type]){
+ int column = resolveColMap[resolveMap[type]];
+ resolveMap[type]->setText(column,address);
+ resolveMap.erase(type);
+ resolveColMap.erase(resolveMap[type]);
+ }
+}
+
+void torkview_base::NonTorTraffic_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+ QPopupMenu *menu = new QPopupMenu( NonTorTraffic );
+
+ menu->clear();
+ menu->insertItem( SmallIconSet("help"), "Resolve Hostname/Address", this, SLOT(queryHostName()) );
+ menu->popup( point );
+
+}
diff --git a/src/torservers.ui b/src/torservers.ui
new file mode 100644
index 0000000..bad5983
--- /dev/null
+++ b/src/torservers.ui
@@ -0,0 +1,619 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>TorServers</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>TorServers</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>556</width>
+ <height>435</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>MyDialog1</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QTabWidget" row="0" column="0">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Exit Servers To Avoid</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView" row="0" column="2" rowspan="4" colspan="1">
+ <column>
+ <property name="text">
+ <string>CC</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>geoipcc</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>FP</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Enemy Servers </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>ExcludeNodes</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QListBox" row="3" column="0">
+ <property name="name">
+ <cstring>CountryList</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>110</height>
+ </size>
+ </property>
+ <property name="selectionMode">
+ <enum>Multi</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Countries To Avoid:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <spacer row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>310</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="3" column="1">
+ <property name="name">
+ <cstring>spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>140</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel7_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; These are exit servers you have chosen to avoid. Exit servers are the computers where your traffic emerges back in to the real world and connects to the service you are using (e.g.the web page you are reading).&lt;/p&gt;
+&lt;p&gt; You have selected countries to avoid below. &lt;/p&gt;
+&lt;p&gt; To select a country or server, right-click on a server in the 'Tor Network' window and select 'From Now On Never Use At All' or 'From Now On Never Use Country At All'. &lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="4" column="2">
+ <property name="name">
+ <cstring>clearSelectedNodes</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Delete Selected</string>
+ </property>
+ <property name="accel">
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="4" column="0">
+ <property name="name">
+ <cstring>clearSelectedCountries</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Delete Selected</string>
+ </property>
+ <property name="accel">
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Preferred Exit Servers</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView" row="0" column="1">
+ <column>
+ <property name="text">
+ <string>CC</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>geoipcc</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>FP</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Preferred Exit Servers</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>ExitNodes</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>clearSelectedPreferredNodes</cstring>
+ </property>
+ <property name="text">
+ <string>Delete Selected</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0">
+ <property name="name">
+ <cstring>kcfg_StrictExitNodes</cstring>
+ </property>
+ <property name="text">
+ <string>Use onl&amp;y these servers for 'Exit'.</string>
+ </property>
+ <property name="accel">
+ <string>Alt+Y</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel7_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; This is the list of servers you prefer to use as the exit point for traffic over the internet. These are the servers where you traffic emerges back in to the real world and connects to the service you are using (e.g.the web page you are reading).
+&lt;p&gt; To select a country or server, right-click on a server in the 'Tor Network' window and select 'Try to Use Server as an Exit' or 'Always Use Server as an Exit'. &lt;/p&gt;</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>TabPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>S&amp;pecial Friends</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel7_2_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; This is the list of servers you like to use for particular destinations. For example, all traffic to Google should pop out on to the internet from the friendly server 'trustme'.</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>Destination</cstring>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="4">
+ <property name="name">
+ <cstring>pushButton6</cstring>
+ </property>
+ <property name="text">
+ <string>O&amp;K</string>
+ </property>
+ <property name="accel">
+ <string>Alt+K</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="2">
+ <property name="name">
+ <cstring>CandidateList</cstring>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QListView" row="0" column="1" rowspan="1" colspan="4">
+ <column>
+ <property name="text">
+ <string>Destination </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Server </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>When </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>MapAddress</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="3">
+ <item>
+ <property name="text">
+ <string>Entry</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Exit</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>WayPoints</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>Widget8</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Servers Status</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox14</cstring>
+ </property>
+ <property name="title">
+ <string>Unverified Servers</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>You can direct your traffic over &lt;br&gt; servers that haven't been verified &lt;br&gt; yet. Choose the stages in the route over the internet you feel comfortable trusting unverified servers with.</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="0" column="1">
+ <column>
+ <property name="text">
+ <string>Position on Circuit</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <item>
+ <property name="text">
+ <string>Rendezvous</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Introduction</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Middle</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Exit</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Entry</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>AllowUnverifiedNodes</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>pushButton6_2</cstring>
+ </property>
+ <property name="text">
+ <string>Clear Selected</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox" row="0" column="0">
+ <property name="name">
+ <cstring>groupBox19</cstring>
+ </property>
+ <property name="title">
+ <string>Verified Servers</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>textLabel6_3</cstring>
+ </property>
+ <property name="text">
+ <string>seconds</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="0" column="1">
+ <property name="name">
+ <cstring>kcfg_NewCircuitPeriod</cstring>
+ </property>
+ <property name="maxValue">
+ <number>99999</number>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel6_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Build new route on known servers every:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>MapAddress</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>TorServers</receiver>
+ <slot>MapAddress_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>MapAddress</sender>
+ <signal>returnPressed(QListViewItem*)</signal>
+ <receiver>TorServers</receiver>
+ <slot>MapAddress_returnPressed(QListViewItem*)</slot>
+ </connection>
+ <connection>
+ <sender>pushButton6</sender>
+ <signal>clicked()</signal>
+ <receiver>TorServers</receiver>
+ <slot>pushButton6_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>pushButton6_2</sender>
+ <signal>clicked()</signal>
+ <receiver>TorServers</receiver>
+ <slot>pushButton6_2_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>clearSelectedCountries</sender>
+ <signal>clicked()</signal>
+ <receiver>TorServers</receiver>
+ <slot>clearSelectedCountries_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>clearSelectedNodes</sender>
+ <signal>clicked()</signal>
+ <receiver>TorServers</receiver>
+ <slot>clearSelectedNodes_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>clearSelectedPreferredNodes</sender>
+ <signal>clicked()</signal>
+ <receiver>TorServers</receiver>
+ <slot>clearSelectedPreferredNodes_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>CountryList</sender>
+ <signal>selectionChanged()</signal>
+ <receiver>TorServers</receiver>
+ <slot>CountryList_clicked()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">torservers.ui.h</include>
+</includes>
+<slots>
+ <slot>pushButton6_clicked()</slot>
+ <slot>MapAddress_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotDeleteEntry()</slot>
+ <slot>MapAddress_returnPressed( QListViewItem * )</slot>
+ <slot>clearSelectedCountries_clicked()</slot>
+ <slot>clearSelectedNodes_clicked()</slot>
+ <slot>clearSelectedPreferredNodes_clicked()</slot>
+ <slot>pushButton6_2_clicked()</slot>
+ <slot>CountryList_clicked()</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+ <function access="private" specifier="non virtual">destroy()</function>
+ <function specifier="non virtual" returnType="QString">ccode( const QString &amp; country )</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/torservers.ui.h b/src/torservers.ui.h
new file mode 100644
index 0000000..caf7021
--- /dev/null
+++ b/src/torservers.ui.h
@@ -0,0 +1,450 @@
+/***************************************************************************
+ * $Id: torservers.ui.h,v 1.22 2009/01/17 15:49:08 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "torkconfig.h"
+#include "crypto.h"
+#include <klocale.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <kdebug.h>
+#include <kiconloader.h>
+
+#ifndef EXTERNAL_GEOIP
+# include "GeoIP-1.4.0/libGeoIP/GeoIP.h"
+#else
+# include <GeoIP.h>
+#endif
+
+typedef QMap<QString, QString> codemap;
+QString ccode;
+QString cname;
+codemap ccodes;
+QStringList blockCCs;
+
+void TorServers::init()
+{
+
+ ExcludeNodes->setSelectionMode( QListView::Extended );
+ ExcludeNodes->setColumnWidthMode(0, QListView::Manual);
+ ExcludeNodes->hideColumn(0);
+ ExcludeNodes->header()->setResizeEnabled(FALSE, 0);
+ ExcludeNodes->setColumnWidthMode(1, QListView::Manual);
+ ExcludeNodes->hideColumn(1);
+ ExcludeNodes->header()->setResizeEnabled(FALSE, 1);
+ ExcludeNodes->setColumnWidthMode(2, QListView::Manual);
+ ExcludeNodes->hideColumn(2);
+ ExcludeNodes->header()->setResizeEnabled(FALSE, 2);
+ ExcludeNodes->setResizeMode( QListView::LastColumn );
+
+ ExitNodes->setSelectionMode( QListView::Extended );
+ ExitNodes->setColumnWidthMode(0, QListView::Manual);
+ ExitNodes->hideColumn(0);
+ ExitNodes->header()->setResizeEnabled(FALSE, 0);
+ ExitNodes->setColumnWidthMode(1, QListView::Manual);
+ ExitNodes->hideColumn(1);
+ ExitNodes->header()->setResizeEnabled(FALSE, 1);
+ ExitNodes->setColumnWidthMode(2, QListView::Manual);
+ ExitNodes->hideColumn(2);
+ ExitNodes->header()->setResizeEnabled(FALSE, 2);
+ ExitNodes->setResizeMode( QListView::LastColumn );
+ QListViewItem *tm;
+ QString fp;
+ QString nick;
+ QString geoipcc;
+ QString countryName;
+
+ QStringList excludeCountries = TorkConfig::excludeCountries();
+ for ( QStringList::Iterator it = excludeCountries.begin(); it != excludeCountries.end(); ++it )
+ {
+ countryName = GeoIP_country_name[(*it).toInt()];
+ ccodes[countryName] = (*it);
+ CountryList->insertItem(countryName);
+ }
+
+// QStringList preferredCountries = TorkConfig::preferredCountries();
+// for ( QStringList::Iterator it = preferredCountries.begin(); it != preferredCountries.end(); ++it )
+// {
+// countryName = GeoIP_country_name[(*it).toInt()];
+// ccodes[countryName] = (*it);
+// PreferredCountryList->insertItem(countryName);
+// }
+
+ QStringList existingServers = TorkConfig::excludeServersHistory();
+
+ for ( QStringList::Iterator it = existingServers.begin(); it != existingServers.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+
+ fp.setLength(0);
+ nick.setLength(0);
+ geoipcc = (*it).section("-",0,0);
+ fp = (*it).section("-",1,1);
+ nick = (*it).section("-",2);
+ countryName = GeoIP_country_name[(geoipcc).toInt()];
+
+ tm = new QListViewItem(ExcludeNodes,countryName,geoipcc,fp,nick);
+ tm->setPixmap(3,QPixmap(SmallIcon("tork_" + QString(GeoIP_country_code[geoipcc.toInt()]).lower())));
+
+
+ }
+
+ existingServers = TorkConfig::includeServersHistory();
+
+ for ( QStringList::Iterator it = existingServers.begin(); it != existingServers.end(); ++it )
+ {
+
+ if ((*it).isEmpty())
+ continue;
+
+ fp.setLength(0);
+ nick.setLength(0);
+ geoipcc = (*it).section("-",0,0);
+ fp = (*it).section("-",1,1);
+ nick = (*it).section("-",2);
+ countryName = GeoIP_country_name[(geoipcc).toInt()];
+
+ tm = new QListViewItem(ExitNodes,countryName,geoipcc,fp,nick);
+ tm->setPixmap(3,QPixmap(SmallIcon("tork_" + QString(GeoIP_country_code[geoipcc.toInt()]).lower())));
+
+// CandidateList->insertItem( nick );
+
+ }
+ QStringList mapAddresses = TorkConfig::mapAddress();
+
+ for ( QStringList::Iterator it = mapAddresses.begin(); it != mapAddresses.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ QString entry = (*it).section(" ",1,1);
+ QString destination = entry.section(".",0,-3);
+ QString server = entry.section(".",-2,-2);
+ QString waypoint = entry.section(".",-1,-1);
+
+ tm = new QListViewItem(MapAddress,destination,server,waypoint);
+ }
+
+ QListViewItemIterator it(AllowUnverifiedNodes);
+ while ( it.current() ) {
+ if (TorkConfig::allowUnverifiedNodes().contains(it.current()->text(0)))
+ AllowUnverifiedNodes->setSelected(*it,true);
+ ++it;
+ }
+
+ CountryList->sort(true);
+// PreferredCountryList->sort(true);
+
+ kcfg_StrictExitNodes->setEnabled((ExitNodes->childCount() == 0)?false:true);
+
+}
+
+void TorServers::destroy()
+{
+// QStringList cclist;
+// for (unsigned int index = 0; index != CountryList->count(); ++index){
+// cclist.append(ccodes[CountryList->item(index)->text()]);
+// }
+// TorkConfig::setExcludeCountries(cclist);
+//
+// cclist.clear();
+// for (unsigned int index = 0; index != PreferredCountryList->count(); ++index){
+// cclist.append(ccodes[PreferredCountryList->item(index)->text()]);
+// }
+// TorkConfig::setPreferredCountries(cclist);
+//
+// TorkConfig::writeConfig();
+
+}
+
+QString TorServers::ccode(const QString &country)
+{
+ return ccodes[country];
+}
+
+void TorServers::pushButton6_clicked()
+{
+
+ new QListViewItem(MapAddress,Destination->text(), CandidateList->currentText(), WayPoints->currentText());
+}
+
+
+
+void TorServers::MapAddress_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( MapAddress );
+
+ menu->clear();
+ menu->insertItem( "Delete Entry", this,SLOT(slotDeleteEntry()) );
+ menu->popup( point );
+
+}
+
+
+void TorServers::slotDeleteEntry( )
+{
+
+ QListViewItemIterator it(MapAddress, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (MapAddress->isSelected( it.current()))
+ delete it.current();
+ ++it;
+ }
+
+
+}
+
+
+void TorServers::MapAddress_returnPressed( QListViewItem * )
+{
+
+}
+
+
+void TorServers::clearSelectedCountries_clicked()
+{
+
+ QValueList<QListViewItem*> itemsToDelete;
+
+ QListViewItemIterator it(ExcludeNodes, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (CountryList->findItem(it.current()->text(0))->isSelected()){
+ itemsToDelete << it.current();
+ }
+ ++it;
+ }
+
+ for ( QValueList<QListViewItem*>::Iterator itt = itemsToDelete.begin(); itt != itemsToDelete.end(); ++itt ){
+ delete (*itt);
+ }
+
+ QValueList<QListBoxItem*> countriesToDelete;
+
+ for (unsigned int index = 0; index != CountryList->count(); ++index){
+ if (CountryList->item(index)->isSelected() )
+ countriesToDelete << CountryList->item(index);
+ }
+
+ for ( QValueList<QListBoxItem*>::Iterator itb = countriesToDelete.begin();
+ itb != countriesToDelete.end(); ++itb ){
+ delete (*itb);
+ }
+
+ CountryList->clearSelection();
+}
+
+
+void TorServers::clearSelectedNodes_clicked()
+{
+
+ QValueList<QListViewItem*> itemsToDelete;
+
+ QListViewItemIterator it(ExcludeNodes, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ itemsToDelete << it.current();
+ ++it;
+ }
+
+ for ( QValueList<QListViewItem*>::Iterator itt = itemsToDelete.begin(); itt != itemsToDelete.end(); ++itt ){
+ delete (*itt);
+ }
+
+ CountryList->clearSelection();
+}
+
+
+// void TorServers::clearSelectedPreferredCountries_clicked()
+// {
+//
+// QValueList<QListViewItem*> itemsToDelete;
+//
+// QListViewItemIterator it(ExitNodes, QListViewItemIterator::Selected);
+// while ( it.current() ) {
+// if (PreferredCountryList->findItem(it.current()->text(0))->isSelected()){
+// itemsToDelete << it.current();
+// }
+// ++it;
+// }
+//
+// for ( QValueList<QListViewItem*>::Iterator itt = itemsToDelete.begin(); itt != itemsToDelete.end(); ++itt ){
+// delete (*itt);
+// }
+//
+// QValueList<QListBoxItem*> countriesToDelete;
+//
+// for (unsigned int index = 0; index != PreferredCountryList->count(); ++index){
+// if (PreferredCountryList->item(index)->isSelected() )
+// countriesToDelete << PreferredCountryList->item(index);
+// }
+//
+// for ( QValueList<QListBoxItem*>::Iterator itb = countriesToDelete.begin();
+// itb != countriesToDelete.end(); ++itb ){
+// delete (*itb);
+// }
+//
+// PreferredCountryList->clearSelection();
+// }
+
+
+void TorServers::clearSelectedPreferredNodes_clicked()
+{
+
+ QValueList<QListViewItem*> itemsToDelete;
+
+ QListViewItemIterator it(ExitNodes, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ itemsToDelete << it.current();
+ ++it;
+ }
+
+ for ( QValueList<QListViewItem*>::Iterator itt = itemsToDelete.begin(); itt != itemsToDelete.end(); ++itt ){
+ delete (*itt);
+ }
+
+ if (ExitNodes->childCount() == 0){
+ kcfg_StrictExitNodes->setEnabled(false);
+ kcfg_StrictExitNodes->setChecked(false);
+ }
+}
+
+
+
+void TorServers::pushButton6_2_clicked()
+{
+
+ QListViewItemIterator it(AllowUnverifiedNodes, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ it.current()->listView()->setSelected(it.current(),false);
+ ++it;
+ }
+
+}
+
+void TorServers::CountryList_clicked( )
+{
+
+ QStringList selectedCountries;
+ for ( unsigned int i = 0; i < CountryList->count(); ++i){
+ if (CountryList->isSelected(i)){
+ selectedCountries.append(CountryList->item(i)->text());
+ }
+ }
+
+ kdDebug() << "country list clicked" << endl;
+ QListViewItemIterator it( ExcludeNodes );
+ while ( it.current() ) {
+ QListViewItem *item = it.current();
+ if (selectedCountries.contains(item->text(0)))
+ item->setSelected(true);
+ else
+ item->setSelected(false);
+ it++;
+ }
+ ExcludeNodes->repaintContents();
+
+}
+
+// void TorServers::PreferredCountryList_clicked( QListBoxItem * curitem)
+// {
+//
+// QListViewItemIterator it( ExitNodes );
+// while ( it.current() ) {
+// QListViewItem *item = it.current();
+// if (curitem){
+// if (item->text(0) == curitem->text())
+// item->setSelected(curitem->isSelected());
+// }
+// it++;
+// }
+// ExitNodes->repaintContents();
+//
+// }
+
+
+
+// <connections>
+// <connection>
+// <sender>pushButton6</sender>
+// <signal>clicked()</signal>
+// <receiver>TorServers</receiver>
+// <slot>pushButton6_clicked()</slot>
+// </connection>
+// <connection>
+// <sender>MapAddress</sender>
+// <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+// <receiver>TorServers</receiver>
+// <slot>MapAddress_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+// </connection>
+// <connection>
+// <sender>MapAddress</sender>
+// <signal>returnPressed(QListViewItem*)</signal>
+// <receiver>TorServers</receiver>
+// <slot>MapAddress_returnPressed(QListViewItem*)</slot>
+// </connection>
+// <connection>
+// <sender>clearSelected</sender>
+// <signal>clicked()</signal>
+// <receiver>TorServers</receiver>
+// <slot>clearSelected_clicked()</slot>
+// </connection>
+// <connection>
+// <sender>clearSelected_2</sender>
+// <signal>clicked()</signal>
+// <receiver>TorServers</receiver>
+// <slot>clearSelected_2_clicked()</slot>
+// </connection>
+// <connection>
+// <sender>clearSelected_3</sender>
+// <signal>clicked()</signal>
+// <receiver>TorServers</receiver>
+// <slot>clearSelected_3_clicked()</slot>
+// </connection>
+// <connection>
+// <sender>clearSelected_3_2</sender>
+// <signal>clicked()</signal>
+// <receiver>TorServers</receiver>
+// <slot>clearSelected_3_2_clicked()</slot>
+// </connection>
+// <connection>
+// <sender>pushButton6_2</sender>
+// <signal>clicked()</signal>
+// <receiver>TorServers</receiver>
+// <slot>pushButton6_2_clicked()</slot>
+// </connection>
+// </connections>
+// <includes>
+// <include location="local" impldecl="in implementation">torservers.ui.h</include>
+// </includes>
+// <slots>
+// <slot>pushButton6_clicked()</slot>
+// <slot>MapAddress_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+// <slot>slotDeleteEntry()</slot>
+// <slot>MapAddress_returnPressed( QListViewItem * )</slot>
+// <slot>clearSelected_clicked()</slot>
+// <slot>clearSelected_2_clicked()</slot>
+// <slot>clearSelected_3_clicked()</slot>
+// <slot>clearSelected_3_2_clicked()</slot>
+// <slot>pushButton6_2_clicked()</slot>
+// </slots>
+// <functions>
+// <function access="private" specifier="non virtual">init()</function>
+// </functions>
+// <layoutdefaults spacing="6" margin="11"/>
+// </UI>
diff --git a/src/trayhoverpopup.cpp b/src/trayhoverpopup.cpp
new file mode 100644
index 0000000..2c63fd0
--- /dev/null
+++ b/src/trayhoverpopup.cpp
@@ -0,0 +1,154 @@
+/***************************************************************************
+ * $Id: trayhoverpopup.cpp,v 1.4 2008/07/31 19:56:28 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qtooltip.h>
+#include <qpixmap.h>
+#include <kdialog.h>
+#include "trayhoverpopup.h"
+
+
+TrayHoverPopup::TrayHoverPopup(const QPixmap & pix,QWidget *parent, const char *name )
+ : KPassivePopup(KPassivePopup::Boxed,parent,name),pix(pix)
+{
+ setTimeout(0);
+ setAutoDelete(false);
+ connect(&hover_timer,SIGNAL(timeout()),this,SLOT(onHoverTimeout()));
+ connect(&show_timer,SIGNAL(timeout()),this,SLOT(onShowTimeout()));
+ create();
+ setPalette(QToolTip::palette());
+ setLineWidth(1);
+ context_menu_shown = false;
+ cursor_over_icon = false;
+}
+
+
+TrayHoverPopup::~TrayHoverPopup()
+{}
+
+void TrayHoverPopup::contextMenuAboutToShow()
+{
+ context_menu_shown = true;
+ if (isShown())
+ {
+ hide();
+ hover_timer.stop();
+ }
+}
+
+void TrayHoverPopup::contextMenuAboutToHide()
+{
+ context_menu_shown = false;
+}
+
+
+void TrayHoverPopup::enterEvent()
+{
+ cursor_over_icon = true;
+ if (isHidden() && !context_menu_shown)
+ {
+ // start the show timer
+ show_timer.start(1000,true);
+ }
+ else
+ hover_timer.stop(); // stop timeout
+}
+
+void TrayHoverPopup::leaveEvent()
+{
+ cursor_over_icon = false;
+ // to avoid problems with a quick succession of enter and leave events, because the cursor
+ // is on the edge, use a timer to expire the popup
+ // in enterEvent we will stop the timer
+ if (isShown())
+ hover_timer.start(2000,true);
+}
+
+void TrayHoverPopup::onHoverTimeout()
+{
+ hide();
+ show_timer.stop();
+}
+
+void TrayHoverPopup::onShowTimeout()
+{
+ if (!context_menu_shown && cursor_over_icon)
+ show();
+}
+
+void TrayHoverPopup::updateText(const QString & msg)
+{
+ text->setText(msg);
+}
+
+void TrayHoverPopup::create()
+{
+ QVBox *vb = new QVBox(this);
+ vb->setSpacing(KDialog::spacingHint());
+
+ QHBox *hb=0;
+ if (!pix.isNull())
+ {
+ hb = new QHBox(vb);
+ hb->setMargin(0);
+ hb->setSpacing(KDialog::spacingHint());
+ QLabel* pix_lbl = new QLabel(hb,"title_icon");
+ pix_lbl->setPixmap(pix);
+ pix_lbl->setAlignment(AlignLeft);
+ }
+
+
+ QLabel* title = new QLabel("Tor Status", hb ? hb : vb, "title_label" );
+ QFont fnt = title->font();
+ fnt.setBold( true );
+ title->setFont( fnt );
+ title->setAlignment( Qt::AlignHCenter );
+ if ( hb )
+ hb->setStretchFactor(title, 10 ); // enforce centering
+
+ // text will be filled later
+ text = new QLabel( "Dummy", vb, "msg_label" );
+ text->setAlignment( AlignLeft );
+ setView(vb);
+}
+
+
+#include "trayhoverpopup.moc"
diff --git a/src/trayhoverpopup.h b/src/trayhoverpopup.h
new file mode 100644
index 0000000..ee03f6a
--- /dev/null
+++ b/src/trayhoverpopup.h
@@ -0,0 +1,91 @@
+/***************************************************************************
+ * $Id: trayhoverpopup.h,v 1.4 2008/07/31 19:56:28 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef TRAYHOVERPOPUP_H
+#define TRAYHOVERPOPUP_H
+
+#include <qtimer.h>
+#include <kpassivepopup.h>
+
+class QLabel;
+class QPixmap;
+
+/**
+ @author Joris Guisson <joris.guisson@gmail.com>
+
+ This is the passive popup which is shown when the mouse cursor is hovered over the tray icon
+*/
+class TrayHoverPopup : public KPassivePopup
+{
+ Q_OBJECT
+public:
+ TrayHoverPopup(const QPixmap & pix,QWidget *parent = 0, const char *name = 0 );
+ virtual ~TrayHoverPopup();
+
+ /// Cursor entered system tray icon
+ void enterEvent();
+
+ /// Cursor left system tray icon
+ void leaveEvent();
+
+ /// Update the text which is shown
+ void updateText(const QString & msg);
+
+public slots:
+ void contextMenuAboutToShow();
+ void contextMenuAboutToHide();
+
+private:
+ void create();
+
+private slots:
+ void onHoverTimeout();
+ void onShowTimeout();
+
+
+private:
+ const QPixmap & pix;
+ QTimer hover_timer;
+ QTimer show_timer;
+ QLabel* text;
+ bool context_menu_shown;
+ bool cursor_over_icon;
+};
+
+#endif
diff --git a/src/trayicon.cpp b/src/trayicon.cpp
new file mode 100644
index 0000000..5517def
--- /dev/null
+++ b/src/trayicon.cpp
@@ -0,0 +1,270 @@
+/***************************************************************************
+ * $Id: trayicon.cpp,v 1.10 2008/07/31 19:56:28 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************
+ * This is a modified version of trayicon.cpp from ktorrent. *
+ * Original copyright notice follows: *
+ ***************************************************************************
+ * Copyright (C) 2005 by *
+ * Joris Guisson <joris.guisson@gmail.com> *
+ * Ivan Vasic <ivasic@gmail.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <kpopupmenu.h>
+#include <kurldrag.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include "trayicon.h"
+#include <qtooltip.h>
+#include <kpassivepopup.h>
+#include <qstringlist.h>
+#include "trayhoverpopup.h"
+#include "torkconfig.h"
+
+
+TrayIcon::TrayIcon( tork *parent, const char *name)
+ : KSystemTray(parent, name)
+{
+ m_kt_pix = loadIcon("tork");
+ setPixmap(m_kt_pix);
+ paint=new QPainter( this );
+ drawContents ( paint );
+ m_parent = parent;
+
+ setAcceptDrops( TRUE );
+ m_hover_popup = new TrayHoverPopup(m_kt_pix,this);
+
+ connect(this,SIGNAL(quitSelected()),kapp,SLOT(quit()));
+
+ connect(this->contextMenu(),SIGNAL(aboutToShow()),m_hover_popup,SLOT(contextMenuAboutToShow()));
+ connect(this->contextMenu(),SIGNAL(aboutToHide()),m_hover_popup,SLOT(contextMenuAboutToHide()));
+}
+
+TrayIcon::~TrayIcon()
+{}
+
+void TrayIcon::dragEnterEvent(QDragEnterEvent *e)
+{
+ e->accept (KURLDrag::canDecode(e));
+}
+
+void TrayIcon::dropEvent (QDropEvent *o)
+{
+ KURL::List list;
+ QString text;
+ if ( KURLDrag::decode( o, list ) )
+ droppedfile(list);
+}
+
+void TrayIcon::droppedfile (KURL::List url)
+{
+ m_parent->startEverything();
+ if (TorkConfig::availablePrograms().contains("konqueror"))
+ m_parent->enableKDEAndLaunchKonqWithUrl(url.first().url());
+ else if (TorkConfig::availablePrograms().contains("firefox"))
+ m_parent->anonymizedFirefox(url.first().url());
+}
+
+
+void TrayIcon::enterEvent(QEvent* ev)
+{
+ KSystemTray::enterEvent(ev);
+ m_hover_popup->enterEvent();
+}
+
+void TrayIcon::leaveEvent(QEvent* )
+{
+ m_hover_popup->leaveEvent();
+}
+
+void TrayIcon::updateStats(const QString & downloadBandwidthHist,
+ const QString & uploadBandwidthHist,
+ const QString & downloadBandwidth, const QString & uploadBandwidth,
+ const QStringList & serverReport, const QStringList & clientReport,
+ const QString & curBandwidthRate)
+{
+
+ QString serverStatus;
+ for ( QStringList::ConstIterator it = serverReport.begin(); it != serverReport.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ if ((it) != serverReport.begin())
+ serverStatus.append(QString("<tr><td></td><td colspan='2'>%1</td></tr>").arg((*it)));
+ }
+
+ QString tip = i18n("<table cellpadding='2' cellspacing='2'align='center'>"
+ "<tr>"
+ "<td><b>Client:</b></td>"
+ "<td colspan='2'>%1</td>"
+ "</tr>")
+ .arg(*clientReport.begin());
+ if (!TorkConfig::clientOnly()){
+ tip.append(i18n("<tr>"
+ "<td><b>Server:</b></td>"
+ "<td colspan='2'>Nickname <b>%1</b></td>"
+ "</tr>"
+ "<tr>"
+ "<td></td>"
+ "<td colspan='2'>%2</td>"
+ "</tr>"
+ "%3")
+ .arg(TorkConfig::nickName())
+ .arg(*serverReport.begin())
+ .arg(serverStatus));
+ }
+ tip.append(i18n(
+ "<tr>"
+ "<td></td>"
+ "<td><b>BW Down</b></td>"
+ "<td><b>BW Up</b></td>"
+ "</tr>"
+ "<tr>"
+ "<td><b>Speed:</b></td>"
+ "<td><font color='#1c9a1c'>%1</font></td>"
+ "<td><font color='#990000'>%2</font></td>"
+ "</tr>"
+ "<tr>"
+ "<td><b>Total:</b></td>"
+ "<td><font color='#1c9a1c'>%3</font></td>"
+ "<td> <font color='#990000'>%4</font></td>"
+ "</tr>"
+ "<tr>"
+ "<td><b>Max:</b></td>"
+ "<td><font color='#1c9a1c'>%5</font></td>"
+ "<td> <font color='#990000'>%6</font></td>"
+ "</tr>"
+ "</table>")
+ .arg(downloadBandwidth)
+ .arg(uploadBandwidth)
+ .arg(downloadBandwidthHist)
+ .arg(uploadBandwidthHist)
+ .arg(curBandwidthRate)
+ .arg(curBandwidthRate));
+
+ m_hover_popup->updateText(tip);
+
+}
+
+SetMaxRate::SetMaxRate( tork *parent, const char *name):KPopupMenu(parent, name)
+{
+ m_parent = parent;
+ m_rate = TorkConfig::bandwidthRate();
+ makeMenu();
+ connect(this,SIGNAL(activated(int)),this,SLOT(rateSelected(int)));
+}
+void SetMaxRate::makeMenu()
+{
+
+ int maxBandwidth=(m_rate > 0) ? m_rate : 300 ;
+ int delta = 0;
+ int maxBandwidthRounded;
+
+ setCheckable(true);
+ insertTitle(i18n("Bandwidth Limit"));
+
+ if((maxBandwidth%5)>=3)
+ maxBandwidthRounded=maxBandwidth + 5 - (maxBandwidth%5);
+ else
+ maxBandwidthRounded=maxBandwidth - (maxBandwidth%5);
+
+ for (int i = 0; i < 15; i++)
+ {
+ QValueList<int> valuePair;
+ if (delta == 0)
+ valuePair.append(maxBandwidth);
+ else
+ {
+ if((maxBandwidth%5)!=0)
+ {
+ valuePair.append(maxBandwidthRounded - delta);
+ valuePair.append(maxBandwidthRounded + delta);
+ }
+ else
+ {
+ valuePair.append(maxBandwidth - delta);
+ valuePair.append(maxBandwidth + delta);
+ }
+ }
+
+ for (int j = 0; j < (int)valuePair.count(); j++)
+ {
+ if (valuePair[j] >= 1)
+ {
+ if(m_rate == valuePair[j] && j==0)
+ {
+ setItemChecked(insertItem(QString("%1 KB/s").arg(valuePair[j]),-1, (j == 0) ? 2 : (int)count()), true);
+ }
+ else
+ insertItem(QString("%1 KB/s").arg(valuePair[j]),-1, (j == 0) ? 2 : (int)count());
+ }
+ }
+
+ delta += (delta >= 50) ? 50 : (delta >= 20) ? 10 : 5;
+
+ }
+}
+void SetMaxRate::update()
+{
+ clear();
+ makeMenu();
+}
+
+void SetMaxRate::rateSelected(int id)
+{
+
+// kdDebug() << id << endl;
+// kdDebug() << text(id) << endl;
+// kdDebug() << text(id).toInt() << endl;
+
+ //QT Bug: The value referenced by the QPopUpMenu ID often has an ampersand
+ QString textID = text(id);
+ textID.replace("&","");
+ textID.replace(" KB/s","");
+
+// kdDebug() << textID << endl;
+// kdDebug() << textID.toInt() << endl;
+
+ m_rate=textID.toInt();
+ m_parent->setBandwidthFromSysTray(m_rate);
+ TorkConfig::setBandwidthRate(m_rate);
+ TorkConfig::setBandwidthBurst(m_rate*2);
+ TorkConfig::writeConfig();
+
+ update();
+}
+
+
+#include "trayicon.moc"
diff --git a/src/trayicon.h b/src/trayicon.h
new file mode 100644
index 0000000..b5ffc88
--- /dev/null
+++ b/src/trayicon.h
@@ -0,0 +1,105 @@
+/***************************************************************************
+ * $Id: trayicon.h,v 1.7 2008/07/31 19:56:28 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+/***************************************************************************
+ * Copyright (C) 2005 by *
+ * Joris Guisson <joris.guisson@gmail.com> *
+ * Ivan Vasic <ivasic@gmail.com> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef TRAYICON_H
+#define TRAYICON_H
+
+
+#include <ksystemtray.h>
+#include <kpopupmenu.h>
+#include <qpainter.h>
+#include <kurl.h>
+#include <tork.h>
+
+
+class QString;
+class TrayHoverPopup;
+class tork;
+
+/**
+ * @author Joris Guisson
+ * @author Ivan Vasic
+*/
+class TrayIcon : public KSystemTray
+{
+ Q_OBJECT
+public:
+ TrayIcon(tork *parent = 0, const char *name = 0);
+ virtual ~TrayIcon();
+
+ /// Update stats for system tray icon
+ void updateStats(const QString &, const QString &,
+ const QString &,const QString &, const QStringList &, const QStringList &,
+ const QString &);
+
+private:
+ virtual void enterEvent(QEvent* ev);
+ virtual void leaveEvent(QEvent* ev);
+ virtual void dragEnterEvent(QDragEnterEvent *e);
+ virtual void dropEvent (QDropEvent *o);
+ void droppedfile (KURL::List url);
+private:
+ QPainter *paint;
+ TrayHoverPopup* m_hover_popup;
+ QPixmap m_kt_pix;
+ tork *m_parent;
+
+};
+
+
+class SetMaxRate : public KPopupMenu
+{
+ Q_OBJECT
+ public:
+ SetMaxRate(tork *parent=0, const char *name=0); // type: 0 Upload; 1 Download
+ ~SetMaxRate()
+ {}
+ ;
+
+ void update();
+ private:
+ void makeMenu();
+ tork *m_parent;
+ int m_rate;
+ private slots:
+ void rateSelected(int id);
+};
+
+#endif
diff --git a/src/update.cpp b/src/update.cpp
new file mode 100644
index 0000000..0785526
--- /dev/null
+++ b/src/update.cpp
@@ -0,0 +1,646 @@
+/***************************************************************************
+ * $Id: update.cpp,v 1.26 2008/12/08 19:39:02 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "update.h"
+
+#include <kstaticdeleter.h>
+
+#include <klocale.h>
+#include <kio/netaccess.h>
+
+
+#include <kaction.h>
+
+#include <qcheckbox.h>
+#include <kbuttonbox.h>
+#include <kurlcompletion.h>
+#include <kcombobox.h>
+#include <qlayout.h>
+#include <kmessagebox.h>
+#include <klineedit.h>
+#include <ktempfile.h>
+#include <ksystemtray.h>
+#include <ktar.h>
+#include <kprogress.h>
+#include <kprocio.h>
+#include <knotifyclient.h>
+#include <dom/html_misc.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+#include <kuser.h>
+
+#include <qtimer.h>
+#include <qdir.h>
+#include "version.h"
+
+#include <stdlib.h>
+
+const char *mirrors[] = {
+ "heanet",
+ "internap",
+ "surfnet",
+ "umn",
+ "nchc",
+ "ufpr",
+ "unc",
+ "jaist",
+ "voxel",
+ "citkit",
+ "optusnet",
+ "ovh",
+ "mesh",
+ "easynews",
+ "switch",
+ "kent",
+ "puzzle",
+ 0
+};
+
+TorkUpdate::TorkUpdate(QWidget *parent, const char *name)
+ : QWidget(parent, name),filelist(new KHTMLPart(this))
+{
+
+}
+
+
+TorkUpdate::~TorkUpdate()
+{
+}
+
+
+void TorkUpdate::downloadComponent(QString component, QString version, QString extension)
+{
+
+ upgradeinprogress = true;
+
+ QString location = getenv("HOME");
+
+ location += "/.tork";
+ QDir torkdir(location);
+ if (!torkdir.exists() && !torkdir.mkdir(location))
+ location = getenv("HOME");
+
+ QString currenttor = location + QString("/%1-%2").arg(component).arg(version);
+ QDir tordir(currenttor);
+
+ QString configure;
+ configure = QString("%1/%2-%3/configure").arg(location).arg(component).arg(version);
+
+ QFile configurefile(configure);
+
+ bool download = true;
+
+ if (torkdir.exists() && configurefile.exists()){
+ int result = KMessageBox::questionYesNo(0, i18n( "You seem to have downloaded %1-%2 already (in %3/%4-%5). Would you like to skip re-downloading it and just try to compile it?").arg(component).arg(version).arg(location).arg(component).arg(version),i18n( "Compile %1" ).arg(component));
+
+ switch (result) {
+ case KMessageBox::Yes :
+ download = true;break;
+ case KMessageBox::No :
+ download = false;
+ }
+ }
+
+ QStringList entry;
+ while (download){
+
+ startProgressDialog( i18n( "Downloading %1-%2..." ).arg(component).arg(version) );
+
+ QString dlLocation;
+ QString dlLocationSig;
+ if (component == "tor"){
+ dlLocation = QString("https://torproject.org/dist/%3").arg(highestsofarfilename);
+ dlLocationSig = QString("https://torproject.org/dist/%3.asc").arg(highestsofarfilename);
+ }else if (component == "privoxy")
+ dlLocation = QString("http://%1.dl.sourceforge.net/sourceforge%3").arg(getMirror()).arg(highestsofarfilename);
+ else if (component == "dante")
+ dlLocation = QString("http://www.mirrors.wiretapped.net/security/firewalls/dante/%3").arg(highestsofarfilename);
+ else if (component == "thttpd")
+ dlLocation = QString("http://www.acme.com/software/thttpd/thttpd-2.25b.tar.gz");
+ else if (component == "Mixminion")
+ dlLocation = QString("http://www.mixminion.net/dist/0.0.8alpha3/Mixminion-0.0.8alpha3.tar.gz");
+ else
+ dlLocation = QString("http://%1.dl.sourceforge.net/sourceforge/%2/%3-%4%5").arg(getMirror()).arg(component).arg(component).arg(version).arg(extension);
+
+ QString tmpFile;
+ if ( !KIO::NetAccess::download( dlLocation, tmpFile, 0L ) ){
+ KMessageBox::information (0,i18n("Couldn't download %1.").arg(component));
+ delete timer;
+ timer=0;
+ delete progressDialog;
+ progressDialog = 0;
+ upgradeinprogress = false;
+ return;
+ }
+
+ QString tmpFile2;
+ if (!dlLocationSig.isEmpty()){
+ if ( !KIO::NetAccess::download( dlLocationSig, tmpFile2, 0L ) ){
+ KMessageBox::information (0,i18n("Couldn't download %1 signature file.").arg(component));
+ delete timer;
+ timer=0;
+ delete progressDialog;
+ progressDialog = 0;
+ upgradeinprogress = false;
+ return;
+ }
+ int res = KMessageBox::questionYesNo(0, i18n( "<p>Before proceeding you should verify the source package we have just downloaded. You can copy and paste the commands below into a terminal session such as Konsole.<br>"
+ "<br>"
+ "<b>Step One</b> Import the keys used by the Tor developers to sign the Tor source code:<br>"
+ "<b>gpg --keyserver subkeys.pgp.net --recv-keys 0x28988BF5</b><br>"
+ "<b>gpg --keyserver subkeys.pgp.net --recv-keys 0x165733EA</b><br>"
+ "<br>"
+ "<b>Step Two</b> To verify the source package we have just downloaded:<br>"
+ "<b>gpg --verify %1 %2</b><br>"
+ "<br>"
+ "For further info on what you should expect to see, visit: <b>http://wiki.noreply.org/noreply/TheOnionRouter/VerifyingSignatures</b>"
+ "<br>"
+ "<br> Are you happy that the source file is authentic?</p>").arg(tmpFile2).arg(tmpFile));
+ switch (res) {
+ case KMessageBox::Yes :
+ break;
+ case KMessageBox::No :
+ default:
+ updateCanceled();
+ delete progressDialog;
+ progressDialog = 0;
+ return;
+ return;
+ }
+
+ }
+
+ if ((progressDialog) && (progressDialog->wasCancelled())){
+ updateCanceled();
+ return;
+ }
+
+
+
+ progressDialog->setLabel( i18n( "Unpacking %1-%2 to %3/%4-%5" ).arg(component).arg(version).arg(location).arg(component).arg(version));
+
+ // unpack the tarball
+ KTar tar( tmpFile );
+ if (!(tar.open( IO_ReadOnly ))){
+ int result = KMessageBox::questionYesNo(0, i18n( "The mirror I attempted to download from has not updated yet. Should I try another?"));
+ switch (result) {
+ case KMessageBox::Yes :
+ download = true; break;
+ case KMessageBox::No :
+ download = false;
+ default:
+ download = false;
+ }
+ }else{
+ download = false;
+ }
+ tar.directory()->copyTo( location );
+ entry = tar.directory()->entries();
+ tar.close();
+ // remove the temp file
+ //KIO::NetAccess::removeTempFile( tmpFile );
+
+ delete timer;
+ timer=0;
+ delete progressDialog;
+ progressDialog = 0;
+ }
+
+// if ((progressDialog) && (progressDialog->wasCancelled())){
+// updateCanceled();
+// delete progressDialog;
+// progressDialog = 0;
+// return;
+// }
+
+ //KTar does not honour executable permissions
+
+ if (component == "privoxy"){
+ configure = QString("%1/%2/").arg(location).arg(entry.first());
+ configurefile.setName(configure+"configure.in");
+ }
+
+ if (component == "Mixminion"){
+ configure = QString("%1/%2/").arg(location).arg(entry.first());
+ configurefile.setName(configure+"README");
+ }
+
+ if (torkdir.exists() && configurefile.exists()){
+
+ chmod((const char *)configure,0700);
+
+ int result = KMessageBox::warningContinueCancel(0, i18n( "%1-%2 is ready for compiling and installation. Would you like the wizard to ask you for the root password so it can compile and install it for you? (If not, you can compile it yourself later at %3/%4-%5)").arg(component).arg(version).arg(location).arg(component).arg(version),i18n( "Install %1-%2" ).arg(component).arg(version),i18n( "Use the Wizard" ));
+
+ switch (result) {
+ case 2 :
+ KMessageBox::information (0,i18n("Installation of %1 Cancelled.").arg(component));
+ upgradeinprogress = false;
+ break;
+ case 5 :
+
+ KProcess* arkollonproc = new KShellProcess();
+
+ KMessageBox::information (this,i18n( "<p><b>If this the first time you've compiled software then here are a few useful tips:</b><br>"
+ "1. Any error messages in the log file with the words 'KDE', 'Qt','curl' or 'X' in them mean that you need to install "
+ "the appropriate development libraries.<br>"
+ "2. Any package provided by your distribution with 'lib' or 'devel' in the name is a development library, e.g. qt-devel, libkde.<br>"
+ "</p>" ),"Compilation Tips","compiler");
+
+ QString command;
+ if (component == "Mixminion")
+ command = QString("kdesu -i tork -c 'xterm -hold -e \"cd %1;make install;printf \\\"If there were errors try downloading and installing Mixminion from the Mixminion homepage. If the installation looks successful try sending an anonymous mail to yourself. Close the window to continue.\\\"\"'").arg(configure);
+ else if (component == "privoxy")
+ command = QString("cd %1; autoheader;autoconf;torkarkollon %2").arg(configure).arg(configure);
+ else
+ command = QString("torkarkollon %1/%2-%3").arg(location).arg(component).arg(version);
+
+ *arkollonproc << command;
+
+ connect( arkollonproc, SIGNAL(processExited(KProcess *)), SLOT(torkInstallationExited(KProcess *)) );
+ arkollonproc->start();
+ }
+ }
+
+}
+
+void TorkUpdate::downloadThttpd()
+{
+/* startProgressDialog( i18n( "Downloading thttpd..." ) );*/
+ downloadComponent("thttpd", "2.25b", "tar.gz");
+}
+
+void TorkUpdate::downloadMixminion()
+{
+/* startProgressDialog( i18n( "Downloading thttpd..." ) );*/
+ downloadComponent("Mixminion", "0.0.8alpha3", "tar.gz");
+}
+
+void TorkUpdate::checkForNewTork()
+{
+
+ highestsofarnumeric = 0;
+ tork_url = "http://prdownloads.sourceforge.net/tork/";
+ getLatestVersionFromSFHack(tork_url);
+
+}
+
+void TorkUpdate::checkForNewPrivoxyDirectly()
+{
+
+ checkingDirectly = true;
+
+ highestsofarnumeric = 0;
+ tork_url = "http://prdownloads.sourceforge.net/ijbswa/";
+ startProgressDialog( i18n( "Checking for new version of Privoxy..." ) );
+
+ getLatestVersionFromSF(tork_url);
+
+}
+
+void TorkUpdate::checkForNewTorkDirectly()
+{
+
+ checkingDirectly = true;
+
+ highestsofarnumeric = 0;
+ tork_url = "http://downloadtork.anonymityanywhere.com/";
+ startProgressDialog( i18n( "Checking for new version of Tork..." ) );
+
+ getLatestVersionFromSF(tork_url);
+
+}
+
+
+void TorkUpdate::checkForNewTorDirectly(bool alpha)
+{
+
+ checkingDirectly = true;
+ m_alpha=alpha;
+ highestsofarnumeric = 0;
+ tork_url = "http://torproject.org/dist/";
+
+ startProgressDialog( i18n( "Checking for new version of Tor..." ) );
+
+ getLatestVersionFromSF(tork_url);
+
+}
+
+void TorkUpdate::checkForNewDanteDirectly()
+{
+
+ checkingDirectly = true;
+
+ highestsofarnumeric = 0;
+ tork_url = "http://www.mirrors.wiretapped.net/security/firewalls/dante/";
+
+ startProgressDialog( i18n( "Checking for new version of Dante..." ) );
+
+ getLatestVersionFromSF(tork_url);
+
+}
+
+void TorkUpdate::completedSearchForUpdates(const QString &component, const QString &extension)
+{
+
+ double currentversion;
+
+
+ if (component == "Tork")
+ currentversion = VERSION_TORK;
+ else{
+ if (currentTorVersion.mid(currentTorVersion.length() - 2,1) == ".")
+ currentversion = currentTorVersion.replace(currentTorVersion.length() - 2,1,"").toDouble();
+ else
+ currentversion = currentTorVersion.toDouble();
+ }
+
+ if (highestsofarnumeric > currentversion){
+ int result = KMessageBox::warningContinueCancel(0, i18n( "The newest version of %1 available is %2-%3. Would you like Tork to download and compile it for you?").arg(component).arg(component).arg(highestsofarraw),i18n( "Download and Install %1-%2" ).arg(component).arg(highestsofarraw),i18n( "Download and Install %1-%2" ).arg(component).arg(highestsofarraw));
+
+ switch (result) {
+ case 2 :
+ break;
+ case 5 :
+ downloadComponent(component.lower(), highestsofarraw, extension);
+ }
+ }else if (checkingDirectly){
+ KMessageBox::information (this,i18n("Your installation of %1 is already up-to-date!").arg(component));
+ }
+ checkingDirectly = false;
+ m_alpha=false;
+// tork_options->setEnabled(true);
+// tork_options->setEnabled(true);
+
+// if (filelist)
+// filelist->deleteLater();
+
+}
+
+
+
+void TorkUpdate::startProgressDialog( const QString & text )
+{
+
+
+ progressDialog = new KProgressDialog( 0, "progress_dialog", QString::null, text, false );
+
+ progressDialog->setAllowCancel( true );
+ progressDialog->showCancelButton( true );
+ progressDialog->setPlainCaption( i18n( "Please Wait" ) );
+
+ progressDialog->progressBar()->setTotalSteps( 0 );
+ progressDialog->progressBar()->setPercentageVisible( false );
+
+ progressDialog->setMinimumDuration( 500 );
+ progressDialog->show();
+
+ connect( progressDialog, SIGNAL( cancelClicked() ), this,
+ SLOT( updateCanceled() ) );
+
+ timer = new QTimer( this );
+ connect( timer, SIGNAL( timeout() ), this, SLOT( slotProg() ) );
+
+ timer->start( 200, FALSE );
+}
+
+void TorkUpdate::slotProg()
+{
+
+ if (progressDialog)
+ progressDialog->progressBar()->setProgress(progressDialog->progressBar()->progress() + 4 );
+}
+
+
+void TorkUpdate::torkInstallationExited(KProcess* arkollonproc)
+{
+
+ arkollonproc = 0;
+ delete arkollonproc;
+ upgradeinprogress = false;
+
+ KMessageBox::information (this,i18n( "If the installation completed successfully you should restart the component for the new version to take effect." ));
+
+}
+
+void
+TorkUpdate::checkInternet() //SLOT
+{
+ m_url.setHost( "prdownloads.sourceforge.net" );
+ if ( !m_url.port() ) m_url.setPort( 80 );
+
+ connect( &m_resolver, SIGNAL( finished( KResolverResults ) ), SLOT( resolved( KResolverResults ) ) );
+ connectToHost();
+}
+
+void
+TorkUpdate::connectToHost() //SLOT
+{
+ m_resolver.setNodeName( m_url.host() );
+ m_resolver.setFamily( KResolver::InetFamily );
+ m_resolver.start();
+}
+
+
+void
+TorkUpdate::resolved( KResolverResults result) // SLOT
+{
+ if ((!( result.error() != KResolver::NoError || result.isEmpty() ))
+ /*&& tork_box->isChecked()*/)
+ checkForNewTork();
+ else
+ kdDebug() << "network error or not set to check for new tork" << endl;
+}
+
+
+
+void TorkUpdate::getLatestVersionFromSF(KURL url)
+{
+
+ connect( filelist, SIGNAL( completed() ), this,
+ SLOT( parseSFPage() ) );
+
+ filelist->setStatusMessagesEnabled(false);
+ filelist->openURL(url);
+
+}
+
+void TorkUpdate::getLatestVersionFromSFHack(KURL url)
+{
+
+
+ if (!filelist)
+ filelist = new KHTMLPart();
+
+ connect( filelist, SIGNAL( completed() ), this,
+ SLOT( parseSFPageHack() ) );
+
+ filelist->setStatusMessagesEnabled(false);
+ filelist->openURL(url);
+
+}
+
+
+
+void TorkUpdate::updateCanceled()
+{
+
+ filelist->closeURL();
+// tork_options->setEnabled(true);
+// tork_options->setEnabled(true);
+
+}
+
+void TorkUpdate::parseSFPage()
+{
+
+ const DOM::HTMLCollection links = filelist->htmlDocument().links();
+
+ if (links.length() == 0){
+ KMessageBox::information (this,i18n( "Could not contact update server!" ));
+ updateCanceled();
+ delete progressDialog;
+ progressDialog = 0;
+ return;
+ }
+
+ disconnect( filelist, SIGNAL( completed() ), this,
+ SLOT( parseSFPage() ) );
+
+ for (unsigned int j=0; j != links.length(); j++ ){
+ const DOM::Node linkNode = links.item( j );
+ getVersionFromLink( linkNode );
+ }
+
+ delete progressDialog;
+ progressDialog = 0;
+
+ if (highestsofarfilename.contains("tork"))
+ completedSearchForUpdates("Tork", ".tar.bz2");
+ else if (highestsofarfilename.contains("tor"))
+ completedSearchForUpdates("Tor", ".tar.gz");
+ else if (highestsofarfilename.contains("privoxy"))
+ completedSearchForUpdates("Privoxy", ".tar.gz");
+ else if (highestsofarfilename.contains("dante"))
+ completedSearchForUpdates("Dante", ".tar.gz");
+
+
+}
+
+void TorkUpdate::parseSFPageHack()
+{
+
+ const DOM::HTMLCollection links = filelist->htmlDocument().links();
+
+ if (links.length() == 0){
+ return;
+ }
+
+ disconnect( filelist, SIGNAL( completed() ), this,
+ SLOT( parseSFPageHack() ) );
+
+ for (unsigned int j=0; j != links.length(); j++ ){
+ const DOM::Node linkNode = links.item( j );
+ getVersionFromLink( linkNode );
+ }
+
+ //delete progressDialog;
+ //progressDialog = 0;
+
+ if (highestsofarfilename.contains("tork"))
+ completedSearchForUpdates("Tork", "tar.bz2");
+ else if (highestsofarfilename.contains("tor"))
+ completedSearchForUpdates("Tor", "tar.gz");
+
+
+}
+
+
+void TorkUpdate::getVersionFromLink( const DOM::Node &n )
+{
+ double numericversion;
+ QString tmpversion;
+
+ if ( n.isNull() || n.nodeType() != DOM::Node::ELEMENT_NODE )
+ return;
+
+ DOM::Element elem = static_cast<DOM::Element>( n );
+
+ KURL href ( elem.getAttribute( "href" ).string() );
+
+ QString name = elem.getAttribute( "href" ).string();
+ QString version = name.replace(".tar.bz2","").replace(".tar.gz","");
+ version = version.replace("tork-","").replace("tor-","")
+ .replace("/ijbswa/privoxy-","")
+ .replace("-stable-src","")
+ .replace("dante-","");
+
+ QString rawversion = version;
+ if (m_alpha) {
+ version.remove("-alpha").remove("-beta").remove("-rc");
+ }
+ numericversion = numericizeVersion(version);
+
+ if (numericversion > highestsofarnumeric){
+ highestsofarnumeric = numericversion;
+ highestsofarraw = rawversion;
+ highestsofarfilename = elem.getAttribute( "href" ).string();
+ }
+
+
+}
+
+QString TorkUpdate::getMirror()
+{
+ int r = 1+(int) (16.0*rand()/(RAND_MAX+1.0));
+ static int previousmirror = 0;
+
+ while (r == previousmirror)
+ r=1+(int) (16.0*rand()/(RAND_MAX+1.0));
+
+ previousmirror = r;
+
+ return mirrors[r];
+}
+
+double TorkUpdate::numericizeVersion(QString &version)
+{
+ QString tmpversion = version;
+ QStringList tokens = QStringList::split(".",tmpversion);
+ for ( QStringList::Iterator it = tokens.begin(); it != tokens.end(); it++ )
+ {
+ if ((*it).length() < 2)
+ (*it).prepend("0");
+ }
+ tmpversion = tokens.join(".");
+
+ unsigned int firstdot = tmpversion.find(".");
+ for (unsigned int j=tmpversion.length(); j != firstdot; j-- ){
+ if (tmpversion.mid(j,1) == "."){
+ tmpversion.remove(j,1);
+ j--;
+ }
+ }
+
+ return tmpversion.toDouble();
+}
+#include "update.moc"
+
+// forward-socks4a / localhost:9050 .
diff --git a/src/update.h b/src/update.h
new file mode 100644
index 0000000..1b3f35f
--- /dev/null
+++ b/src/update.h
@@ -0,0 +1,127 @@
+/***************************************************************************
+ * $Id: update.h,v 1.13 2008/12/08 19:39:02 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#ifndef _UPDATE_H_
+#define _UPDATE_H_
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <kapplication.h>
+#include <kdirlister.h> //stack allocated
+#include <kurl.h> //stack allocated
+#include <kresolver.h> // namespace
+#include <khtml_part.h>
+
+
+namespace DOM {
+ class Node;
+}
+
+
+using namespace KNetwork;
+
+class KURL;
+class KProcess;
+class KURLRequester;
+class KProgressDialog;
+class KProcIO;
+class KHTMLPart;
+
+/**
+ * This class serves as the main window for TorkUpdate. It handles the
+ * menus, toolbars, and status bars.
+ *
+ * @short Main window class
+ * @author $AUTHOR <$EMAIL>
+ * @version $APP_VERSION
+ */
+class TorkUpdate : public QWidget
+{
+ Q_OBJECT
+
+ public:
+
+ TorkUpdate(QWidget *parent, const char *name=0);
+
+ /**
+ * Default Destructor
+ */
+ virtual ~TorkUpdate();
+
+
+
+public slots:
+ void checkForNewTorDirectly(bool alpha);
+ void checkForNewDanteDirectly();
+ void checkForNewPrivoxyDirectly();
+ void checkForNewTorkDirectly();
+ void downloadThttpd();
+ void downloadMixminion();
+
+
+private slots:
+ void slotProg();
+ void torkInstallationExited(KProcess *arkollonproc);
+ void resolved(KResolverResults result);
+ void parseSFPage();
+ void parseSFPageHack();
+ void updateCanceled();
+private:
+ void getLatestVersionFromSF(KURL url);
+ void getLatestVersionFromSFHack(KURL url);
+ void downloadComponent(QString component, QString version, QString extension);
+ void startProgressDialog( const QString & text );
+ void checkInternet();
+ void connectToHost();
+ void checkForNewTork();
+ void getVersionFromLink( const DOM::Node &n );
+ void completedSearchForUpdates(const QString &component, const QString &extension);
+ double numericizeVersion(QString &version);
+ QString getMirror();
+ KProcess *childproc;
+ KProcIO *versionproc;
+ QString tempFileName;
+ QString errorMessage;
+ QString pidFileName;
+ KProgressDialog *progressDialog;
+ QTimer *timer;
+ bool upgradeinprogress;
+ bool checkingDirectly;
+ double highestsofarnumeric;
+ QString highestsofarraw;
+ QString highestsofarfilename;
+ KResolver m_resolver;
+ QString currentTorVersion;
+ bool m_alpha;
+ KHTMLPart *filelist;
+private:
+ KDirLister tor_lister;
+ KURL tor_url;
+ KDirLister tork_lister;
+ KURL tork_url;
+ KURL m_url;
+
+};
+
+#endif // _TorkUpdate_H_
diff --git a/src/upnp/Makefile.am b/src/upnp/Makefile.am
new file mode 100644
index 0000000..97a2708
--- /dev/null
+++ b/src/upnp/Makefile.am
@@ -0,0 +1,14 @@
+METASOURCES = AUTO
+INCLUDES = $(all_includes)
+
+libktupnp_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libktupnp.la
+libktupnp_la_SOURCES = soap.cpp upnpdescriptionparser.cpp upnpmcastsocket.cpp \
+ upnprouter.cpp portlist.cpp httprequest.cpp exitoperation.cpp \
+ forwardportlist.cpp
+
+noinst_HEADERS = upnpmcastsocket.h upnprouter.h \
+ upnpdescriptionparser.h soap.h
+
+
+KDE_CXXFLAGS = $(USE_EXCEPTIONS) $(USE_RTTI)
diff --git a/src/upnp/exitoperation.cpp b/src/upnp/exitoperation.cpp
new file mode 100644
index 0000000..8eedb7a
--- /dev/null
+++ b/src/upnp/exitoperation.cpp
@@ -0,0 +1,47 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "exitoperation.h"
+
+namespace kt
+{
+
+ ExitOperation::ExitOperation()
+ {}
+
+
+ ExitOperation::~ExitOperation()
+ {}
+
+ ExitJobOperation::ExitJobOperation(KIO::Job* j)
+ {
+ connect(j,SIGNAL(result(KIO::Job*)),this,SLOT(onResult( KIO::Job* )));
+ }
+
+ ExitJobOperation::~ExitJobOperation()
+ {
+ }
+
+ void ExitJobOperation::onResult(KIO::Job* )
+ {
+ operationFinished(this);
+ }
+
+}
+#include "exitoperation.moc"
diff --git a/src/upnp/exitoperation.h b/src/upnp/exitoperation.h
new file mode 100644
index 0000000..edaa2fa
--- /dev/null
+++ b/src/upnp/exitoperation.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef KTEXITOPERATION_H
+#define KTEXITOPERATION_H
+
+#include <qobject.h>
+#include <kio/job.h>
+
+namespace kt
+{
+
+ /**
+ * @author Joris Guisson <joris.guisson@gmail.com>
+ *
+ * Object to derive from for operations which need to be performed at exit.
+ * The operation should emit the operationFinished signal when they are done.
+ *
+ * ExitOperation's can be used in combination with a WaitJob, to wait for a certain amount of time
+ * to give serveral ExitOperation's the time time to finish up.
+ */
+ class ExitOperation : public QObject
+ {
+ Q_OBJECT
+ public:
+ ExitOperation();
+ virtual ~ExitOperation();
+
+ /// wether or not we can do a deleteLater on the job after it has finished.
+ virtual bool deleteAllowed() const {return true;}
+ signals:
+ void operationFinished(kt::ExitOperation* opt);
+ };
+
+ /**
+ * Exit operation which waits for a KIO::Job
+ */
+ class ExitJobOperation : public ExitOperation
+ {
+ Q_OBJECT
+ public:
+ ExitJobOperation(KIO::Job* j);
+ virtual ~ExitJobOperation();
+
+ virtual bool deleteAllowed() const {return false;}
+ private slots:
+ virtual void onResult(KIO::Job* j);
+ };
+}
+
+#endif
diff --git a/src/upnp/forwardportlist.cpp b/src/upnp/forwardportlist.cpp
new file mode 100644
index 0000000..906bde3
--- /dev/null
+++ b/src/upnp/forwardportlist.cpp
@@ -0,0 +1,83 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "forwardportlist.h"
+#include <kdebug.h>
+namespace net
+{
+ ForwardPort::ForwardPort() : extnumber(0),intnumber(0),proto(TCP),forward(false)
+ {
+ }
+
+ ForwardPort::ForwardPort(bt::Uint16 extnumber,bt::Uint16 intnumber,Protocol proto,bool forward)
+ : extnumber(extnumber),intnumber(intnumber),proto(proto),forward(forward)
+ {
+ }
+
+ ForwardPort::ForwardPort(const ForwardPort & p) : extnumber(p.extnumber),
+ intnumber(p.intnumber),proto(p.proto),forward(p.forward)
+ {
+ }
+
+
+ bool ForwardPort::operator == (const ForwardPort & p) const
+ {
+ return extnumber == p.extnumber && intnumber == p.intnumber && proto == p.proto;
+ }
+
+ ForwardPortList::ForwardPortList() : lst(0)
+ {}
+
+
+ ForwardPortList::~ForwardPortList()
+ {}
+
+
+ void ForwardPortList::addNewForwardPort(bt::Uint16 extnumber,bt::Uint16 intnumber,Protocol proto,
+ bool forward)
+ {
+ kdDebug() << "adding forward port" << endl;
+
+ ForwardPort p = ForwardPort(extnumber,intnumber,proto,forward);
+ append(p);
+ if (lst)
+ lst->portAdded(p);
+ kdDebug() << "added forward port" << endl;
+
+ }
+
+
+ void ForwardPortList::removeForwardPort(bt::Uint16 extnumber,bt::Uint16 intnumber,Protocol proto)
+ {
+ kdDebug() << "removing forward port" << endl;
+ ForwardPortList::iterator itr = find(ForwardPort(extnumber,intnumber,proto,false));
+ if (itr == end())
+ return;
+
+ if (lst)
+ lst->portRemoved(*itr);
+
+ erase(itr);
+ kdDebug() << "removed forward port" << endl;
+
+ }
+
+
+
+}
diff --git a/src/upnp/forwardportlist.h b/src/upnp/forwardportlist.h
new file mode 100644
index 0000000..2a27f59
--- /dev/null
+++ b/src/upnp/forwardportlist.h
@@ -0,0 +1,101 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef FORWARDPORTLIST_H
+#define FORWARDPORTLIST_H
+
+#include <qvaluelist.h>
+#include "../constants.h"
+#include "portlist.h"
+
+namespace net
+{
+
+
+ struct ForwardPort
+ {
+ bt::Uint16 extnumber;
+ bt::Uint16 intnumber;
+ Protocol proto;
+ bool forward;
+
+ ForwardPort();
+ ForwardPort(bt::Uint16 extnumber,bt::Uint16 intnumber,Protocol proto,bool forward);
+ ForwardPort(const ForwardPort & p);
+
+ bool operator == (const ForwardPort & p) const;
+ };
+
+ /**
+ * Listener class for the ForwardPortList.
+ */
+ class ForwardPortListener
+ {
+ public:
+ /**
+ * A port has been added.
+ * @param port The port
+ */
+ virtual void portAdded(const ForwardPort & port) = 0;
+
+ /**
+ * A port has been removed
+ * @param port The port
+ */
+ virtual void portRemoved(const ForwardPort & port) = 0;
+ };
+
+ /**
+ * @author Joris Guisson <joris.guisson@gmail.com>
+ *
+ * List of ports which are currently being used.
+ *
+ */
+ class ForwardPortList : public QValueList<ForwardPort>
+ {
+ ForwardPortListener* lst;
+ public:
+ ForwardPortList();
+ virtual ~ForwardPortList();
+
+ /**
+ * When a port is in use, this function needs to be called.
+ * @param number ForwardPort number
+ * @param proto Protocol
+ * @param forward Wether or not it needs to be forwarded
+ */
+ void addNewForwardPort(bt::Uint16 extnumber,bt::Uint16 intnumber,Protocol proto,bool forward);
+
+ /**
+ * Needs to be called when a port is not being using anymore.
+ * @param number ForwardPort number
+ * @param proto Protocol
+ */
+ void removeForwardPort(bt::Uint16 extnumber,bt::Uint16 intnumber,Protocol proto);
+
+ /**
+ * Set the port listener.
+ * @param pl ForwardPort listener
+ */
+ void setListener(ForwardPortListener* pl) {lst = pl;}
+ };
+
+}
+
+#endif
diff --git a/src/upnp/httprequest.cpp b/src/upnp/httprequest.cpp
new file mode 100644
index 0000000..5a612b0
--- /dev/null
+++ b/src/upnp/httprequest.cpp
@@ -0,0 +1,123 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <qstringlist.h>
+#include "httprequest.h"
+#include "../functions.h"
+#include <kdebug.h>
+#include <ksocks.h>
+
+
+namespace bt
+{
+
+ HTTPRequest::HTTPRequest(const QString & hdr,const QString & payload,const QString & host,Uint16 port,bool verbose, bool fwd) : hdr(hdr),payload(payload),verbose(verbose),fwd(fwd)
+ {
+ KSocks::self()->disableSocks();
+ sock = new KNetwork::KStreamSocket(host,QString::number(port),this,0);
+ sock->enableRead(true);
+ sock->enableWrite(true);
+ sock->setTimeout(30000);
+ sock->setBlocking(false);
+ connect(sock,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
+ connect(sock,SIGNAL(gotError(int)),this,SLOT(onError(int )));
+ connect(sock,SIGNAL(timedOut()),this,SLOT(onTimeout()));
+ connect(sock,SIGNAL(connected(const KResolverEntry&)),
+ this, SLOT(onConnect( const KResolverEntry& )));
+ }
+
+
+ HTTPRequest::~HTTPRequest()
+ {
+ sock->close();
+ delete sock;
+ }
+
+ void HTTPRequest::start()
+ {
+ sock->connect();
+ }
+
+ void HTTPRequest::onConnect(const KResolverEntry&)
+ {
+ payload = payload.replace("$LOCAL_IP",sock->localAddress().nodeName());
+ hdr = hdr.replace("$CONTENT_LENGTH",QString::number(payload.length()));
+
+ QString req = hdr + payload;
+/* if (verbose)
+ {
+ KdDebug() << "Sending " << endl;
+ KdDebug() << hdr << payload << endl;
+ }*/
+ sock->writeBlock(req.ascii(),req.length());
+ }
+
+ void HTTPRequest::onReadyRead()
+ {
+ Uint32 ba = sock->bytesAvailable();
+ if (ba == 0)
+ {
+ error(this,false);
+ sock->close();
+ return;
+ }
+
+ Array<char> data(ba);
+ ba = sock->readBlock(data,ba);
+ QString strdata((const char*)data);
+ QStringList sl = QStringList::split("\r\n",strdata,false);
+
+/* if (verbose)
+ {
+ KdDebug() << "Got reply : " << endl;
+ KdDebug() << strdata << endl;
+ }*/
+
+ if (sl.first().contains("HTTP") && sl.first().contains("200"))
+ {
+ // emit reply OK
+ replyOK(this,sl.last(),fwd);
+ }
+ else
+ {
+ // emit reply error
+ replyError(this,sl.last(),fwd);
+ }
+ operationFinished(this);
+ }
+
+ void HTTPRequest::onError(int)
+ {
+ kdDebug() << "HTTPRequest error : " << sock->errorString() << endl;
+ error(this,false);
+ sock->close();
+ operationFinished(this);
+ }
+
+ void HTTPRequest::onTimeout()
+ {
+ kdDebug() << "HTTPRequest timeout" << endl;
+ error(this,true);
+ sock->close();
+ operationFinished(this);
+ }
+
+
+}
+#include "httprequest.moc"
diff --git a/src/upnp/httprequest.h b/src/upnp/httprequest.h
new file mode 100644
index 0000000..9832da8
--- /dev/null
+++ b/src/upnp/httprequest.h
@@ -0,0 +1,98 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef BTHTTPREQUEST_H
+#define BTHTTPREQUEST_H
+
+#include <qobject.h>
+#include <kurl.h>
+#include <kstreamsocket.h>
+#include "exitoperation.h"
+#include "../constants.h"
+
+using KNetwork::KResolverEntry;
+
+namespace bt
+{
+
+ /**
+ * @author Joris Guisson
+ *
+ * Just create one, fill in the fields,
+ * connect to the right signals and forget about it. After the reply has been received or
+ * an error occurred, the appropriate signal will be emitted.
+ */
+ class HTTPRequest : public kt::ExitOperation
+ {
+ Q_OBJECT
+ public:
+ /**
+ * Constructor, set the url and the request header.
+ * @param hdr The http request header
+ * @param payload The payload
+ * @param host The host
+ * @param port THe port
+ * @param verbose Print traffic to the log
+ */
+ HTTPRequest(const QString & hdr,const QString & payload,const QString & host,
+ Uint16 port,bool verbose, bool fwd);
+ virtual ~HTTPRequest();
+
+ /**
+ * Open a connetion and send the request.
+ */
+ void start();
+ QString showPayload(){return payload;};
+ signals:
+ /**
+ * An OK reply was sent.
+ * @param r The sender of the request
+ * @param data The data of the reply
+ */
+ void replyOK(bt::HTTPRequest* r,const QString & data, bool fwd);
+
+ /**
+ * Anything else but an 200 OK was sent.
+ * @param r The sender of the request
+ * @param data The data of the reply
+ */
+ void replyError(bt::HTTPRequest* r,const QString & data, bool fwd);
+
+ /**
+ * No reply was sent and an error or timeout occurred.
+ * @param r The sender of the request
+ * @param timeout Wether or not a timeout occurred
+ */
+ void error(bt::HTTPRequest* r,bool timeout);
+
+ private slots:
+ void onReadyRead();
+ void onError(int);
+ void onTimeout();
+ void onConnect(const KResolverEntry&);
+
+ private:
+ KNetwork::KStreamSocket* sock;
+ QString hdr,payload;
+ bool verbose,fwd;
+ };
+
+}
+
+#endif
diff --git a/src/upnp/portlist.cpp b/src/upnp/portlist.cpp
new file mode 100644
index 0000000..56076ed
--- /dev/null
+++ b/src/upnp/portlist.cpp
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "portlist.h"
+
+namespace net
+{
+ Port::Port() : number(0),proto(TCP),forward(false)
+ {
+ }
+
+ Port::Port(bt::Uint16 number,Protocol proto,bool forward)
+ : number(number),proto(proto),forward(forward)
+ {
+ }
+
+ Port::Port(const Port & p) : number(p.number),proto(p.proto),forward(p.forward)
+ {
+ }
+
+ bool Port::operator == (const Port & p) const
+ {
+ return number == p.number && proto == p.proto;
+ }
+
+ PortList::PortList() : lst(0)
+ {}
+
+
+ PortList::~PortList()
+ {}
+
+
+ void PortList::addNewPort(bt::Uint16 number,Protocol proto,bool forward)
+ {
+ Port p = Port(number,proto,forward);
+ append(p);
+ if (lst)
+ lst->portAdded(p);
+ }
+
+
+ void PortList::removePort(bt::Uint16 number,Protocol proto)
+ {
+ PortList::iterator itr = find(Port(number,proto,false));
+ if (itr == end())
+ return;
+
+ if (lst)
+ lst->portRemoved(*itr);
+
+ erase(itr);
+ }
+
+
+
+}
diff --git a/src/upnp/portlist.h b/src/upnp/portlist.h
new file mode 100644
index 0000000..5063b78
--- /dev/null
+++ b/src/upnp/portlist.h
@@ -0,0 +1,103 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef NETPORTLIST_H
+#define NETPORTLIST_H
+
+#include <qvaluelist.h>
+#include "../constants.h"
+
+namespace net
+{
+ enum Protocol
+ {
+ TCP,
+ UDP
+ };
+
+ struct Port
+ {
+ bt::Uint16 number;
+ Protocol proto;
+ bool forward;
+
+ Port();
+ Port(bt::Uint16 number,Protocol proto,bool forward);
+ Port(const Port & p);
+
+ bool operator == (const Port & p) const;
+ };
+
+ /**
+ * Listener class for the PortList.
+ */
+ class PortListener
+ {
+ public:
+ /**
+ * A port has been added.
+ * @param port The port
+ */
+ virtual void portAdded(const Port & port) = 0;
+
+ /**
+ * A port has been removed
+ * @param port The port
+ */
+ virtual void portRemoved(const Port & port) = 0;
+ };
+
+ /**
+ * @author Joris Guisson <joris.guisson@gmail.com>
+ *
+ * List of ports which are currently being used.
+ *
+ */
+ class PortList : public QValueList<Port>
+ {
+ PortListener* lst;
+ public:
+ PortList();
+ virtual ~PortList();
+
+ /**
+ * When a port is in use, this function needs to be called.
+ * @param number Port number
+ * @param proto Protocol
+ * @param forward Wether or not it needs to be forwarded
+ */
+ void addNewPort(bt::Uint16 number,Protocol proto,bool forward);
+
+ /**
+ * Needs to be called when a port is not being using anymore.
+ * @param number Port number
+ * @param proto Protocol
+ */
+ void removePort(bt::Uint16 number,Protocol proto);
+
+ /**
+ * Set the port listener.
+ * @param pl Port listener
+ */
+ void setListener(PortListener* pl) {lst = pl;}
+ };
+
+}
+
+#endif
diff --git a/src/upnp/soap.cpp b/src/upnp/soap.cpp
new file mode 100644
index 0000000..b155b55
--- /dev/null
+++ b/src/upnp/soap.cpp
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include "soap.h"
+
+namespace kt
+{
+
+ QString SOAP::createCommand(const QString & action,const QString & service)
+ {
+ QString comm = QString("<?xml version=\"1.0\"?>\r\n"
+ "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
+ "<SOAP-ENV:Body>"
+ "<m:%1 xmlns:m=\"%2\"/>"
+ "</SOAP-ENV:Body></SOAP-ENV:Envelope>"
+ "\r\n").arg(action).arg(service);
+
+ return comm;
+ }
+
+ QString SOAP::createCommand(const QString & action,const QString & service,const QValueList<Arg> & args)
+ {
+ QString comm = QString("<?xml version=\"1.0\"?>\r\n"
+ "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
+ "<SOAP-ENV:Body>"
+ "<m:%1 xmlns:m=\"%2\">").arg(action).arg(service);
+
+ for (QValueList<Arg>::const_iterator i = args.begin();i != args.end();i++)
+ {
+ const Arg & a = *i;
+ comm += "<" + a.element + ">" + a.value + "</" + a.element + ">";
+ }
+
+ comm += QString("</m:%1></SOAP-ENV:Body></SOAP-ENV:Envelope>\r\n").arg(action);
+ return comm;
+ }
+}
diff --git a/src/upnp/soap.h b/src/upnp/soap.h
new file mode 100644
index 0000000..c11e2ed
--- /dev/null
+++ b/src/upnp/soap.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef KTSOAP_H
+#define KTSOAP_H
+
+#include <qvaluelist.h>
+#include <qstring.h>
+
+namespace kt
+{
+
+ /**
+ @author Joris Guisson
+ */
+ class SOAP
+ {
+ public:
+
+ /**
+ * Create a simple UPnP SOAP command without parameters.
+ * @param action The name of the action
+ * @param service The name of the service
+ * @return The command
+ */
+ static QString createCommand(const QString & action,const QString & service);
+
+ struct Arg
+ {
+ QString element;
+ QString value;
+ };
+
+ /**
+ * Create a UPnP SOAP command with parameters.
+ * @param action The name of the action
+ * @param service The name of the service
+ * @param args Arguments for command
+ * @return The command
+ */
+ static QString createCommand(const QString & action,const QString & service,const QValueList<Arg> & args);
+ };
+
+}
+
+#endif
diff --git a/src/upnp/upnpdescriptionparser.cpp b/src/upnp/upnpdescriptionparser.cpp
new file mode 100644
index 0000000..f27b6cd
--- /dev/null
+++ b/src/upnp/upnpdescriptionparser.cpp
@@ -0,0 +1,220 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <qxml.h>
+#include <qvaluestack.h>
+// #include <util/fileops.h>
+#include <kdebug.h>
+// #include <torrent/globals.h>
+#include "upnprouter.h"
+#include "upnpdescriptionparser.h"
+
+using namespace bt;
+
+namespace kt
+{
+
+ class XMLContentHandler : public QXmlDefaultHandler
+ {
+ enum Status
+ {
+ TOPLEVEL,ROOT,DEVICE,SERVICE,FIELD,OTHER
+ };
+
+ QString tmp;
+ UPnPRouter* router;
+ UPnPService curr_service;
+ QValueStack<Status> status_stack;
+ public:
+ XMLContentHandler(UPnPRouter* router);
+ virtual ~XMLContentHandler();
+
+
+ bool startDocument();
+ bool endDocument();
+ bool startElement(const QString &, const QString & localName, const QString &,
+ const QXmlAttributes & atts);
+ bool endElement(const QString & , const QString & localName, const QString & );
+ bool characters(const QString & ch);
+
+ bool interestingDeviceField(const QString & name);
+ bool interestingServiceField(const QString & name);
+ };
+
+
+ UPnPDescriptionParser::UPnPDescriptionParser()
+ {}
+
+
+ UPnPDescriptionParser::~UPnPDescriptionParser()
+ {}
+
+ bool UPnPDescriptionParser::parse(const QString & file,UPnPRouter* router)
+ {
+ bool ret = true;
+ {
+ QFile fptr(file);
+ if (!fptr.open(IO_ReadOnly))
+ return false;
+
+ QXmlInputSource input(&fptr);
+ XMLContentHandler chandler(router);
+ QXmlSimpleReader reader;
+
+ reader.setContentHandler(&chandler);
+ ret = reader.parse(&input,false);
+ }
+
+ if (!ret)
+ {
+ kdDebug() << "Error parsing XML" << endl;
+ return false;
+ }
+ return true;
+ }
+
+ /////////////////////////////////////////////////////////////////////////////////
+
+
+ XMLContentHandler::XMLContentHandler(UPnPRouter* router) : router(router)
+ {}
+
+ XMLContentHandler::~XMLContentHandler()
+ {}
+
+
+ bool XMLContentHandler::startDocument()
+ {
+ status_stack.push(TOPLEVEL);
+ return true;
+ }
+
+ bool XMLContentHandler::endDocument()
+ {
+ status_stack.pop();
+ return true;
+ }
+
+ bool XMLContentHandler::interestingDeviceField(const QString & name)
+ {
+ return name == "friendlyName" || name == "manufacturer" || name == "modelDescription" ||
+ name == "modelName" || name == "modelNumber";
+ }
+
+
+ bool XMLContentHandler::interestingServiceField(const QString & name)
+ {
+ return name == "serviceType" || name == "serviceId" || name == "SCPDURL" ||
+ name == "controlURL" || name == "eventSubURL";
+ }
+
+ bool XMLContentHandler::startElement(const QString &, const QString & localName, const QString &,
+ const QXmlAttributes & )
+ {
+ tmp = "";
+ switch (status_stack.top())
+ {
+ case TOPLEVEL:
+ // from toplevel we can only go to root
+ if (localName == "root")
+ status_stack.push(ROOT);
+ else
+ return false;
+ break;
+ case ROOT:
+ // from the root we can go to device or specVersion
+ // we are not interested in the specVersion
+ if (localName == "device")
+ status_stack.push(DEVICE);
+ else
+ status_stack.push(OTHER);
+ break;
+ case DEVICE:
+ // see if it is a field we are interested in
+ if (interestingDeviceField(localName))
+ status_stack.push(FIELD);
+ else
+ status_stack.push(OTHER);
+ break;
+ case SERVICE:
+ if (interestingServiceField(localName))
+ status_stack.push(FIELD);
+ else
+ status_stack.push(OTHER);
+ break;
+ case OTHER:
+ if (localName == "service")
+ status_stack.push(SERVICE);
+ else if (localName == "device")
+ status_stack.push(DEVICE);
+ else
+ status_stack.push(OTHER);
+ break;
+ case FIELD:
+ break;
+ }
+ return true;
+ }
+
+ bool XMLContentHandler::endElement(const QString & , const QString & localName, const QString & )
+ {
+ switch (status_stack.top())
+ {
+ case FIELD:
+ // we have a field so set it
+ status_stack.pop();
+ if (status_stack.top() == DEVICE)
+ {
+ // if we are in a device
+ router->getDescription().setProperty(localName,tmp);
+ }
+ else if (status_stack.top() == SERVICE)
+ {
+ // set a property of a service
+ curr_service.setProperty(localName,tmp);
+ }
+ break;
+ case SERVICE:
+ // add the service
+ router->addService(curr_service);
+ curr_service.clear();
+ // pop the stack
+ status_stack.pop();
+ break;
+ default:
+ status_stack.pop();
+ break;
+ }
+
+ // reset tmp
+ tmp = "";
+ return true;
+ }
+
+
+ bool XMLContentHandler::characters(const QString & ch)
+ {
+ if (ch.length() > 0)
+ {
+ tmp += ch;
+ }
+ return true;
+ }
+
+}
diff --git a/src/upnp/upnpdescriptionparser.h b/src/upnp/upnpdescriptionparser.h
new file mode 100644
index 0000000..5d4bf1e
--- /dev/null
+++ b/src/upnp/upnpdescriptionparser.h
@@ -0,0 +1,49 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef KTUPNPDESCRIPTIONPARSER_H
+#define KTUPNPDESCRIPTIONPARSER_H
+
+namespace kt
+{
+ class UPnPRouter;
+
+ /**
+ * @author Joris Guisson
+ *
+ * Parses the xml description of a router.
+ */
+ class UPnPDescriptionParser
+ {
+ public:
+ UPnPDescriptionParser();
+ virtual ~UPnPDescriptionParser();
+
+ /**
+ * Parse the xml description.
+ * @param file File it is located in
+ * @param router The router off the xml description
+ * @return true upon success
+ */
+ bool parse(const QString & file,UPnPRouter* router);
+ };
+
+}
+
+#endif
diff --git a/src/upnp/upnpmcastsocket.cpp b/src/upnp/upnpmcastsocket.cpp
new file mode 100644
index 0000000..48159c2
--- /dev/null
+++ b/src/upnp/upnpmcastsocket.cpp
@@ -0,0 +1,313 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <kurl.h>
+#include <kdebug.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <arpa/inet.h>
+#include <netinet/ip.h>
+#include <qstringlist.h>
+#include <ksocketdevice.h>
+#include <ksocketaddress.h>
+/*#include <util/log.h>
+#include <torrent/globals.h>*/
+#include <qfile.h>
+#include <qtextstream.h>
+#include "upnpmcastsocket.h"
+
+
+
+using namespace KNetwork;
+using namespace bt;
+
+namespace kt
+{
+
+ UPnPMCastSocket::UPnPMCastSocket(bool verbose) : verbose(verbose)
+ {
+ routers.setAutoDelete(true);
+ QObject::connect(this,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
+ QObject::connect(this,SIGNAL(gotError(int)),this,SLOT(onError(int)));
+ setAddressReuseable(true);
+ setFamily(KNetwork::KResolver::IPv4Family);
+ setBlocking(true);
+ for (Uint32 i = 0;i < 10;i++)
+ {
+ if (!bind(QString::null,QString::number(1900 + i)))
+ kdDebug() << "Cannot bind to UDP port 1900" << endl;
+ else
+ break;
+ }
+ setBlocking(false);
+ joinUPnPMCastGroup();
+ }
+
+
+ UPnPMCastSocket::~UPnPMCastSocket()
+ {
+ leaveUPnPMCastGroup();
+ QObject::disconnect(this,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
+ QObject::disconnect(this,SIGNAL(gotError(int)),this,SLOT(onError(int)));
+ }
+
+ void UPnPMCastSocket::discover()
+ {
+ kdDebug() << "Trying to find UPnP devices on the local network" << endl;
+
+ // send a HTTP M-SEARCH message to 239.255.255.250:1900
+ const char* data = "M-SEARCH * HTTP/1.1\r\n"
+ "HOST: 239.255.255.250:1900\r\n"
+ "ST:urn:schemas-upnp-org:device:InternetGatewayDevice:1\r\n"
+ "MAN:\"ssdp:discover\"\r\n"
+ "MX:3\r\n"
+ "\r\n\0";
+
+ if (verbose)
+ {
+ kdDebug() << "Sending : " << endl;
+ kdDebug() << data << endl;
+ }
+
+ KDatagramSocket::send(KNetwork::KDatagramPacket(data,strlen(data),KInetSocketAddress("239.255.255.250",1900)));
+ }
+
+ void UPnPMCastSocket::onXmlFileDownloaded(UPnPRouter* r,bool success)
+ {
+ if (!success)
+ {
+ // we couldn't download and parse the XML file so
+ // get rid of it
+ r->deleteLater();
+ }
+ else
+ {
+ // add it to the list and emit the signal
+ if (!routers.contains(r->getServer()))
+ {
+ routers.insert(r->getServer(),r);
+ discovered(r);
+ }
+ else
+ {
+ r->deleteLater();
+ }
+ }
+ }
+
+ void UPnPMCastSocket::onReadyRead()
+ {
+ if (bytesAvailable() == 0)
+ {
+ kdDebug() << "0 byte UDP packet " << endl;
+ // KDatagramSocket wrongly handles UDP packets with no payload
+ // so we need to deal with it oursleves
+ int fd = socketDevice()->socket();
+ char tmp;
+ read(fd,&tmp,1);
+ return;
+ }
+
+ KNetwork::KDatagramPacket p = KDatagramSocket::receive();
+ if (p.isNull())
+ return;
+
+ if (verbose)
+ {
+ kdDebug() << "Received : " << endl;
+ kdDebug() << QString(p.data()) << endl;
+ }
+
+ // try to make a router of it
+ UPnPRouter* r = parseResponse(p.data());
+ if (r)
+ {
+ QObject::connect(r,SIGNAL(xmlFileDownloaded( UPnPRouter*, bool )),
+ this,SLOT(onXmlFileDownloaded( UPnPRouter*, bool )));
+
+ // download it's xml file
+ r->downloadXMLFile();
+ }
+ }
+
+ UPnPRouter* UPnPMCastSocket::parseResponse(const QByteArray & arr)
+ {
+ QStringList lines = QStringList::split("\r\n",QString(arr),false);
+ QString server;
+ KURL location;
+
+
+ kdDebug() << "Received : " << endl;
+ for (Uint32 idx = 0;idx < lines.count(); idx++)
+ kdDebug() << lines[idx] << endl;
+
+
+ // first read first line and see if contains a HTTP 200 OK message
+ QString line = lines.first();
+ if (!line.contains("HTTP"))
+ {
+ // it is either a 200 OK or a NOTIFY
+ if (!line.contains("NOTIFY") && !line.contains("200"))
+ return 0;
+ }
+ else if (line.contains("M-SEARCH")) // ignore M-SEARCH
+ return 0;
+
+ // quick check that the response being parsed is valid
+ bool validDevice = false;
+ for (Uint32 idx = 0;idx < lines.count() && !validDevice; idx++)
+ {
+ line = lines[idx];
+ if ((line.contains("ST:") || line.contains("NT:")) && line.contains("InternetGatewayDevice"))
+ {
+ validDevice = true;
+ }
+ }
+ if (!validDevice)
+ {
+ kdDebug() << "Not a valid Internet Gateway Device" << endl;
+ return 0;
+ }
+
+ // read all lines and try to find the server and location fields
+ for (Uint32 i = 1;i < lines.count();i++)
+ {
+ line = lines[i];
+ if (line.startsWith("Location") || line.startsWith("LOCATION") || line.startsWith("location"))
+ {
+ location = line.mid(line.find(':') + 1).stripWhiteSpace();
+ if (!location.isValid())
+ return 0;
+ }
+ else if (line.startsWith("Server") || line.startsWith("server") || line.startsWith("SERVER"))
+ {
+ server = line.mid(line.find(':') + 1).stripWhiteSpace();
+ if (server.length() == 0)
+ return 0;
+
+ }
+ }
+
+ if (routers.contains(server))
+ {
+ return 0;
+ }
+ else
+ {
+ kdDebug() << "Detected IGD " << server << endl;
+ // everything OK, make a new UPnPRouter
+ return new UPnPRouter(server,location,verbose);
+ }
+ }
+
+ void UPnPMCastSocket::onError(int)
+ {
+ kdDebug() << "UPnPMCastSocket Error : " << errorString() << endl;
+ }
+
+ void UPnPMCastSocket::saveRouters(const QString & file)
+ {
+ QFile fptr(file);
+ if (!fptr.open(IO_WriteOnly))
+ {
+ kdDebug() << "Cannot open file " << file << " : " << fptr.errorString() << endl;
+ return;
+ }
+
+ // file format is simple : 2 lines per router,
+ // one containing the server, the other the location
+ QTextStream fout(&fptr);
+ bt::PtrMap<QString,UPnPRouter>::iterator i = routers.begin();
+ while (i != routers.end())
+ {
+ UPnPRouter* r = i->second;
+ fout << r->getServer() << endl;
+ fout << r->getLocation().prettyURL() << endl;
+ i++;
+ }
+ }
+
+ void UPnPMCastSocket::loadRouters(const QString & file)
+ {
+ QFile fptr(file);
+ if (!fptr.open(IO_ReadOnly))
+ {
+ kdDebug() << "Cannot open file " << file << " : " << fptr.errorString() << endl;
+ return;
+ }
+
+ // file format is simple : 2 lines per router,
+ // one containing the server, the other the location
+ QTextStream fin(&fptr);
+
+ while (!fin.atEnd())
+ {
+ QString server, location;
+ server = fin.readLine();
+ location = fin.readLine();
+ if (!routers.contains(server))
+ {
+ UPnPRouter* r = new UPnPRouter(server,location);
+ // download it's xml file
+ QObject::connect(r,SIGNAL(xmlFileDownloaded( UPnPRouter*, bool )),this,SLOT(onXmlFileDownloaded( UPnPRouter*, bool )));
+ r->downloadXMLFile();
+ }
+ }
+ }
+
+ void UPnPMCastSocket::joinUPnPMCastGroup()
+ {
+ int fd = socketDevice()->socket();
+ struct ip_mreq mreq;
+
+ memset(&mreq,0,sizeof(struct ip_mreq));
+
+ inet_aton("239.255.255.250",&mreq.imr_multiaddr);
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ if (setsockopt(fd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&mreq,sizeof(struct ip_mreq)) < 0)
+ {
+ kdDebug() << "Failed to join multicast group 239.255.255.250" << endl;
+ }
+ }
+
+ void UPnPMCastSocket::leaveUPnPMCastGroup()
+ {
+ int fd = socketDevice()->socket();
+ struct ip_mreq mreq;
+
+ memset(&mreq,0,sizeof(struct ip_mreq));
+
+ inet_aton("239.255.255.250",&mreq.imr_multiaddr);
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+
+ if (setsockopt(fd,IPPROTO_IP,IP_DROP_MEMBERSHIP,&mreq,sizeof(struct ip_mreq)) < 0)
+ {
+ kdDebug() << "Failed to leave multicast group 239.255.255.250" << endl;
+ }
+ }
+}
+
+
+
+#include "upnpmcastsocket.moc"
diff --git a/src/upnp/upnpmcastsocket.h b/src/upnp/upnpmcastsocket.h
new file mode 100644
index 0000000..be75f4b
--- /dev/null
+++ b/src/upnp/upnpmcastsocket.h
@@ -0,0 +1,91 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef KTUPNPMCASTSOCKET_H
+#define KTUPNPMCASTSOCKET_H
+
+#include <kdatagramsocket.h>
+#include "../constants.h"
+#include "../functions.h"
+#include "upnprouter.h"
+
+using bt::Uint32;
+
+namespace kt
+{
+ class UPnPRouter;
+
+ /**
+ * @author Joris Guisson
+ *
+ * Socket used to discover UPnP devices. This class will keep track
+ * of all discovered devices.
+ */
+ class UPnPMCastSocket : public KNetwork::KDatagramSocket
+ {
+ Q_OBJECT
+ public:
+ UPnPMCastSocket(bool verbose = false);
+ virtual ~UPnPMCastSocket();
+
+ /// Get the number of routers discovered
+ Uint32 getNumDevicesDiscovered() const {return routers.count();}
+
+ /// Find a router using it's server name
+ UPnPRouter* findDevice(const QString & name) {return routers.find(name);}
+
+ /// Save all routers to a file (for convenience at startup)
+ void saveRouters(const QString & file);
+
+ /// Load all routers from a file
+ void loadRouters(const QString & file);
+
+ public slots:
+ /**
+ * Try to discover a UPnP device on the network.
+ * A signal will be emitted when a device is found.
+ */
+ void discover();
+
+ private slots:
+ void onReadyRead();
+ void onError(int);
+ void onXmlFileDownloaded(UPnPRouter* r,bool success);
+
+ signals:
+ /**
+ * Emitted when a router or internet gateway device is detected.
+ * @param router The router
+ */
+ void discovered(kt::UPnPRouter* router);
+
+ public:
+ UPnPRouter* parseResponse(const QByteArray & arr);
+
+ private:
+ void joinUPnPMCastGroup();
+ void leaveUPnPMCastGroup();
+
+ private:
+ bt::PtrMap<QString,UPnPRouter> routers;
+ bool verbose;
+ };
+}
+
+#endif
diff --git a/src/upnp/upnprouter.cpp b/src/upnp/upnprouter.cpp
new file mode 100644
index 0000000..4d8f5ad
--- /dev/null
+++ b/src/upnp/upnprouter.cpp
@@ -0,0 +1,531 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#include <stdlib.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
+#include <qstringlist.h>
+#include <kio/netaccess.h>
+#include <kio/job.h>
+#include "httprequest.h"
+#include "upnprouter.h"
+#include "upnpdescriptionparser.h"
+#include "soap.h"
+#include "../functions.h"
+#include <fcntl.h>
+#include <qdir.h>
+#include <qfile.h>
+
+using namespace bt;
+using namespace net;
+
+namespace kt
+{
+ UPnPService::UPnPService()
+ {
+ }
+
+ UPnPService::UPnPService(const UPnPService & s)
+ {
+ this->servicetype = s.servicetype;
+ this->controlurl = s.controlurl;
+ this->eventsuburl = s.eventsuburl;
+ this->serviceid = s.serviceid;
+ this->scpdurl = s.scpdurl;
+ }
+
+ void UPnPService::setProperty(const QString & name,const QString & value)
+ {
+ if (name == "serviceType")
+ servicetype = value;
+ else if (name == "controlURL")
+ controlurl = value;
+ else if (name == "eventSubURL")
+ eventsuburl = value;
+ else if (name == "SCPDURL")
+ scpdurl = value;
+ else if (name == "serviceId")
+ serviceid = value;
+ }
+
+ void UPnPService::clear()
+ {
+ servicetype = controlurl = eventsuburl = scpdurl = serviceid = "";
+ }
+
+ void UPnPService::debugPrintData()
+ {
+ kdDebug() << " servicetype = " << servicetype << endl;
+ kdDebug() << " controlurl = " << controlurl << endl;
+ kdDebug() << " eventsuburl = " << eventsuburl << endl;
+ kdDebug() << " scpdurl = " << scpdurl << endl;
+ kdDebug() << " serviceid = " << serviceid << endl;
+ }
+
+ UPnPService & UPnPService::operator = (const UPnPService & s)
+ {
+ this->servicetype = s.servicetype;
+ this->controlurl = s.controlurl;
+ this->eventsuburl = s.eventsuburl;
+ this->serviceid = s.serviceid;
+ this->scpdurl = s.scpdurl;
+ return *this;
+ }
+
+ ///////////////////////////////////////
+
+ void UPnPDeviceDescription::setProperty(const QString & name,const QString & value)
+ {
+ if (name == "friendlyName")
+ friendlyName = value;
+ else if (name == "manufacturer")
+ manufacturer = value;
+ else if (name == "modelDescription")
+ modelDescription = value;
+ else if (name == "modelName")
+ modelName = value;
+ else if (name == "modelNumber")
+ modelNumber == value;
+ }
+
+ ///////////////////////////////////////
+
+ UPnPRouter::UPnPRouter(const QString & server,const KURL & location,bool verbose) : server(server),location(location),verbose(verbose)
+ {
+ forwardedPortList = new ForwardPortList();
+ // make the tmp_file unique, current time * a random number should be enough
+ tmp_file = QString("/tmp/tork_upnp_description-%1.xml").arg(bt::GetCurrentTime() * rand());
+ }
+
+
+ UPnPRouter::~UPnPRouter()
+ {
+ QValueList<HTTPRequest*>::iterator i = active_reqs.begin();
+ while (i != active_reqs.end())
+ {
+ (*i)->deleteLater();
+ i++;
+ }
+ }
+
+ void UPnPRouter::addService(const UPnPService & s)
+ {
+ QValueList<UPnPService>::iterator i = services.begin();
+ while (i != services.end())
+ {
+ UPnPService & os = *i;
+ if (s.servicetype == os.servicetype)
+ return;
+ i++;
+ }
+ services.append(s);
+ }
+
+ void UPnPRouter::downloadFinished(KIO::Job* j)
+ {
+ if (j->error())
+ {
+ kdDebug() << "Failed to download " << location << " : " << j->errorString() << endl;
+ return;
+ }
+
+ QString target = tmp_file;
+ // load in the file (target is always local)
+ UPnPDescriptionParser desc_parse;
+ bool ret = desc_parse.parse(target,this);
+ if (!ret)
+ {
+ kdDebug() << "Error parsing router description !" << endl;
+ QString dest = KGlobal::dirs()->saveLocation("data","tork") + "upnp_failure";
+ KIO::file_copy(target,dest,-1,true,false,false);
+ }
+ else
+ {
+ if (verbose)
+ debugPrintData();
+ }
+ xmlFileDownloaded(this,ret);
+ remove(QFile::encodeName(target));
+ }
+
+ void UPnPRouter::downloadXMLFile()
+ {
+ // downlaod XML description into a temporary file in /tmp
+ KIO::Job* job = KIO::file_copy(location,tmp_file,-1,true,false,false);
+ connect(job,SIGNAL(result(KIO::Job *)),this,SLOT(downloadFinished( KIO::Job* )));
+ }
+
+ void UPnPRouter::debugPrintData()
+ {
+ kdDebug() << "UPnPRouter : " << endl;
+ kdDebug() << "Friendly name = " << desc.friendlyName << endl;
+ kdDebug() << "Manufacterer = " << desc.manufacturer << endl;
+ kdDebug() << "Model description = " << desc.modelDescription << endl;
+ kdDebug() << "Model name = " << desc.modelName << endl;
+ kdDebug() << "Model number = " << desc.modelNumber << endl;
+ for (QValueList<UPnPService>::iterator i = services.begin();i != services.end();i++)
+ {
+ UPnPService & s = *i;
+ kdDebug() << "Service : " << endl;
+ s.debugPrintData();
+ kdDebug() << "Done" << endl;
+ }
+ kdDebug() << "Done" << endl;
+ }
+
+
+ void UPnPRouter::forward(UPnPService* srv,const net::Port & externalport,
+ const net::Port & internalport)
+ {
+
+
+ // add all the arguments for the command
+ QValueList<SOAP::Arg> args;
+ SOAP::Arg a;
+ a.element = "NewRemoteHost";
+ args.append(a);
+
+ // the external port
+ a.element = "NewExternalPort";
+ a.value = QString::number(externalport.number);
+ args.append(a);
+
+ // the protocol
+ a.element = "NewProtocol";
+ a.value = externalport.proto == TCP ? "TCP" : "UDP";
+ args.append(a);
+
+ // the local port
+ a.element = "NewInternalPort";
+ if (internalport.number)
+ a.value = QString::number(internalport.number);
+ else
+ a.value = QString::number(externalport.number);
+ args.append(a);
+
+ // the local IP address
+ a.element = "NewInternalClient";
+ a.value = "$LOCAL_IP";// will be replaced by our local ip in bt::HTTPRequest
+ args.append(a);
+
+ a.element = "NewEnabled";
+ a.value = "1";
+ args.append(a);
+
+ a.element = "NewPortMappingDescription";
+ static Uint32 cnt = 0;
+ a.value = QString("TorK UPNP %1").arg(cnt++); // TODO: change this
+ args.append(a);
+
+ a.element = "NewLeaseDuration";
+ a.value = "0";
+ args.append(a);
+
+ QString action = "AddPortMapping";
+ QString comm = SOAP::createCommand(action,srv->servicetype,args);
+
+ Forwarding fw = {externalport,internalport,0,srv};
+ // erase old forwarding if one exists
+ QValueList<Forwarding>::iterator itr = fwds.begin();
+ while (itr != fwds.end())
+ {
+ Forwarding & fwo = *itr;
+ if (fwo.extport == externalport && fwo.intport == internalport && fwo.service == srv)
+ itr = fwds.erase(itr);
+ else
+ itr++;
+ }
+
+ fw.pending_req = sendSoapQuery(comm,srv->servicetype + "#" + action,srv->controlurl, true);
+ fwds.append(fw);
+
+ //Track the forwarding request so we can know whether it was successful or not
+ //and keep a map of successfully forwarded ports in forwardedPorts
+ ForwardingRequest fwreq = {externalport,internalport,fw.pending_req};
+ QValueList<ForwardingRequest>::iterator itrq = fwdreqs.begin();
+ while (itrq != fwdreqs.end())
+ {
+ ForwardingRequest & fwo = *itrq;
+ if (fwo.extport == externalport && fwo.intport == internalport)
+ itrq = fwdreqs.erase(itrq);
+ else
+ itrq++;
+ }
+ fwdreqs.append(fwreq);
+
+ }
+
+ void UPnPRouter::forward(const net::Port & externalport,
+ const net::Port & internalport,
+ bool force)
+ {
+
+ if ((forwardedPortList->contains(net::ForwardPort(externalport.number,
+ internalport.number,
+ net::TCP,false)))
+ && (!force))
+ return;
+
+ kdDebug() << "Forwarding port " << externalport.number << " (" << (externalport.proto == UDP ? "UDP" : "TCP") << ")" << endl;
+ // first find the right service
+ QValueList<UPnPService>::iterator i = services.begin();
+ while (i != services.end())
+ {
+ UPnPService & s = *i;
+ if (s.servicetype == "urn:schemas-upnp-org:service:WANIPConnection:1" ||
+ s.servicetype == "urn:schemas-upnp-org:service:WANPPPConnection:1")
+ {
+ if (internalport.number)
+ forward(&s,externalport,internalport);
+ else
+ forward(&s,externalport);
+ }
+ i++;
+ }
+
+ }
+
+ void UPnPRouter::undoForward(UPnPService* srv,const net::Port & extport,
+ const net::Port & intport,bt::WaitJob* waitjob)
+ {
+ // add all the arguments for the command
+ QValueList<SOAP::Arg> args;
+ SOAP::Arg a;
+ a.element = "NewRemoteHost";
+ args.append(a);
+
+ // the external port
+ a.element = "NewExternalPort";
+ a.value = QString::number(extport.number);
+ args.append(a);
+
+ // the protocol
+ a.element = "NewProtocol";
+ a.value = extport.proto == TCP ? "TCP" : "UDP";
+ args.append(a);
+
+
+ QString action = "DeletePortMapping";
+ QString comm = SOAP::createCommand(action,srv->servicetype,args);
+ bt::HTTPRequest* r = sendSoapQuery(comm,srv->servicetype + "#" + action,srv->controlurl,waitjob != 0,false);
+
+ ForwardingRequest fwreq = {extport,intport,r};
+ QValueList<ForwardingRequest>::iterator itrq = fwdreqs.begin();
+ while (itrq != fwdreqs.end())
+ {
+ ForwardingRequest & fwo = *itrq;
+ if (fwo.extport == extport && fwo.intport == intport)
+ itrq = fwdreqs.erase(itrq);
+ else
+ itrq++;
+ }
+ fwdreqs.append(fwreq);
+
+
+ if (waitjob)
+ waitjob->addExitOperation(r);
+
+ updateGUI();
+ }
+
+
+ void UPnPRouter::undoForward(const net::Port & externalport,
+ const net::Port & ,bt::WaitJob* waitjob)
+ {
+ kdDebug() << "Undoing forward of port " << externalport.number
+ << " (" << (externalport.proto == UDP ? "UDP" : "TCP") << ")" << endl;
+
+ QValueList<Forwarding>::iterator itr = fwds.begin();
+ while (itr != fwds.end())
+ {
+ Forwarding & wd = *itr;
+ if (wd.extport == externalport)
+ {
+ undoForward(wd.service,wd.extport,wd.intport,waitjob);
+ itr = fwds.erase(itr);
+ }
+ else
+ {
+ itr++;
+ }
+ }
+ }
+
+ bt::HTTPRequest* UPnPRouter::sendSoapQuery(const QString & query,const QString & soapact,const QString & controlurl, bool fwd,bool at_exit)
+ {
+ // if port is not set, 0 will be returned
+ // thanks to Diego R. Brogna for spotting this bug
+ if (location.port()==0)
+ location.setPort(80);
+
+ QString http_hdr = QString(
+ "POST %1 HTTP/1.1\r\n"
+ "HOST: %2:%3\r\n"
+ "Content-length: $CONTENT_LENGTH\r\n"
+ "Content-Type: text/xml\r\n"
+ "SOAPAction: \"%4\"\r\n"
+ "\r\n").arg(controlurl).arg(location.host()).arg(location.port()).arg(soapact);
+
+
+ HTTPRequest* r = new HTTPRequest(http_hdr,query,location.host(),location.port(),verbose, fwd);
+ connect(r,SIGNAL(replyError(bt::HTTPRequest* ,const QString& ,bool)),
+ this,SLOT(onReplyError(bt::HTTPRequest* ,const QString& ,bool)));
+ connect(r,SIGNAL(replyOK(bt::HTTPRequest* ,const QString& ,bool)),
+ this,SLOT(onReplyOK(bt::HTTPRequest* ,const QString& ,bool)));
+ connect(r,SIGNAL(error(bt::HTTPRequest*, bool )),
+ this,SLOT(onError(bt::HTTPRequest*, bool )));
+ r->start();
+ if (!at_exit)
+ active_reqs.append(r);
+ return r;
+ }
+
+ void UPnPRouter::httpRequestDone(bt::HTTPRequest* r,bool erase_fwd)
+ {
+ QValueList<Forwarding>::iterator i = fwds.begin();
+ while (i != fwds.end())
+ {
+ Forwarding & fw = *i;
+ if (fw.pending_req == r)
+ {
+ fw.pending_req = 0;
+ if (erase_fwd)
+ fwds.erase(i);
+ break;
+ }
+ i++;
+ }
+
+ updateGUI();
+ active_reqs.remove(r);
+ r->deleteLater();
+ }
+
+ void UPnPRouter::onReplyOK(bt::HTTPRequest* r,const QString & s,bool fwd)
+ {
+ kdDebug() << "UPnPRouter : OK" << endl;
+ kdDebug() << "FWD : " << fwd << endl;
+ QValueList<ForwardingRequest>::iterator i = fwdreqs.begin();
+ while (i != fwdreqs.end())
+ {
+ ForwardingRequest & fw = *i;
+ if (fw.pending_req == r)
+ {
+ if (fwd)
+ forwardedPortList->addNewForwardPort(fw.extport.number,
+ fw.intport.number,net::TCP,false);
+ else
+ forwardedPortList->removeForwardPort(fw.extport.number,
+ fw.intport.number,net::TCP);
+ break;
+ }
+ i++;
+ }
+
+ emit replyOK(this,r,s,fwd);
+ httpRequestDone(r,false);
+ }
+
+ void UPnPRouter::onReplyError(bt::HTTPRequest* r,const QString & s,bool fwd)
+ {
+ if (verbose)
+ kdDebug() << "UPnPRouter : Error" << endl;
+ kdDebug() << r->showPayload() << endl;
+ httpRequestDone(r,true);
+ emit replyError(this,r,s,fwd);
+ }
+
+ void UPnPRouter::onError(bt::HTTPRequest* r,bool)
+ {
+ httpRequestDone(r,true);
+ }
+
+
+}
+
+
+namespace bt
+{
+
+ WaitJob::WaitJob(Uint32 millis) : KIO::Job(false)
+ {
+ connect(&timer,SIGNAL(timeout()),this,SLOT(timerDone()));
+ timer.start(millis,true);
+ }
+
+
+ WaitJob::~WaitJob()
+ {}
+
+ void WaitJob::kill(bool)
+ {
+ m_error = 0;
+ emitResult();
+ }
+
+ void WaitJob::timerDone()
+ {
+ // set the error to null and emit the result
+ m_error = 0;
+ emitResult();
+ }
+
+ void WaitJob::addExitOperation(kt::ExitOperation* op)
+ {
+ exit_ops.append(op);
+ connect(op,SIGNAL(operationFinished( kt::ExitOperation* )),
+ this,SLOT(operationFinished( kt::ExitOperation* )));
+ }
+
+ void WaitJob::operationFinished(kt::ExitOperation* op)
+ {
+ if (exit_ops.count() > 0)
+ {
+ exit_ops.remove(op);
+ if (op->deleteAllowed())
+ op->deleteLater();
+
+ if (exit_ops.count() == 0)
+ timerDone();
+ }
+ }
+
+ void WaitJob::execute(WaitJob* job)
+ {
+ KIO::NetAccess::synchronousRun(job,0);
+ }
+
+ void SynchronousWait(Uint32 millis)
+ {
+ kdDebug() << "SynchronousWait" << endl;
+ WaitJob* j = new WaitJob(millis);
+ KIO::NetAccess::synchronousRun(j,0);
+ }
+
+
+// void UpdateCurrentTime()
+// {
+// global_time_stamp = Now();
+// }
+
+}
+
+#include "upnprouter.moc"
diff --git a/src/upnp/upnprouter.h b/src/upnp/upnprouter.h
new file mode 100644
index 0000000..d717a49
--- /dev/null
+++ b/src/upnp/upnprouter.h
@@ -0,0 +1,303 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+#ifndef KTUPNPROUTER_H
+#define KTUPNPROUTER_H
+
+#include <qtimer.h>
+#include <kio/job.h>
+#include <qvaluelist.h>
+#include "exitoperation.h"
+#include <kurl.h>
+#include <qstringlist.h>
+#include <kstreamsocket.h>
+#include "portlist.h"
+#include "forwardportlist.h"
+
+using bt::Uint16;
+
+namespace bt
+{
+
+ /**
+ * @author Joris Guisson <joris.guisson@gmail.com>
+ *
+ * Job to wait for a certain amount of time or until one or more ExitOperation's have
+ * finished.
+ */
+ class WaitJob : public KIO::Job
+ {
+ Q_OBJECT
+ public:
+ WaitJob(Uint32 millis);
+ virtual ~WaitJob();
+
+ virtual void kill(bool quietly=true);
+
+ /**
+ * Add an ExitOperation;
+ * @param op The operation
+ */
+ void addExitOperation(kt::ExitOperation* op);
+
+
+ /**
+ * Execute a WaitJob
+ * @param job The Job
+ */
+ static void execute(WaitJob* job);
+
+ /// Are there any ExitOperation's we need to wait for
+ bool needToWait() const {return exit_ops.count() > 0;}
+
+ private slots:
+ void timerDone();
+ void operationFinished(kt::ExitOperation* op);
+
+ private:
+ QTimer timer;
+ QValueList<kt::ExitOperation*> exit_ops;
+ };
+
+ void SynchronousWait(Uint32 millis);
+
+
+}
+
+namespace bt
+{
+ class HTTPRequest;
+ class WaitJob;
+}
+
+namespace net
+{
+ class ForwardPortList;
+}
+namespace KIO
+{
+ class Job;
+}
+
+namespace kt
+{
+
+ /**
+ * Structure describing a UPnP service found in an xml file.
+ */
+ struct UPnPService
+ {
+ QString serviceid;
+ QString servicetype;
+ QString controlurl;
+ QString eventsuburl;
+ QString scpdurl;
+
+ UPnPService();
+ UPnPService(const UPnPService & s);
+
+ /**
+ * Set a property of the service.
+ * @param name Name of the property (matches to variable names)
+ * @param value Value of the property
+ */
+ void setProperty(const QString & name,const QString & value);
+
+ /**
+ * Set all strings to empty.
+ */
+ void clear();
+
+ /// Print the data of this service
+ void debugPrintData();
+
+ /**
+ * Assignment operator
+ * @param s The service to copy
+ * @return *this
+ */
+ UPnPService & operator = (const UPnPService & s);
+ };
+
+ /**
+ * Struct to hold the description of a device
+ */
+ struct UPnPDeviceDescription
+ {
+ QString friendlyName;
+ QString manufacturer;
+ QString modelDescription;
+ QString modelName;
+ QString modelNumber;
+
+ /**
+ * Set a property of the description
+ * @param name Name of the property (matches to variable names)
+ * @param value Value of the property
+ */
+ void setProperty(const QString & name,const QString & value);
+ };
+
+ /**
+ * @author Joris Guisson
+ *
+ * Class representing a UPnP enabled router. This class is also used to communicate
+ * with the router.
+ */
+ class UPnPRouter : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ struct Forwarding
+ {
+ net::Port extport;
+ net::Port intport;
+ bt::HTTPRequest* pending_req;
+ UPnPService* service;
+ };
+
+ struct ForwardingRequest
+ {
+ net::Port extport;
+ net::Port intport;
+ bt::HTTPRequest* pending_req;
+ };
+
+ private:
+ QString server;
+ QString tmp_file;
+ KURL location;
+ UPnPDeviceDescription desc;
+ QValueList<UPnPService> services;
+ QValueList<Forwarding> fwds;
+ QValueList<ForwardingRequest> fwdreqs;
+ QValueList<bt::HTTPRequest*> active_reqs;
+ net::ForwardPortList* forwardedPortList;
+
+ public:
+ /**
+ * Construct a router.
+ * @param server The name of the router
+ * @param location The location of it's xml description file
+ * @param verbose Print lots of debug info
+ */
+ UPnPRouter(const QString & server,const KURL & location,bool verbose = false);
+ virtual ~UPnPRouter();
+
+ /// Get the name of the server
+ QString getServer() const {return server;}
+
+ /// Get the location of it's xml description
+ KURL getLocation() const {return location;}
+
+ /// Get the device description
+ UPnPDeviceDescription & getDescription() {return desc;}
+
+ /// Get the device description (const version)
+ const UPnPDeviceDescription & getDescription() const {return desc;}
+
+ /**
+ * Download the XML File of the router.
+ */
+ void downloadXMLFile();
+
+ /**
+ * Add a service to the router.
+ * @param s The service
+ */
+ void addService(const UPnPService & s);
+
+#if 0
+ /**
+ * See if a port is forwarded
+ * @param port The Port
+ */
+ void isPortForwarded(const net::Port & port);
+
+ /**
+ * Get the external IP address.
+ */
+ void getExternalIP();
+#endif
+
+ /**
+ * Forward a local port
+ * @param port The local port to forward
+ */
+ void forward(const net::Port & externalport,
+ const net::Port & internalport = net::Port::Port(),
+ bool force = false);
+
+ /**
+ * Undo forwarding
+ * @param port The port
+ * @param waitjob When this is set the jobs needs to be added to the waitjob,
+ * so we can wait for their completeion at exit
+ */
+ void undoForward(const net::Port & externalport,const net::Port & internalport,
+ bt::WaitJob* waitjob = 0);
+
+ void debugPrintData();
+
+ QValueList<ForwardingRequest>::iterator beginReqMappings() {return fwdreqs.begin();}
+ QValueList<ForwardingRequest>::iterator endReqMappings() {return fwdreqs.end();}
+ QValueList<Forwarding>::iterator beginPortMappings() {return fwds.begin();}
+ QValueList<Forwarding>::iterator endPortMappings() {return fwds.end();}
+ net::ForwardPortList* forwardedPorts() {return forwardedPortList;}
+ private slots:
+ void onReplyOK(bt::HTTPRequest* r,const QString &,bool);
+ void onReplyError(bt::HTTPRequest* r,const QString &,bool);
+ void onError(bt::HTTPRequest* r,bool);
+ void downloadFinished(KIO::Job* j);
+
+
+
+ signals:
+ /**
+ * Tell the GUI that it needs to be updated.
+ */
+ void updateGUI();
+
+ /**
+ * Signal which indicates that the XML was downloaded successfully or not.
+ * @param r The router which emitted the signal
+ * @param success Wether or not it succeeded
+ */
+ void xmlFileDownloaded(UPnPRouter* r,bool success);
+
+ void replyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const QString &,bool);
+ void replyError(kt::UPnPRouter*,bt::HTTPRequest* ,const QString &,bool);
+
+ private:
+ QValueList<UPnPService>::iterator findPortForwardingService();
+
+ bt::HTTPRequest* sendSoapQuery(const QString & query,const QString & soapact,const QString & controlurl,bool fwd, bool at_exit = false );
+ bool verbose;
+
+ void forward(UPnPService* srv,const net::Port & externalport,const net::Port & internalport = net::Port::Port());
+ void undoForward(UPnPService* srv,const net::Port & externalport,const net::Port &
+ internalport,bt::WaitJob* waitjob);
+ void httpRequestDone(bt::HTTPRequest* r,bool erase_fwd);
+ };
+
+}
+
+
+#endif
diff --git a/src/upnpmanager.cpp b/src/upnpmanager.cpp
new file mode 100644
index 0000000..573fa16
--- /dev/null
+++ b/src/upnpmanager.cpp
@@ -0,0 +1,173 @@
+/***************************************************************************
+ * $Id: upnpmanager.cpp,v 1.5 2008/04/14 11:15:53 hoganrobert Exp $
+ * Copyright (C) 2008 by Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <kmessagebox.h>
+#include "upnpmanager.h"
+#include "kdebug.h"
+
+using namespace bt;
+
+UPnPManager* UPnPManager::manager = 0;
+
+ UPnPManager* UPnPManager::Manager ()
+ {
+ if (manager == 0)
+ {
+ manager = new UPnPManager;
+ }
+ return manager;
+ }
+
+ UPnPManager::UPnPManager(QWidget* parent, const char* name)
+ : QWidget(parent, name)
+ {
+ sock = new UPnPMCastSocket();
+ connect(sock,SIGNAL(discovered( kt::UPnPRouter* )),
+ this,SLOT(discovered( kt::UPnPRouter* )));
+ discover();
+ }
+
+ UPnPManager::~UPnPManager()
+ {
+ delete sock;
+
+ }
+
+// void UPnPManager::shutdown(bt::WaitJob* job)
+// {
+// if (!def_router)
+// return;
+//
+// net::PortList & pl = bt::Globals::instance().getPortList();
+// if (pl.count() == 0)
+// return;
+//
+// for (net::PortList::iterator i = pl.begin(); i != pl.end();i++)
+// {
+// net::Port & p = *i;
+// if (p.forward)
+// def_router->undoForward(p,job);
+// }
+// }
+
+ void UPnPManager::discover()
+ {
+ sock->discover();
+ }
+
+ void UPnPManager::forward(const net::ForwardPortList &forwardPorts,
+ bool force, bool silent)
+ {
+ m_silent = silent;
+ QValueList<kt::UPnPRouter*>::iterator r = discoveredRouters.begin();
+ while (r != discoveredRouters.end())
+ {
+ disconnect((*r),SIGNAL(replyError(kt::UPnPRouter*,bt::HTTPRequest* ,const QString&, bool )),
+ this,SLOT(onReplyError(kt::UPnPRouter*,bt::HTTPRequest* ,const QString&, bool )));
+ disconnect((*r),SIGNAL(replyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const QString&, bool )),
+ this,SLOT(onReplyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const QString&, bool )));
+
+ connect((*r),SIGNAL(replyError(kt::UPnPRouter*,bt::HTTPRequest* ,const QString&, bool )),
+ this,SLOT(onReplyError(kt::UPnPRouter*,bt::HTTPRequest* ,const QString&, bool )));
+ connect((*r),SIGNAL(replyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const QString&, bool )),
+ this,SLOT(onReplyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const QString&, bool )));
+
+ for (net::ForwardPortList::ConstIterator i = forwardPorts.begin();
+ i != forwardPorts.end();i++)
+ {
+ const net::ForwardPort & s = *i;
+
+/* (*r)->undoForward(net::Port(s.extnumber,s.proto,s.forward),false);*/
+ (*r)->forward(net::Port(s.extnumber,s.proto,s.forward),
+ net::Port(s.intnumber,s.proto,s.forward),
+ force);
+ }
+ r++;
+ }
+
+ kdDebug() << "Done" << endl;
+ }
+
+ void UPnPManager::onReplyError(kt::UPnPRouter* router,bt::HTTPRequest* req,const QString&, bool fwd )
+ {
+
+ emit forwardingError(router,req->showPayload(),fwd);
+ }
+
+ void UPnPManager::onReplyOK(kt::UPnPRouter* router,bt::HTTPRequest* req,const QString&, bool fwd )
+ {
+
+ kdDebug() << "forwarding OK" << endl;
+ emit forwardingOK(router,req->showPayload(),fwd);
+ }
+
+ void UPnPManager::undoForward(const net::ForwardPortList &forwardPorts,
+ bool silent)
+ {
+ m_silent = silent;
+ QValueList<kt::UPnPRouter*>::iterator r = discoveredRouters.begin();
+ while (r != discoveredRouters.end())
+ {
+ for (net::ForwardPortList::ConstIterator i = forwardPorts.begin();i != forwardPorts.end();i++)
+ {
+ const net::ForwardPort & s = *i;
+ (*r)->undoForward(net::Port(s.extnumber,s.proto,s.forward),
+ net::Port(s.intnumber,s.proto,s.forward),false);
+ }
+ r++;
+ }
+
+ kdDebug() << "Done" << endl;
+ }
+
+ QStringList UPnPManager::discoveredRoutersNameList()
+ {
+ QStringList routers;
+ QValueList<kt::UPnPRouter*>::iterator r = discoveredRouters.begin();
+ while (r != discoveredRouters.end())
+ {
+ routers.append((*r)->getDescription().friendlyName);
+ r++;
+ }
+ return routers;
+ }
+
+ void UPnPManager::discovered(UPnPRouter* r)
+ {
+ discoveredRouters.append(r);
+ emit routerDiscovered(r);
+ }
+
+
+ void UPnPManager::unload()
+ {
+/* QString routers_file = KGlobal::dirs()->saveLocation("data","tork") + "routers";
+ sock->saveRouters(routers_file);*/
+ sock->close();
+ delete sock;
+ sock = 0;
+ }
+
+
+#include "upnpmanager.moc"
diff --git a/src/upnpmanager.h b/src/upnpmanager.h
new file mode 100644
index 0000000..44d1e3c
--- /dev/null
+++ b/src/upnpmanager.h
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * $Id: upnpmanager.h,v 1.7 2009/10/20 20:16:00 hoganrobert Exp $
+ * Copyright (C) 2008 by Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * Copyright (C) 2005 by Joris Guisson *
+ * joris.guisson@gmail.com *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef UPNPMANAGER_H
+#define UPNPMANAGER_H
+
+#include <qmap.h>
+#include <qwidget.h>
+#include "upnp/upnprouter.h"
+#include "upnp/upnpdescriptionparser.h"
+#include "upnp/upnpmcastsocket.h"
+#include "upnp/portlist.h"
+#include "upnp/forwardportlist.h"
+#include "upnp/httprequest.h"
+
+using namespace kt;
+using namespace net;
+
+/**
+ * Widget for the UPnP pref dialog page.
+ */
+class UPnPManager : public QWidget
+{
+ Q_OBJECT
+
+public:
+ static UPnPManager* Manager();
+ void discover();
+ void forward(const net::ForwardPortList & forwardPorts,
+ bool force, bool silent=false);
+ void undoForward(const net::ForwardPortList & forwardPorts,
+ bool silent=false);
+ bool routersDiscovered(){ return ((!discoveredRouters.isEmpty()) ? true : false);};
+ bool silentUpdate(){ return m_silent;};
+ QStringList discoveredRoutersNameList();
+protected:
+ UPnPManager(QWidget* parent = 0, const char* name = 0);
+ virtual ~UPnPManager();
+private:
+ static UPnPManager* manager;
+
+public slots:
+ /**
+ * Add a device to the list.
+ * @param r The device
+ */
+ void discovered(kt::UPnPRouter* r);
+ void onReplyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const QString&, bool );
+ void onReplyError(kt::UPnPRouter*,bt::HTTPRequest* ,const QString&, bool );
+signals:
+ void routerDiscovered(kt::UPnPRouter*);
+ void forwardingError(kt::UPnPRouter*,const QString &, bool );
+ void forwardingOK(kt::UPnPRouter*,const QString &, bool );
+
+private:
+ void load();
+ void unload();
+
+private:
+ kt::UPnPRouter* def_router;
+ kt::UPnPMCastSocket* sock;
+ net::ForwardPortList m_forwardPorts;
+ QValueList<kt::UPnPRouter*> discoveredRouters;
+ bool m_silent;
+};
+
+#endif
+
diff --git a/src/usability.ui b/src/usability.ui
new file mode 100644
index 0000000..731c8c2
--- /dev/null
+++ b/src/usability.ui
@@ -0,0 +1,333 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Usability</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Usability</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>540</width>
+ <height>554</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>groupBox12</cstring>
+ </property>
+ <property name="title">
+ <string>Session Continuity</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="1" column="3">
+ <property name="name">
+ <cstring>PushAdd</cstring>
+ </property>
+ <property name="text">
+ <string>O&amp;K</string>
+ </property>
+ <property name="accel">
+ <string>Alt+K</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="2">
+ <property name="name">
+ <cstring>NewHost</cstring>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="2">
+ <property name="name">
+ <cstring>kcfg_TrackHostExitsExpire</cstring>
+ </property>
+ <property name="suffix">
+ <string> minutes</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="0" column="2" rowspan="1" colspan="2">
+ <column>
+ <property name="text">
+ <string>Domains </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>TrackHostExits</cstring>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel10</cstring>
+ </property>
+ <property name="text">
+ <string>Maximum Length of Session Time:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>textLabel9</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; This is a list of domains which might give you trouble if you connect from a range of different IP addresses during a single session. Adding them to this list ensures the same IP address is presented to the domain during the session.</string>
+ </property>
+ </widget>
+ <spacer row="0" column="1">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>70</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="2" column="1">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>65</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <spacer row="2" column="1">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>31</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel4_2_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Don't reuse a connection if it is more than</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="2">
+ <property name="name">
+ <cstring>kcfg_MaxCircuitDirtiness</cstring>
+ </property>
+ <property name="suffix">
+ <string> seconds old</string>
+ </property>
+ <property name="maxValue">
+ <number>9999</number>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>groupBox13</cstring>
+ </property>
+ <property name="title">
+ <string>Networks Services With Long Session Times</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="0" column="1">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>100</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton" row="1" column="2">
+ <property name="name">
+ <cstring>clearSelected</cstring>
+ </property>
+ <property name="text">
+ <string>Clear Selected</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>textLabel11</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt; These services are known to have long session times. Select any of them that you use and this will ensure that their traffic is routed over servers that have a high-availability rating (i.e. are rarely offline).</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="0" column="2">
+ <column>
+ <property name="text">
+ <string>Services </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <item>
+ <property name="text">
+ <string>ftp</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>msn</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>jabber</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>aol</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>telnet</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ssh</string>
+ </property>
+ <property name="pixmap">
+ <pixmap></pixmap>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>LongLivedPorts</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>Extended</enum>
+ </property>
+ <property name="resizeMode">
+ <enum>AllColumns</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>LongLivedPorts</sender>
+ <signal>selectionChanged()</signal>
+ <receiver>Usability</receiver>
+ <slot>LongLivedPorts_selectionChanged()</slot>
+ </connection>
+ <connection>
+ <sender>TrackHostExits</sender>
+ <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+ <receiver>Usability</receiver>
+ <slot>TrackHostExits_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+ </connection>
+ <connection>
+ <sender>PushAdd</sender>
+ <signal>clicked()</signal>
+ <receiver>Usability</receiver>
+ <slot>PushAdd_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>clearSelected</sender>
+ <signal>clicked()</signal>
+ <receiver>Usability</receiver>
+ <slot>clearSelected_clicked()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">usability.ui.h</include>
+</includes>
+<signals>
+ <signal>settingsChanged()</signal>
+</signals>
+<slots>
+ <slot>LongLivedPorts_selectionChanged()</slot>
+ <slot>PushAdd_clicked()</slot>
+ <slot>TrackHostExits_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+ <slot>slotDeleteEntry()</slot>
+ <slot>clearSelected_clicked()</slot>
+</slots>
+<functions>
+ <function access="private" specifier="non virtual">init()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/usability.ui.h b/src/usability.ui.h
new file mode 100644
index 0000000..4d0f677
--- /dev/null
+++ b/src/usability.ui.h
@@ -0,0 +1,151 @@
+/***************************************************************************
+ * $Id: usability.ui.h,v 1.12 2008/07/31 19:56:28 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+
+#include "torkconfig.h"
+#include "portsandnames.h"
+#include <klocale.h>
+#include <qtooltip.h>
+#include <qpopupmenu.h>
+#include <kdebug.h>
+
+
+void Usability::init()
+{
+ QListViewItemIterator it(LongLivedPorts);
+ while ( it.current() ) {
+ int i;
+ QString port;
+ for (i = 0; _port_name[i].port; ++i) {
+ portsandnames_t *pics = &_port_name[i];
+ if (it.current()->text(0) == pics->name){
+ port = pics->port;
+ continue;
+ }
+ }
+
+ if (TorkConfig::longLivedPorts().contains(port))
+ LongLivedPorts->setSelected(*it,true);
+ ++it;
+ }
+
+ QStringList existingTracks = TorkConfig::trackHostExits();
+ QListViewItem *tm;
+ for ( QStringList::Iterator it = existingTracks.begin(); it != existingTracks.end(); ++it )
+ {
+ if ((*it).isEmpty())
+ continue;
+ tm = new QListViewItem(TrackHostExits,(*it));
+ }
+
+}
+void Usability::LongLivedPorts_selectionChanged()
+{
+ emit settingsChanged();
+}
+
+
+
+
+void Usability::PushAdd_clicked()
+{
+
+ new QListViewItem(TrackHostExits,NewHost->text());
+}
+
+
+
+void Usability::TrackHostExits_contextMenuRequested( QListViewItem *, const QPoint &point, int )
+{
+
+ QPopupMenu *menu = new QPopupMenu( TrackHostExits );
+
+ menu->clear();
+ menu->insertItem( "Delete Entry", this,SLOT(slotDeleteEntry()) );
+ menu->popup( point );
+
+}
+
+
+void Usability::slotDeleteEntry( )
+{
+
+ QListViewItemIterator it(TrackHostExits, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ if (TrackHostExits->isSelected( it.current()))
+ delete it.current();
+ ++it;
+ }
+
+
+}
+
+
+// <connections>
+// <connection>
+// <sender>LongLivedPorts</sender>
+// <signal>selectionChanged()</signal>
+// <receiver>Usability</receiver>
+// <slot>LongLivedPorts_selectionChanged()</slot>
+// </connection>
+// <connection>
+// <sender>TrackHostExits</sender>
+// <signal>contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</signal>
+// <receiver>Usability</receiver>
+// <slot>TrackHostExits_contextMenuRequested(QListViewItem*,const QPoint&amp;,int)</slot>
+// </connection>
+// <connection>
+// <sender>PushAdd</sender>
+// <signal>clicked()</signal>
+// <receiver>Usability</receiver>
+// <slot>PushAdd_clicked()</slot>
+// </connection>
+// </connections>
+// <includes>
+// <include location="local" impldecl="in implementation">usability.ui.h</include>
+// </includes>
+// <signals>
+// <signal>settingsChanged()</signal>
+// </signals>
+// <slots>
+// <slot>LongLivedPorts_selectionChanged()</slot>
+// <slot>TrackHostExits_contextMenuRequested( QListViewItem *, const QPoint &amp; point, int )</slot>
+// <slot>slotDeleteEntry()</slot>
+// <slot>PushAdd_clicked()</slot>
+// </slots>
+// <functions>
+// <function access="private" specifier="non virtual">init()</function>
+// </functions>
+// <layoutdefaults spacing="6" margin="11"/>
+// </UI>
+
+
+
+void Usability::clearSelected_clicked()
+{
+
+ QListViewItemIterator it(LongLivedPorts, QListViewItemIterator::Selected);
+ while ( it.current() ) {
+ it.current()->listView()->setSelected(it.current(),false);
+ ++it;
+ }
+
+}
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000..0c14a5d
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,24 @@
+/***************************************************************************
+ * $Id: version.h,v 1.42 2010/07/24 12:21:14 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#define VERSION_TORK 0.33
+#define TORK_VERSION "0.33"
+
diff --git a/src/warnings.h b/src/warnings.h
new file mode 100644
index 0000000..dbd01a4
--- /dev/null
+++ b/src/warnings.h
@@ -0,0 +1,413 @@
+/***************************************************************************
+ * $Id: warnings.h,v 1.34 2009/06/20 09:29:15 hoganrobert Exp $
+ * Copyright (C) 2006 - 2008 Robert Hogan *
+ * robert@roberthogan.net *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "tork.h"
+#include <qstring.h>
+
+typedef struct message_t {
+ const char *logmessage; /**< The full keyword (case insensitive). */
+ const QString headline; /**< String (or null) describing initial value. */
+ char torsaid[250]; /**< String (or null) describing initial value. */
+ const QString body; /**< String (or null) describing initial value. */
+ const QString type; /**< String (or null) describing initial value. */
+ const char *icon; /**< String (or null) describing initial value. */
+ bool (tork::*pt2Member)();
+ display_status_t state; /**< The type of the value. */
+ bool always; /**< The type of the value. */
+ bool showstopper; /**< The type of the value. */
+} message_t;
+
+
+#define MSG(logmessage,headline,torsaid, body, type, icon, show, state, always, showstopper) \
+ { logmessage, headline,torsaid,body, type, icon, show, state, always, showstopper }
+
+static message_t _tork_messages[] = {
+ MSG("ommencing hibernation",
+ i18n("Tor Is No Longer Accepting Traffic!"),
+ "",
+ i18n("Tor has exceeded the bandwidth limits you set in "
+ "'My Server->Performance' and so will no longer accept traffic. To fix this, set a higher threshold in"
+ "'My Server->Performance'."),
+ i18n("Show Usage Warnings"),
+ "tork_info",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("Accounting period ended",
+ i18n("Tor Is No Longer Accepting Traffic!"),
+ "",
+ i18n("Tor has exceeded the bandwidth limits you set in "
+ "'My Server->Performance' and so will no longer accept traffic. To fix this, set a higher threshold in"
+ "'My Server->Performance'."),
+ i18n("Show Usage Warnings"),
+ "tork_info",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("Hibernation period ended",
+ i18n("Tor Is Now Accepting Traffic Again!"),
+ "",
+ i18n("Tor has completed a hibernation period that resulted from the settings you defined in "
+ "'My Server->Performance'. If you do not want to accept traffic, set a lower threshold in"
+ "'My Server->Performance'."),
+ i18n("Show Usage Warnings"),
+ "tork_info",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("Your IP seems to have changed",
+ i18n("You are running a server without any contact information!"),
+ "",
+ i18n("You can set your contact info in the configuration section 'My Server'. Please do so! "),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("notorexecutable",
+ i18n("Can't Find Your Tor Installation!"),
+ "",
+ i18n("You need to tell me where Tor is - it's not in any of your executable paths. Run the 'First Run Wizard' again from the 'Tools' menu."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, true),
+ MSG("noprivoxyexecutable",
+ i18n("Can't Find Your Privoxy Installation!"),
+ "",
+ i18n("You need to tell me where Privoxy is - it's not in any of your executable paths. Run the 'First Run Wizard' again from the 'Tools' menu."),
+ i18n("General Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("dnsrequestsdetected",
+ i18n("You May Be Leaking DNS Requests!"),
+ "",
+ i18n("You should inspect the 'Traffic Log' to establish which application made the DNS request. Look for :domain or :53 in the Host/Port column of the Non-Tor traffic log. It may be that the application submitting the request is not of interest to you."),
+ i18n("DNS Leak Warnings"),
+ "tork_alert",
+ (&tork::showDNSLeaks),
+ DISPLAY_NONE, false, false),
+ MSG("Error writing to",
+ i18n("Problem Accessing Files!"),
+ "",
+ i18n("You should make sure that you have the requisite access to the files required by Tor. Try typing 'tor' at the command line to investigate further."),
+ i18n("General Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, true),
+ MSG("cannot be read",
+ i18n("Problem Accessing Files!"),
+ "",
+ i18n("You should make sure that you have the requesite access to the files required by Tor. Try typing 'tor' at the command line to investigate further."),
+ i18n("General Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, true),
+ MSG("Could not chmod",
+ i18n("Problem Accessing Files!"),
+ "",
+ i18n("You should make sure that you have the requesite access to the files required by Tor. Try typing 'tor' at the command line to investigate further."),
+ i18n("General Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, true),
+ MSG("Couldn't open",
+ i18n("Problem Accessing Files!"),
+ "",
+ i18n("You should make sure that you have the requesite access to the files required by Tor. Try typing 'tor' at the command line to investigate further."),
+ i18n("General Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, true),
+ MSG("Error creating",
+ i18n("Problem Accessing Files!"),
+ "",
+ i18n("You should make sure that you have the requesite access to the files required by Tor. Try typing 'tor' at the command line to investigate further."),
+ i18n("General Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, true),
+ MSG("deprecated",
+ i18n("TorK is using a deprecated config option!"),
+ "",
+ i18n("Please report this using 'Help->Report Bug' in the menu. Try to provide as much detail as possible. Thanks!"),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("Unparseable address in hidden service",
+ i18n("Your Hidden Service Could Not Be Started!"),
+ "",
+ i18n("The address you configured for it may be invalid. See 'Tor Log' pane for details."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("Failed to parse/validate config",
+ i18n("TorK has passed an invalid configuration file to Tor!"),
+ "",
+ i18n("Please report this using 'Help->Report Bug' in the menu. Try to provide as much detail as possible. Thanks!"),
+ i18n("General Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, true),
+ MSG("your clock just jumped",
+ i18n("Tor is having problems with your local clock!"),
+ "",
+ i18n("Please report this using 'Help->Report Bug' in the menu or directly to or-talk@freehaven.net. Try to provide as much detail as possible. Thanks!"),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("your ORPort is reachable from the outside",
+ i18n("Your Tor Server appears to be working!!"),
+ "",
+ i18n("You are now serving the Tor network. Be careful out there!"),
+ i18n("Show Usage Warnings"),
+ "tork_torserver",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+ MSG("your DirPort is reachable from the outside",
+ i18n("Your Tor Server's directory appears to be working!!"),
+ "",
+ i18n("You can now serve directory listings to the Tor network. Be careful out there!"),
+ i18n("Show Usage Warnings"),
+ "tork_torserver",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+ MSG("torclosedconnection",
+ i18n("Tor Stopped Talking To Us!!"),
+ "",
+ i18n("Try starting Tork again!"),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, true),
+ MSG("hidden service is unavailable",
+ i18n("The Hidden Service You Are Trying to Reach is Currently Unavailable!"),
+ "",
+ i18n("It's not just you. The hidden service you're trying to reach is actually down."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("we have none",
+ i18n("Tor can't retrieve a list of all servers on the network yet!"),
+ "",
+ i18n("TorK will try again as soon as Tor says it has enough info, in the meantime you can still use Tor though the servers list in the 'Tor Network' tab will be empty."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("/var/lib/tor",
+ i18n("You are using an old version of Tor that TorK is not compatible with!"),
+ "",
+ i18n("Try upgrading Tor through Tools->Download Tor."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("cantreadprofiles",
+ i18n("The file is not readable by Tork!"),
+ "",
+ i18n("Does it exist?."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("cantcopyprofile",
+ i18n("The file is not readable by Tork!"),
+ "",
+ i18n("Does it exist?"),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("cantwritefirefoxsettings",
+ i18n("The file is not writeable by Tork!"),
+ "",
+ i18n("Try again maybe."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("torrunning",
+ i18n("TorK is connected to Tor. You need to click 'Stop' first!"),
+ "",
+ i18n("To run the setup wizard, click 'Stop' in the Anonymize tab and try again."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+
+ MSG("bwreset",
+ i18n("TorK has reset the bandwidth rates on Tor as per your instructions!"),
+ "",
+ i18n("You instructed TorK to do this in 'My Bandwidth'."),
+ i18n("Show Usage Warnings"),
+ "tork_info",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+
+ MSG("nonanonkonqhidden",
+ i18n("TorK has hidden your non-anonymous Konqueror windows."),
+ "",
+ i18n("Konqueror windows that have been used non-anonymously are not suitable for anonymous work!"),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+
+ MSG("nonanonkonqshown",
+ i18n("TorK has un-hidden your non-anonymous Konqueror windows."),
+ "",
+ i18n("Konqueror windows that were used non-anonymously are safe to use again for non-anonymous work!"),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+
+ MSG("DANGEROUS_VERSION",
+ i18n("Your version of Tor may have problems."),
+ "",
+ i18n("You should think of using the recommended version of Tor!"),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+
+ MSG("CIRCUIT_ESTABLISHED",
+ i18n("Tor is ready for use as a client."),
+ "",
+ i18n("You can now use Tor to anonymize your traffic!"),
+ i18n("Show Usage Warnings"),
+ "tork_info",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+
+ MSG("TOO_MANY_CONNECTIONS",
+ i18n("Your system has too many open connections."),
+ "",
+ i18n("You should try running 'ulimit -n 10000' to improve things."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+
+ MSG("cookienotfound",
+ i18n("Tor's Authentication Cookie Not Available."),
+ "",
+ i18n("If you stored it elsewhere, please copy it to the suggested location above."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, true),
+
+ MSG("authenticationfailed",
+ i18n("You used the wrong password to connect to Tor!"),
+ "",
+ i18n("Check the password entered in 'My Client'."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, true),
+
+ MSG("authenticationrequired",
+ i18n("You need to use a password or cookie to connect to Tor!"),
+ "",
+ i18n("Enter the correct password or select cookie authentication in 'My Client'."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, true),
+
+ MSG("featuresdisabled",
+ i18n("You may notice some of TorK's features have been disabled/hidden!"),
+ "",
+ i18n("This is because they are for use with the 0.2.x alpha series of Tor. If you "
+ "run the alpha series they will be re-enabled."),
+ i18n("Show Usage Warnings"),
+ "tork_info",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+
+ MSG("geoipmissing",
+ i18n("Your GeoIP database is missing!"),
+ "",
+ i18n("TorK needs the file GeoIP.dat to assign country flags to Tor servers. "
+ "It looks like this file has gone missing. Please re-install GeoIP and/or TorK to fix."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, false, false),
+ MSG("fwdok",
+ i18n("Easy Accessiblity Enabled On Your Router!"),
+ "",
+ i18n("TorK has forwarded the common web ports on your router to Tor. "
+ "This will make your Tor server more accessible to users and other servers."
+ ),
+ i18n("Show Usage Warnings"),
+ "tork_info",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+ MSG("unfwok",
+ i18n("Easy Accessibility Disabled On Your Router!"),
+ "",
+ i18n("TorK has removed the forwarding of the common web ports on your router to Tor. "
+ "For your Tor server to be reachable, ensure you manually configure your router."
+ ),
+ i18n("Show Usage Warnings"),
+ "tork_info",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+
+
+ MSG("fwderror",
+ i18n("Error Enabling Easy Accessibility On Your Router!"),
+ "",
+ i18n("It's possible that this is just temporary. TorK will try again later."
+ ),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+
+ MSG("unfwerror",
+ i18n("Error Disabling Easy Accessibility On Your Router!"),
+ "",
+ i18n("It's possible that this is just temporary. TorK will try again later."
+ ),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+
+ MSG("cantfindrouter",
+ i18n("Your Broadband Router May Not Be Plug 'n Playable!"),
+ "",
+ i18n("Check that UPnP is enabled on the router and that your computer firewall "
+ "allows traffic to and from the router. You can still be a server, but the "
+ "ports Tor uses will be the defaults rather than 443 and 80."),
+ i18n("Show Usage Warnings"),
+ "tork_alert",
+ (&tork::showUsage),
+ DISPLAY_NONE, true, false),
+
+ { NULL, NULL, "", NULL, NULL, NULL, NULL, DISPLAY_NONE, false, false }
+};
+#undef MSG